summaryrefslogtreecommitdiffstats
path: root/ld/ldlang.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2005-05-03 01:05:03 +0000
committerH.J. Lu <hjl.tools@gmail.com>2005-05-03 01:05:03 +0000
commit5daa8fe797a3f310f9e53282e097b52583ab5109 (patch)
tree328f6a35f3261e96844ec9da27a4b088bd5981d9 /ld/ldlang.c
parent3c95e6af3b96e8603713949ffb3e74cb5e8f2436 (diff)
downloadppe42-binutils-5daa8fe797a3f310f9e53282e097b52583ab5109.tar.gz
ppe42-binutils-5daa8fe797a3f310f9e53282e097b52583ab5109.zip
bfd/
2005-05-02 H.J. Lu <hongjiu.lu@intel.com> * bfd.c (bfd): Remove section_tail and add section_last. (bfd_preserve): Likewise. (bfd_preserve_save): Likewise. (bfd_preserve_restore): Likewise. * opncls.c (_bfd_new_bfd): Likewise. * coffcode.h (coff_compute_section_file_positions): Updated. (coff_compute_section_file_positions): Likewise. * elf.c (assign_section_numbers): Likewise. * elf32-i370.c (i370_elf_size_dynamic_sections): Likewise. * elf64-mmix.c (mmix_elf_final_link): Likewise. * elfxx-ia64.c (elfNN_ia64_object_p): Likewise. * elfxx-mips.c (_bfd_mips_elf_link_hash_table_create): Likewise. * sunos.c (sunos_add_dynamic_symbols): Likewise. * xcofflink.c (_bfd_xcoff_bfd_final_link): Likewise. * ecoff.c (bfd_debug_section): Initialize prev. * section.c (bfd_section): Add prev. (bfd_section_list_remove): Updated. (bfd_section_list_append): New. (bfd_section_list_insert_after): New. (bfd_section_list_insert_before): New. (bfd_section_list_insert): Removed. (bfd_section_removed_from_list): Updated. (STD_SECTION): Initialize prev. (bfd_section_init): Updated. (bfd_section_list_clear): Updated. * bfd-in2.h: Regenerated. gas/ 2005-05-02 H.J. Lu <hongjiu.lu@intel.com> * write.c (write_object_file): Use bfd_section_double_list_remove to remove sections. ld/ 2005-05-02 H.J. Lu <hongjiu.lu@intel.com> * emultempl/elf32.em (gld${EMULATION_NAME}_strip_empty_section): Updated for bfd_section_list_remove change. * ldlang.c (lang_insert_orphan): Likewise. (strip_excluded_output_sections): Likewise. (sort_sections_by_lma): New. (lang_check_section_addresses): Sort the sections before checking addresses.
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r--ld/ldlang.c128
1 files changed, 75 insertions, 53 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 2568feda9d..895eded0bb 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -1202,7 +1202,6 @@ lang_insert_orphan (lang_input_statement_type *file,
etree_type *load_base;
lang_output_section_statement_type *os;
lang_output_section_statement_type **os_tail;
- asection **bfd_tail;
/* Start building a list of statements for this section.
First save the current statement pointer. */
@@ -1256,7 +1255,6 @@ lang_insert_orphan (lang_input_statement_type *file,
os_tail = ((lang_output_section_statement_type **)
lang_output_section_statement.tail);
- bfd_tail = output_bfd->section_tail;
os = lang_enter_output_section_statement (secname, address, 0, NULL, NULL,
load_base, 0);
@@ -1288,7 +1286,7 @@ lang_insert_orphan (lang_input_statement_type *file,
if (after != NULL && os->bfd_section != NULL)
{
- asection *snew;
+ asection *snew, *as;
snew = os->bfd_section;
@@ -1314,12 +1312,15 @@ lang_insert_orphan (lang_input_statement_type *file,
if (place->section == NULL)
place->section = &output_bfd->sections;
- /* Unlink the section. */
- ASSERT (*bfd_tail == snew);
- bfd_section_list_remove (output_bfd, bfd_tail);
+ as = *place->section;
+ if (as != snew && as->prev != snew)
+ {
+ /* Unlink the section. */
+ bfd_section_list_remove (output_bfd, snew);
- /* Now tack it back on in the right place. */
- bfd_section_list_insert (output_bfd, place->section, snew);
+ /* Now tack it back on in the right place. */
+ bfd_section_list_insert_before (output_bfd, as, snew);
+ }
/* Save the end of this list. Further ophans of this type will
follow the one we've just added. */
@@ -3044,17 +3045,12 @@ strip_excluded_output_sections (void)
s = os->bfd_section;
if (s != NULL && (s->flags & SEC_EXCLUDE) != 0)
{
- asection **p;
-
os->bfd_section = NULL;
-
- for (p = &output_bfd->sections; *p; p = &(*p)->next)
- if (*p == s)
- {
- bfd_section_list_remove (output_bfd, p);
- output_bfd->section_count--;
- break;
- }
+ if (!bfd_section_removed_from_list (output_bfd, s))
+ {
+ bfd_section_list_remove (output_bfd, s);
+ output_bfd->section_count--;
+ }
}
}
}
@@ -3683,6 +3679,22 @@ size_input_section
return dot;
}
+static int
+sort_sections_by_lma (const void *arg1, const void *arg2)
+{
+ const asection *sec1 = *(const asection **) arg1;
+ const asection *sec2 = *(const asection **) arg2;
+
+ if (bfd_section_lma (sec1->owner, sec1)
+ < bfd_section_lma (sec2->owner, sec2))
+ return -1;
+ else if (bfd_section_lma (sec1->owner, sec1)
+ > bfd_section_lma (sec2->owner, sec2))
+ return 1;
+
+ return 0;
+}
+
#define IGNORE_SECTION(s) \
((s->flags & SEC_NEVER_LOAD) != 0 \
|| (s->flags & SEC_ALLOC) == 0 \
@@ -3696,52 +3708,62 @@ size_input_section
static void
lang_check_section_addresses (void)
{
- asection *s;
+ asection *s, *os;
+ asection **sections, **spp;
+ unsigned int count;
+ bfd_vma s_start;
+ bfd_vma s_end;
+ bfd_vma os_start;
+ bfd_vma os_end;
+ bfd_size_type amt;
+
+ if (bfd_count_sections (output_bfd) <= 1)
+ return;
+
+ amt = bfd_count_sections (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)
{
- asection *os;
-
- /* Ignore sections which are not loaded or which have no contents. */
+ /* Only consider loadable sections with real contents. */
if (IGNORE_SECTION (s) || s->size == 0)
continue;
- /* Once we reach section 's' stop our seach. This prevents two
- warning messages from being produced, one for 'section A overlaps
- section B' and one for 'section B overlaps section A'. */
- for (os = output_bfd->sections; os != s; os = os->next)
- {
- bfd_vma s_start;
- bfd_vma s_end;
- bfd_vma os_start;
- bfd_vma os_end;
-
- /* Only consider loadable sections with real contents. */
- if (IGNORE_SECTION (os) || os->size == 0)
- continue;
-
- /* We must check the sections' LMA addresses not their
- VMA addresses because overlay sections can have
- 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 (s->size) - 1;
- os_end = os_start + TO_ADDR (os->size) - 1;
+ sections[count] = s;
+ count++;
+ }
+
+ if (count <= 1)
+ return;
- /* Look for an overlap. */
- if ((s_end < os_start) || (s_start > os_end))
- continue;
+ qsort (sections, (size_t) count, sizeof (asection *),
+ sort_sections_by_lma);
- einfo (
-_("%X%P: section %s [%V -> %V] overlaps section %s [%V -> %V]\n"),
- s->name, s_start, s_end, os->name, os_start, os_end);
+ spp = sections;
+ s = *spp++;
+ s_start = bfd_section_lma (output_bfd, s);
+ s_end = s_start + TO_ADDR (s->size) - 1;
+ for (count--; count; count--)
+ {
+ /* We must check the sections' LMA addresses not their VMA
+ addresses because overlay sections can have overlapping VMAs
+ but they must have distinct LMAs. */
+ os = s;
+ os_start = s_start;
+ os_end = s_end;
+ s = *spp++;
+ s_start = bfd_section_lma (output_bfd, s);
+ s_end = s_start + TO_ADDR (s->size) - 1;
- /* Once we have found one overlap for this section,
- stop looking for others. */
- break;
- }
+ /* Look for an overlap. */
+ if (s_end >= os_start && s_start <= os_end)
+ einfo (_("%X%P: section %s [%V -> %V] overlaps section %s [%V -> %V]\n"),
+ s->name, s_start, s_end, os->name, os_start, os_end);
}
+
+ free (sections);
}
/* Make sure the new address is within the region. We explicitly permit the
OpenPOWER on IntegriCloud