p->next = NULL;
p->symbol_count = 0;
p->dynamic = config.dynamic_link;
+ p->add_needed = add_needed;
p->as_needed = as_needed;
p->whole_archive = whole_archive;
p->loaded = FALSE;
}
else if (!ud->map_symbol_def_tail)
ud->map_symbol_def_tail = &ud->map_symbol_def_head;
+
def = obstack_alloc (&map_obstack, sizeof *def);
def->entry = hash_entry;
- *ud->map_symbol_def_tail = def;
+ *(ud->map_symbol_def_tail) = def;
ud->map_symbol_def_tail = &def->next;
}
return TRUE;
einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME);
new = stat_alloc (SECTION_USERDATA_SIZE);
+ memset (new, 0, SECTION_USERDATA_SIZE);
s->bfd_section = bfd_get_section_by_name (output_bfd, s->name);
if (s->bfd_section == NULL)
}
}
\f
-/* Sections marked with the SEC_LINK_ONCE flag should only be linked
- once into the output. This routine checks each section, and
- arrange to discard it if a section of the same name has already
- been linked. If the section has COMDAT information, then it uses
- that to decide whether the section should be included. This code
- assumes that all relevant sections have the SEC_LINK_ONCE flag set;
- that is, it does not depend solely upon the section name.
- section_already_linked is called via bfd_map_over_sections. */
-
-/* This is the shape of the elements inside the already_linked hash
- table. It maps a name onto a list of already_linked elements with
- the same name. It's possible to get more than one element in a
- list if the COMDAT sections have different names. */
-
-struct already_linked_hash_entry
-{
- struct bfd_hash_entry root;
- struct already_linked *entry;
-};
-
-struct already_linked
-{
- struct already_linked *next;
- asection *sec;
-};
-
-/* The hash table. */
-
-static struct bfd_hash_table already_linked_table;
-
static void
section_already_linked (bfd *abfd, asection *sec, void *data)
{
lang_input_statement_type *entry = data;
- flagword flags;
- const char *name;
- struct already_linked *l;
- struct already_linked_hash_entry *already_linked_list;
/* If we are only reading symbols from this object, then we want to
discard all sections. */
return;
}
- flags = sec->flags;
- if ((flags & SEC_LINK_ONCE) == 0)
- return;
-
- /* FIXME: When doing a relocatable link, we may have trouble
- copying relocations in other sections that refer to local symbols
- in the section being discarded. Those relocations will have to
- be converted somehow; as of this writing I'm not sure that any of
- the backends handle that correctly.
-
- It is tempting to instead not discard link once sections when
- doing a relocatable link (technically, they should be discarded
- whenever we are building constructors). However, that fails,
- because the linker winds up combining all the link once sections
- into a single large link once section, which defeats the purpose
- of having link once sections in the first place.
-
- Also, not merging link once sections in a relocatable link
- causes trouble for MIPS ELF, which relies on link once semantics
- to handle the .reginfo section correctly. */
-
- name = bfd_get_section_name (abfd, sec);
-
- already_linked_list =
- ((struct already_linked_hash_entry *)
- bfd_hash_lookup (&already_linked_table, name, TRUE, FALSE));
-
- for (l = already_linked_list->entry; l != NULL; l = l->next)
- {
- if (sec->comdat == NULL
- || l->sec->comdat == NULL
- || strcmp (sec->comdat->name, l->sec->comdat->name) == 0)
- {
- /* The section has already been linked. See if we should
- issue a warning. */
- switch (flags & SEC_LINK_DUPLICATES)
- {
- default:
- abort ();
-
- case SEC_LINK_DUPLICATES_DISCARD:
- break;
-
- case SEC_LINK_DUPLICATES_ONE_ONLY:
- if (sec->comdat == NULL)
- einfo (_("%P: %B: warning: ignoring duplicate section `%s'\n"),
- abfd, name);
- else
- einfo (_("%P: %B: warning: ignoring duplicate `%s'"
- " section symbol `%s'\n"),
- abfd, name, sec->comdat->name);
- break;
-
- case SEC_LINK_DUPLICATES_SAME_CONTENTS:
- /* FIXME: We should really dig out the contents of both
- sections and memcmp them. The COFF/PE spec says that
- the Microsoft linker does not implement this
- correctly, so I'm not going to bother doing it
- either. */
- /* Fall through. */
- case SEC_LINK_DUPLICATES_SAME_SIZE:
- if (bfd_section_size (abfd, sec)
- != bfd_section_size (l->sec->owner, l->sec))
- einfo (_("%P: %B: warning: duplicate section `%s'"
- " has different size\n"),
- abfd, name);
- break;
- }
-
- /* Set the output_section field so that lang_add_section
- does not create a lang_input_section structure for this
- section. Since there might be a symbol in the section
- being discarded, we must retain a pointer to the section
- which we are really going to use. */
- sec->output_section = bfd_abs_section_ptr;
- sec->kept_section = l->sec;
-
- if (flags & SEC_GROUP)
- bfd_discard_group (abfd, sec);
-
- return;
- }
- }
-
- /* This is the first section with this name. Record it. Allocate
- the memory from the same obstack as the hash table is kept in. */
-
- l = bfd_hash_allocate (&already_linked_table, sizeof *l);
-
- l->sec = sec;
- l->next = already_linked_list->entry;
- already_linked_list->entry = l;
-}
-
-/* Support routines for the hash table used by section_already_linked,
- initialize the table, fill in an entry and remove the table. */
-
-static struct bfd_hash_entry *
-already_linked_newfunc (struct bfd_hash_entry *entry ATTRIBUTE_UNUSED,
- struct bfd_hash_table *table,
- const char *string ATTRIBUTE_UNUSED)
-{
- struct already_linked_hash_entry *ret =
- bfd_hash_allocate (table, sizeof (struct already_linked_hash_entry));
-
- ret->entry = NULL;
-
- return &ret->root;
-}
-
-static void
-already_linked_table_init (void)
-{
- if (! bfd_hash_table_init_n (&already_linked_table,
- already_linked_newfunc,
- 42))
- einfo (_("%P%F: Failed to create hash table\n"));
-}
-
-static void
-already_linked_table_free (void)
-{
- bfd_hash_table_free (&already_linked_table);
+ bfd_section_already_linked (abfd, sec);
}
\f
/* The wild routines.
++len;
}
- minfo ("0x%V %W", section->vma, section->_raw_size);
+ minfo ("0x%V %W", section->vma, section->size);
if (output_section_statement->load_base != NULL)
{
print_input_section (lang_input_section_type *in)
{
asection *i = in->section;
- bfd_size_type size = i->_cooked_size != 0 ? i->_cooked_size : i->_raw_size;
+ bfd_size_type size = i->size;
init_opb ();
if (size != 0)
minfo ("0x%V %W %B\n", addr, TO_ADDR (size), i->owner);
- if (size != i->_raw_size)
+ if (size != i->rawsize && i->rawsize != 0)
{
len = SECTION_NAME_MAP_LENGTH + 3;
#ifdef BFD64
--len;
}
- minfo (_("%W (size before relaxing)\n"), i->_raw_size);
+ minfo (_("%W (size before relaxing)\n"), i->rawsize);
}
if (i->output_section != NULL && (i->flags & SEC_EXCLUDE) == 0)
}
pad->padding_statement.output_offset = dot - output_section->vma;
pad->padding_statement.size = alignment_needed;
- output_section->_raw_size += alignment_needed;
+ output_section->size += alignment_needed;
}
/* Work out how much this section will move the dot point. */
i->output_offset = dot - o->vma;
/* Mark how big the output section must be to contain this now. */
- if (i->_cooked_size != 0)
- dot += TO_ADDR (i->_cooked_size);
- else
- dot += TO_ADDR (i->_raw_size);
- o->_raw_size = TO_SIZE (dot - o->vma);
+ dot += TO_ADDR (i->size);
+ o->size = TO_SIZE (dot - o->vma);
}
else
{
return dot;
}
-#define IGNORE_SECTION(bfd, s) \
+#define IGNORE_SECTION(s) \
(((s->flags & SEC_THREAD_LOCAL) != 0 \
? (s->flags & (SEC_LOAD | SEC_NEVER_LOAD)) != SEC_LOAD \
: (s->flags & (SEC_ALLOC | SEC_NEVER_LOAD)) != SEC_ALLOC) \
- || bfd_section_size (bfd, s) == 0)
+ || s->size == 0)
/* Check to see if any allocated sections overlap with other allocated
sections. This can happen when the linker script specifically specifies
asection *os;
/* Ignore sections which are not loaded or which have no contents. */
- if (IGNORE_SECTION (output_bfd, s))
+ if (IGNORE_SECTION (s))
continue;
/* Once we reach section 's' stop our seach. This prevents two
bfd_vma os_end;
/* Only consider loadable sections with real contents. */
- if (IGNORE_SECTION (output_bfd, os))
+ if (IGNORE_SECTION (os))
continue;
/* We must check the sections' LMA addresses not their
overlapping VMAs but they must have distinct LMAs. */
s_start = bfd_section_lma (output_bfd, s);
os_start = bfd_section_lma (output_bfd, os);
- s_end = s_start + TO_ADDR (bfd_section_size (output_bfd, s)) - 1;
- os_end = os_start + TO_ADDR (bfd_section_size (output_bfd, os)) - 1;
+ s_end = s_start + TO_ADDR (s->size) - 1;
+ os_end = os_start + TO_ADDR (os->size) - 1;
/* Look for an overlap. */
if ((s_end < os_start) || (s_start > os_end))
bfd_set_section_vma (os->bfd_section->owner,
os->bfd_section,
bfd_section_vma (input->owner, input));
- os->bfd_section->_raw_size = input->_raw_size;
+ os->bfd_section->size = input->size;
break;
}
/* If a loadable section is using the default memory
region, and some non default memory regions were
defined, issue an error message. */
- if (!IGNORE_SECTION (output_bfd, os->bfd_section)
+ if (!IGNORE_SECTION (os->bfd_section)
&& ! link_info.relocatable
&& check_regions
&& strcmp (os->region->name,
/* Put the section within the requested block size, or
align at the block boundary. */
after = ((os->bfd_section->vma
- + TO_ADDR (os->bfd_section->_raw_size)
+ + TO_ADDR (os->bfd_section->size)
+ os->block_value - 1)
& - (bfd_vma) os->block_value);
if (bfd_is_abs_section (os->bfd_section))
ASSERT (after == os->bfd_section->vma);
else
- os->bfd_section->_raw_size
+ os->bfd_section->size
= TO_SIZE (after - os->bfd_section->vma);
dot = os->bfd_section->vma;
if ((os->bfd_section->flags & SEC_HAS_CONTENTS) != 0
|| (os->bfd_section->flags & SEC_THREAD_LOCAL) == 0
|| link_info.relocatable)
- dot += TO_ADDR (os->bfd_section->_raw_size);
+ dot += TO_ADDR (os->bfd_section->size);
os->processed = 1;
/* Set load_base, which will be handled later. */
os->load_base = exp_intop (os->lma_region->current);
os->lma_region->current +=
- TO_ADDR (os->bfd_section->_raw_size);
+ TO_ADDR (os->bfd_section->size);
if (check_regions)
os_region_check (os, os->lma_region, NULL,
os->bfd_section->lma);
if (size < TO_SIZE ((unsigned) 1))
size = TO_SIZE ((unsigned) 1);
dot += TO_ADDR (size);
- output_section_statement->bfd_section->_raw_size += size;
+ output_section_statement->bfd_section->size += size;
/* The output section gets contents, and then we inspect for
any flags set in the input script which override any ALLOC. */
output_section_statement->bfd_section->flags |= SEC_HAS_CONTENTS;
output_section_statement->bfd_section;
size = bfd_get_reloc_size (s->reloc_statement.howto);
dot += TO_ADDR (size);
- output_section_statement->bfd_section->_raw_size += size;
+ output_section_statement->bfd_section->size += size;
}
break;
asection *i;
i = (*prev)->input_section.section;
- if (! relax)
- {
- if (i->_cooked_size == 0)
- i->_cooked_size = i->_raw_size;
- }
- else
+ if (relax)
{
bfd_boolean again;
bfd_boolean check_regions)
{
bfd_vma result;
- asection *o;
/* Callers of exp_fold_tree need to increment this. */
lang_statement_iteration++;
}
}
- /* Some backend relaxers want to refer to the output section size. Give
- them a section size that does not change on the next call while they
- relax. We can't set this at top because lang_reset_memory_regions
- which is called before we get here, sets _raw_size to 0 on relaxing
- rounds. */
- for (o = output_bfd->sections; o != NULL; o = o->next)
- o->_cooked_size = o->_raw_size;
-
return result;
}
if ((os->bfd_section->flags & SEC_HAS_CONTENTS) != 0
|| (os->bfd_section->flags & SEC_THREAD_LOCAL) == 0
|| link_info.relocatable)
- dot += TO_ADDR (os->bfd_section->_raw_size);
+ dot += TO_ADDR (os->bfd_section->size);
}
if (os->load_base)
{
asection *in = s->input_section.section;
if ((in->flags & SEC_EXCLUDE) == 0)
- {
- if (in->_cooked_size != 0)
- dot += TO_ADDR (in->_cooked_size);
- else
- dot += TO_ADDR (in->_raw_size);
- }
+ dot += TO_ADDR (in->size);
}
break;
if (h != NULL && h->type == bfd_link_hash_undefined)
{
h->type = bfd_link_hash_defined;
- if (s->_cooked_size != 0)
- h->u.def.value = TO_ADDR (s->_cooked_size);
- else
- h->u.def.value = TO_ADDR (s->_raw_size);
+ h->u.def.value = TO_ADDR (s->size);
h->u.def.section = bfd_abs_section_ptr;
}
}
}
- bfd_hash_table_free (&lang_definedness_table);
+ /* Don't bfd_hash_table_free (&lang_definedness_table);
+ map file output may result in a call of lang_track_definedness. */
}
/* This is a small function used when we want to ignore errors from
section = h->u.c.p->section;
/* Increase the size of the section to align the common sym. */
- section->_cooked_size += ((bfd_vma) 1 << (power_of_two + opb_shift)) - 1;
- section->_cooked_size &= (- (bfd_vma) 1 << (power_of_two + opb_shift));
+ section->size += ((bfd_vma) 1 << (power_of_two + opb_shift)) - 1;
+ section->size &= (- (bfd_vma) 1 << (power_of_two + opb_shift));
/* Adjust the alignment if necessary. */
if (power_of_two > section->alignment_power)
/* Change the symbol from common to defined. */
h->type = bfd_link_hash_defined;
h->u.def.section = section;
- h->u.def.value = section->_cooked_size;
+ h->u.def.value = section->size;
/* Increase the size of the section. */
- section->_cooked_size += size;
+ section->size += size;
/* Make sure the section is allocated in memory, and make sure that
it is no longer a common section. */
}
for (o = output_bfd->sections; o != NULL; o = o->next)
- o->_raw_size = 0;
+ {
+ /* Save the last size for possible use by bfd_relax_section. */
+ o->rawsize = o->size;
+ o->size = 0;
+ }
}
/* Worker for lang_gc_sections_1. */
/* Add to the hash table all undefineds on the command line. */
lang_place_undefineds ();
- already_linked_table_init ();
+ if (!bfd_section_already_linked_table_init ())
+ einfo (_("%P%F: Failed to create hash table\n"));
/* Create a bfd for each input file. */
current_target = default_target;
ldemul_after_open ();
- already_linked_table_free ();
+ bfd_section_already_linked_table_free ();
/* Make sure that we're not mixing architectures. We call this
after all the input files have been opened, but before we do any
NULL, 0);
/* We must do this after lang_do_assignments, because it uses
- _raw_size. */
+ size. */
lang_reset_memory_regions ();
/* Perform another relax pass - this time we know where the
h->u.def.value = 0;
else
h->u.def.value = (bfd_get_section_vma (output_bfd, sec)
- + TO_ADDR (bfd_section_size (output_bfd, sec)));
+ + TO_ADDR (sec->size));
h->u.def.section = bfd_abs_section_ptr;
}
if (sec == NULL)
continue;
- len = bfd_section_size (is->the_bfd, sec);
+ len = sec->size;
contents = xmalloc (len);
if (!bfd_get_section_contents (is->the_bfd, sec, contents, 0, len))
einfo (_("%X%P: unable to read .exports section contents\n"), sec);