aboutsummaryrefslogtreecommitdiff
path: root/ld/ldlang.c
diff options
context:
space:
mode:
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r--ld/ldlang.c176
1 files changed, 92 insertions, 84 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 1e9b090..262c94b 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -1312,7 +1312,8 @@ lang_output_section_find_by_flags (const asection *sec,
if (look->bfd_section != NULL)
{
flags = look->bfd_section->flags;
- if (match_type && !match_type (output_bfd, look->bfd_section,
+ if (match_type && !match_type (link_info.output_bfd,
+ look->bfd_section,
sec->owner, sec))
continue;
}
@@ -1337,7 +1338,8 @@ lang_output_section_find_by_flags (const asection *sec,
if (look->bfd_section != NULL)
{
flags = look->bfd_section->flags;
- if (match_type && !match_type (output_bfd, look->bfd_section,
+ if (match_type && !match_type (link_info.output_bfd,
+ look->bfd_section,
sec->owner, sec))
continue;
}
@@ -1356,7 +1358,8 @@ lang_output_section_find_by_flags (const asection *sec,
if (look->bfd_section != NULL)
{
flags = look->bfd_section->flags;
- if (match_type && !match_type (output_bfd, look->bfd_section,
+ if (match_type && !match_type (link_info.output_bfd,
+ look->bfd_section,
sec->owner, sec))
continue;
}
@@ -1376,7 +1379,8 @@ lang_output_section_find_by_flags (const asection *sec,
if (look->bfd_section != NULL)
{
flags = look->bfd_section->flags;
- if (match_type && !match_type (output_bfd, look->bfd_section,
+ if (match_type && !match_type (link_info.output_bfd,
+ look->bfd_section,
sec->owner, sec))
continue;
}
@@ -1397,7 +1401,8 @@ lang_output_section_find_by_flags (const asection *sec,
if (look->bfd_section != NULL)
{
flags = look->bfd_section->flags;
- if (match_type && !match_type (output_bfd, look->bfd_section,
+ if (match_type && !match_type (link_info.output_bfd,
+ look->bfd_section,
sec->owner, sec))
continue;
}
@@ -1416,7 +1421,8 @@ lang_output_section_find_by_flags (const asection *sec,
if (look->bfd_section != NULL)
{
flags = look->bfd_section->flags;
- if (match_type && !match_type (output_bfd, look->bfd_section,
+ if (match_type && !match_type (link_info.output_bfd,
+ look->bfd_section,
sec->owner, sec))
continue;
}
@@ -1560,7 +1566,7 @@ lang_insert_orphan (asection *s,
etree_type *e_align;
symname = (char *) xmalloc (ps - secname + sizeof "__start_" + 1);
- symname[0] = bfd_get_symbol_leading_char (output_bfd);
+ symname[0] = bfd_get_symbol_leading_char (link_info.output_bfd);
sprintf (symname + (symname[0] != 0), "__start_%s", secname);
e_align = exp_unop (ALIGN_K,
exp_intop ((bfd_vma) 1 << s->alignment_power));
@@ -1595,7 +1601,7 @@ lang_insert_orphan (asection *s,
stat_ptr = &add;
symname = (char *) xmalloc (ps - secname + sizeof "__stop_" + 1);
- symname[0] = bfd_get_symbol_leading_char (output_bfd);
+ symname[0] = bfd_get_symbol_leading_char (link_info.output_bfd);
sprintf (symname + (symname[0] != 0), "__stop_%s", secname);
lang_add_assignment (exp_provide (symname,
exp_nameop (NAME, "."),
@@ -1632,7 +1638,7 @@ lang_insert_orphan (asection *s,
}
if (place->section == NULL)
- place->section = &output_bfd->sections;
+ place->section = &link_info.output_bfd->sections;
as = *place->section;
@@ -1641,18 +1647,18 @@ lang_insert_orphan (asection *s,
/* Put the section at the end of the list. */
/* Unlink the section. */
- bfd_section_list_remove (output_bfd, snew);
+ bfd_section_list_remove (link_info.output_bfd, snew);
/* Now tack it back on in the right place. */
- bfd_section_list_append (output_bfd, snew);
+ bfd_section_list_append (link_info.output_bfd, snew);
}
else if (as != snew && as->prev != snew)
{
/* Unlink the section. */
- bfd_section_list_remove (output_bfd, snew);
+ bfd_section_list_remove (link_info.output_bfd, snew);
/* Now tack it back on in the right place. */
- bfd_section_list_insert_before (output_bfd, as, snew);
+ bfd_section_list_insert_before (link_info.output_bfd, as, snew);
}
/* Save the end of this list. Further ophans of this type will
@@ -1757,7 +1763,7 @@ lang_map (void)
for (s = file->the_bfd->sections; s != NULL; s = s->next)
if ((s->output_section == NULL
- || s->output_section->owner != output_bfd)
+ || s->output_section->owner != link_info.output_bfd)
&& (s->flags & (SEC_LINKER_CREATED | SEC_KEEP)) == 0)
{
if (! dis_header_printed)
@@ -1882,14 +1888,14 @@ init_os (lang_output_section_statement_type *s, asection *isec,
if (strcmp (s->name, DISCARD_SECTION_NAME) == 0)
einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME);
- s->bfd_section = bfd_get_section_by_name (output_bfd, s->name);
+ s->bfd_section = bfd_get_section_by_name (link_info.output_bfd, s->name);
if (s->bfd_section == NULL)
- s->bfd_section = bfd_make_section_with_flags (output_bfd, s->name,
- flags);
+ s->bfd_section = bfd_make_section_with_flags (link_info.output_bfd,
+ s->name, flags);
if (s->bfd_section == NULL)
{
einfo (_("%P%F: output format %s cannot represent section called %s\n"),
- output_bfd->xvec->name, s->name);
+ link_info.output_bfd->xvec->name, s->name);
}
s->bfd_section->output_section = s->bfd_section;
s->bfd_section->output_offset = 0;
@@ -1916,7 +1922,7 @@ init_os (lang_output_section_statement_type *s, asection *isec,
if (isec)
bfd_init_private_section_data (isec->owner, isec,
- output_bfd, s->bfd_section,
+ link_info.output_bfd, s->bfd_section,
&link_info);
}
@@ -2763,11 +2769,9 @@ lang_get_output_target (void)
/* Open the output file. */
-static bfd *
+static void
open_output (const char *name)
{
- bfd *output;
-
output_target = lang_get_output_target ();
/* Has the user requested a particular endianness on the command
@@ -2819,9 +2823,9 @@ open_output (const char *name)
}
}
- output = bfd_openw (name, output_target);
+ link_info.output_bfd = bfd_openw (name, output_target);
- if (output == NULL)
+ if (link_info.output_bfd == NULL)
{
if (bfd_get_error () == bfd_error_invalid_target)
einfo (_("%P%F: target %s not found\n"), output_target);
@@ -2831,19 +2835,18 @@ open_output (const char *name)
delete_output_file_on_failure = TRUE;
- if (! bfd_set_format (output, bfd_object))
+ if (! bfd_set_format (link_info.output_bfd, bfd_object))
einfo (_("%P%F:%s: can not make object file: %E\n"), name);
- if (! bfd_set_arch_mach (output,
+ if (! bfd_set_arch_mach (link_info.output_bfd,
ldfile_output_architecture,
ldfile_output_machine))
einfo (_("%P%F:%s: can not set architecture: %E\n"), name);
- link_info.hash = bfd_link_hash_table_create (output);
+ link_info.hash = bfd_link_hash_table_create (link_info.output_bfd);
if (link_info.hash == NULL)
einfo (_("%P%F: can not create hash table: %E\n"));
- bfd_set_gp_size (output, g_switch_value);
- return output;
+ bfd_set_gp_size (link_info.output_bfd, g_switch_value);
}
static void
@@ -2852,21 +2855,21 @@ ldlang_open_output (lang_statement_union_type *statement)
switch (statement->header.type)
{
case lang_output_statement_enum:
- ASSERT (output_bfd == NULL);
- output_bfd = open_output (statement->output_statement.name);
+ ASSERT (link_info.output_bfd == NULL);
+ open_output (statement->output_statement.name);
ldemul_set_output_arch ();
if (config.magic_demand_paged && !link_info.relocatable)
- output_bfd->flags |= D_PAGED;
+ link_info.output_bfd->flags |= D_PAGED;
else
- output_bfd->flags &= ~D_PAGED;
+ link_info.output_bfd->flags &= ~D_PAGED;
if (config.text_read_only)
- output_bfd->flags |= WP_TEXT;
+ link_info.output_bfd->flags |= WP_TEXT;
else
- output_bfd->flags &= ~WP_TEXT;
+ link_info.output_bfd->flags &= ~WP_TEXT;
if (link_info.traditional_format)
- output_bfd->flags |= BFD_TRADITIONAL_FORMAT;
+ link_info.output_bfd->flags |= BFD_TRADITIONAL_FORMAT;
else
- output_bfd->flags &= ~BFD_TRADITIONAL_FORMAT;
+ link_info.output_bfd->flags &= ~BFD_TRADITIONAL_FORMAT;
break;
case lang_target_statement_enum:
@@ -3078,7 +3081,7 @@ ldlang_add_undef (const char *const name)
new->name = xstrdup (name);
- if (output_bfd != NULL)
+ if (link_info.output_bfd != NULL)
insert_undefined (new->name);
}
@@ -3446,17 +3449,17 @@ process_insert_statements (void)
if (first_sec->prev != NULL)
first_sec->prev->next = last_sec->next;
else
- output_bfd->sections = last_sec->next;
+ link_info.output_bfd->sections = last_sec->next;
if (last_sec->next != NULL)
last_sec->next->prev = first_sec->prev;
else
- output_bfd->section_last = first_sec->prev;
+ link_info.output_bfd->section_last = first_sec->prev;
/* Add back. */
last_sec->next = sec->next;
if (sec->next != NULL)
sec->next->prev = last_sec;
else
- output_bfd->section_last = last_sec;
+ link_info.output_bfd->section_last = last_sec;
first_sec->prev = sec;
sec->next = first_sec;
}
@@ -3516,7 +3519,7 @@ strip_excluded_output_sections (void)
exclude = (output_section->rawsize == 0
&& (output_section->flags & SEC_KEEP) == 0
- && !bfd_section_removed_from_list (output_bfd,
+ && !bfd_section_removed_from_list (link_info.output_bfd,
output_section));
/* Some sections have not yet been sized, notably .gnu.version,
@@ -3548,8 +3551,8 @@ strip_excluded_output_sections (void)
&& !os->update_dot_tree)
os->ignored = TRUE;
output_section->flags |= SEC_EXCLUDE;
- bfd_section_list_remove (output_bfd, output_section);
- output_bfd->section_count--;
+ bfd_section_list_remove (link_info.output_bfd, output_section);
+ link_info.output_bfd->section_count--;
}
}
@@ -3799,7 +3802,8 @@ print_input_section (asection *i)
++len;
}
- if (i->output_section != NULL && i->output_section->owner == output_bfd)
+ if (i->output_section != NULL
+ && i->output_section->owner == link_info.output_bfd)
addr = i->output_section->vma + i->output_offset;
else
{
@@ -3826,7 +3830,8 @@ print_input_section (asection *i)
minfo (_("%W (size before relaxing)\n"), i->rawsize);
}
- if (i->output_section != NULL && i->output_section->owner == output_bfd)
+ if (i->output_section != NULL
+ && i->output_section->owner == link_info.output_bfd)
{
if (link_info.reduce_memory_overheads)
bfd_link_hash_traverse (link_info.hash, print_one_symbol, i);
@@ -4300,15 +4305,15 @@ lang_check_section_addresses (void)
bfd_size_type amt;
lang_memory_region_type *m;
- if (bfd_count_sections (output_bfd) <= 1)
+ if (bfd_count_sections (link_info.output_bfd) <= 1)
return;
- amt = bfd_count_sections (output_bfd) * sizeof (asection *);
+ amt = bfd_count_sections (link_info.output_bfd) * sizeof (asection *);
sections = xmalloc (amt);
/* Scan all sections in the output list. */
count = 0;
- for (s = output_bfd->sections; s != NULL; s = s->next)
+ for (s = link_info.output_bfd->sections; s != NULL; s = s->next)
{
/* Only consider loadable sections with real contents. */
if (IGNORE_SECTION (s) || s->size == 0)
@@ -4326,7 +4331,7 @@ lang_check_section_addresses (void)
spp = sections;
s = *spp++;
- s_start = bfd_section_lma (output_bfd, s);
+ s_start = bfd_section_lma (link_info.output_bfd, s);
s_end = s_start + TO_ADDR (s->size) - 1;
for (count--; count; count--)
{
@@ -4337,7 +4342,7 @@ lang_check_section_addresses (void)
os_start = s_start;
os_end = s_end;
s = *spp++;
- s_start = bfd_section_lma (output_bfd, s);
+ s_start = bfd_section_lma (link_info.output_bfd, s);
s_end = s_start + TO_ADDR (s->size) - 1;
/* Look for an overlap. */
@@ -4445,8 +4450,10 @@ lang_size_sections_1
address from the input section. FIXME: This is COFF
specific; it would be cleaner if there were some other way
to do this, but nothing simple comes to mind. */
- if ((bfd_get_flavour (output_bfd) == bfd_target_ecoff_flavour
- || bfd_get_flavour (output_bfd) == bfd_target_coff_flavour)
+ if (((bfd_get_flavour (link_info.output_bfd)
+ == bfd_target_ecoff_flavour)
+ || (bfd_get_flavour (link_info.output_bfd)
+ == bfd_target_coff_flavour))
&& (os->bfd_section->flags & SEC_COFF_SHARED_LIBRARY) != 0)
{
asection *input;
@@ -4516,12 +4523,12 @@ lang_size_sections_1
if (command_line.check_section_addresses)
einfo (_("%P%F: error: no memory region specified"
" for loadable section `%s'\n"),
- bfd_get_section_name (output_bfd,
+ bfd_get_section_name (link_info.output_bfd,
os->bfd_section));
else
einfo (_("%P: warning: no memory region specified"
" for loadable section `%s'\n"),
- bfd_get_section_name (output_bfd,
+ bfd_get_section_name (link_info.output_bfd,
os->bfd_section));
}
@@ -5010,7 +5017,7 @@ lang_size_sections (bfd_boolean *relax, bfd_boolean check_regions)
/* Find maximum alignment power of sections between
DATA_SEGMENT_ALIGN and DATA_SEGMENT_RELRO_END. */
- for (sec = output_bfd->sections; sec; sec = sec->next)
+ for (sec = link_info.output_bfd->sections; sec; sec = sec->next)
if (sec->vma >= expld.dataseg.base
&& sec->vma < expld.dataseg.relro_end
&& sec->alignment_power > max_alignment_power)
@@ -5209,13 +5216,13 @@ lang_set_startof (void)
if (link_info.relocatable)
return;
- for (s = output_bfd->sections; s != NULL; s = s->next)
+ for (s = link_info.output_bfd->sections; s != NULL; s = s->next)
{
const char *secname;
char *buf;
struct bfd_link_hash_entry *h;
- secname = bfd_get_section_name (output_bfd, s);
+ secname = bfd_get_section_name (link_info.output_bfd, s);
buf = xmalloc (10 + strlen (secname));
sprintf (buf, ".startof.%s", secname);
@@ -5223,7 +5230,7 @@ lang_set_startof (void)
if (h != NULL && h->type == bfd_link_hash_undefined)
{
h->type = bfd_link_hash_defined;
- h->u.def.value = bfd_get_section_vma (output_bfd, s);
+ h->u.def.value = bfd_get_section_vma (link_info.output_bfd, s);
h->u.def.section = bfd_abs_section_ptr;
}
@@ -5278,10 +5285,10 @@ lang_end (void)
bfd_vma val;
val = (h->u.def.value
- + bfd_get_section_vma (output_bfd,
+ + bfd_get_section_vma (link_info.output_bfd,
h->u.def.section->output_section)
+ h->u.def.section->output_offset);
- if (! bfd_set_start_address (output_bfd, val))
+ if (! bfd_set_start_address (link_info.output_bfd, val))
einfo (_("%P%F:%s: can't set start address\n"), entry_symbol.name);
}
else
@@ -5294,7 +5301,7 @@ lang_end (void)
val = bfd_scan_vma (entry_symbol.name, &send, 0);
if (*send == '\0')
{
- if (! bfd_set_start_address (output_bfd, val))
+ if (! bfd_set_start_address (link_info.output_bfd, val))
einfo (_("%P%F: can't set start address\n"));
}
else
@@ -5303,17 +5310,17 @@ lang_end (void)
/* Can't find the entry symbol, and it's not a number. Use
the first address in the text section. */
- ts = bfd_get_section_by_name (output_bfd, entry_section);
+ ts = bfd_get_section_by_name (link_info.output_bfd, entry_section);
if (ts != NULL)
{
if (warn)
einfo (_("%P: warning: cannot find entry symbol %s;"
" defaulting to %V\n"),
entry_symbol.name,
- bfd_get_section_vma (output_bfd, ts));
- if (! bfd_set_start_address (output_bfd,
- bfd_get_section_vma (output_bfd,
- ts)))
+ bfd_get_section_vma (link_info.output_bfd, ts));
+ if (!(bfd_set_start_address
+ (link_info.output_bfd,
+ bfd_get_section_vma (link_info.output_bfd, ts))))
einfo (_("%P%F: can't set start address\n"));
}
else
@@ -5354,7 +5361,7 @@ lang_check (void)
{
input_bfd = file->input_statement.the_bfd;
compatible
- = bfd_arch_get_compatible (input_bfd, output_bfd,
+ = bfd_arch_get_compatible (input_bfd, link_info.output_bfd,
command_line.accept_unknown_input_arch);
/* In general it is not possible to perform a relocatable
@@ -5365,13 +5372,14 @@ lang_check (void)
relocs for other link purposes than a final link). */
if ((link_info.relocatable || link_info.emitrelocations)
&& (compatible == NULL
- || bfd_get_flavour (input_bfd) != bfd_get_flavour (output_bfd))
+ || (bfd_get_flavour (input_bfd)
+ != bfd_get_flavour (link_info.output_bfd)))
&& (bfd_get_file_flags (input_bfd) & HAS_RELOC) != 0)
{
einfo (_("%P%F: Relocatable linking with relocations from"
" format %s (%B) to format %s (%B) is not supported\n"),
bfd_get_target (input_bfd), input_bfd,
- bfd_get_target (output_bfd), output_bfd);
+ bfd_get_target (link_info.output_bfd), link_info.output_bfd);
/* einfo with %F exits. */
}
@@ -5381,7 +5389,7 @@ lang_check (void)
einfo (_("%P%X: %s architecture of input file `%B'"
" is incompatible with %s output\n"),
bfd_printable_name (input_bfd), input_bfd,
- bfd_printable_name (output_bfd));
+ bfd_printable_name (link_info.output_bfd));
}
else if (bfd_count_sections (input_bfd))
{
@@ -5397,7 +5405,7 @@ lang_check (void)
information which is needed in the output file. */
if (! command_line.warn_mismatch)
pfn = bfd_set_error_handler (ignore_bfd_errors);
- if (! bfd_merge_private_bfd_data (input_bfd, output_bfd))
+ if (! bfd_merge_private_bfd_data (input_bfd, link_info.output_bfd))
{
if (command_line.warn_mismatch)
einfo (_("%P%X: failed to merge target specific data"
@@ -5489,7 +5497,7 @@ lang_one_common (struct bfd_link_hash_entry *h, void *info)
header_printed = TRUE;
}
- name = bfd_demangle (output_bfd, h->root.string,
+ name = bfd_demangle (link_info.output_bfd, h->root.string,
DMGL_ANSI | DMGL_PARAMS);
if (name == NULL)
{
@@ -5664,7 +5672,7 @@ ldlang_add_file (lang_input_statement_type *entry)
/* The BFD linker needs to have a list of all input BFDs involved in
a link. */
ASSERT (entry->the_bfd->link_next == NULL);
- ASSERT (entry->the_bfd != output_bfd);
+ ASSERT (entry->the_bfd != link_info.output_bfd);
*link_info.input_bfds_tail = entry->the_bfd;
link_info.input_bfds_tail = &entry->the_bfd->link_next;
@@ -5786,7 +5794,7 @@ lang_reset_memory_regions (void)
os->processed_lma = FALSE;
}
- for (o = output_bfd->sections; o != NULL; o = o->next)
+ for (o = link_info.output_bfd->sections; o != NULL; o = o->next)
{
/* Save the last size for possible use by bfd_relax_section. */
o->rawsize = o->size;
@@ -5858,7 +5866,7 @@ lang_gc_sections (void)
}
if (link_info.gc_sections)
- bfd_gc_sections (output_bfd, &link_info);
+ bfd_gc_sections (link_info.output_bfd, &link_info);
}
/* Worker for lang_find_relro_sections_1. */
@@ -5873,7 +5881,7 @@ find_relro_section_callback (lang_wild_statement_type *ptr ATTRIBUTE_UNUSED,
/* Discarded, excluded and ignored sections effectively have zero
size. */
if (section->output_section != NULL
- && section->output_section->owner == output_bfd
+ && section->output_section->owner == link_info.output_bfd
&& (section->output_section->flags & SEC_EXCLUDE) == 0
&& !IGNORE_SECTION (section)
&& section->size != 0)
@@ -6043,10 +6051,10 @@ lang_process (void)
sections, so that GCed sections are not merged, but before
assigning dynamic symbols, since removing whole input sections
is hard then. */
- bfd_merge_sections (output_bfd, &link_info);
+ bfd_merge_sections (link_info.output_bfd, &link_info);
/* Look for a text section and set the readonly attribute in it. */
- found = bfd_get_section_by_name (output_bfd, ".text");
+ found = bfd_get_section_by_name (link_info.output_bfd, ".text");
if (found != NULL)
{
@@ -6376,11 +6384,11 @@ lang_abs_symbol_at_beginning_of (const char *secname, const char *name)
h->type = bfd_link_hash_defined;
- sec = bfd_get_section_by_name (output_bfd, secname);
+ sec = bfd_get_section_by_name (link_info.output_bfd, secname);
if (sec == NULL)
h->u.def.value = 0;
else
- h->u.def.value = bfd_get_section_vma (output_bfd, sec);
+ h->u.def.value = bfd_get_section_vma (link_info.output_bfd, sec);
h->u.def.section = bfd_abs_section_ptr;
}
@@ -6407,11 +6415,11 @@ lang_abs_symbol_at_end_of (const char *secname, const char *name)
h->type = bfd_link_hash_defined;
- sec = bfd_get_section_by_name (output_bfd, secname);
+ sec = bfd_get_section_by_name (link_info.output_bfd, secname);
if (sec == NULL)
h->u.def.value = 0;
else
- h->u.def.value = (bfd_get_section_vma (output_bfd, sec)
+ h->u.def.value = (bfd_get_section_vma (link_info.output_bfd, sec)
+ TO_ADDR (sec->size));
h->u.def.section = bfd_abs_section_ptr;
@@ -6605,7 +6613,7 @@ lang_record_phdrs (void)
else
at = exp_get_vma (l->at, 0, "phdr load address");
- if (! bfd_record_phdr (output_bfd, l->type,
+ if (! bfd_record_phdr (link_info.output_bfd, l->type,
l->flags != NULL, flags, l->at != NULL,
at, l->filehdr, l->phdrs, c, secs))
einfo (_("%F%P: bfd_record_phdr failed: %E\n"));