From: Alan Modra Date: Fri, 8 Apr 2016 08:22:03 +0000 (+0930) Subject: PR18452, ld allows overlapping sections X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=136a43b762ce7bc692645cc0d9d50c934f9aa392;p=binutils-gdb.git PR18452, ld allows overlapping sections PR 18452 * ldlang.c (maybe_overlays): Delete. (lang_size_sections_1): Remove code setting maybe_overlays. (lang_check_section_addresses): Instead detect overlays by exact match of section VMAs here. Fix memory leak. --- diff --git a/ld/ChangeLog b/ld/ChangeLog index 4d82ea45b38..3c40941fd4f 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,11 @@ +2016-04-08 Alan Modra + + PR 18452 + * ldlang.c (maybe_overlays): Delete. + (lang_size_sections_1): Remove code setting maybe_overlays. + (lang_check_section_addresses): Instead detect overlays by + exact match of section VMAs here. Fix memory leak. + 2016-04-08 Dan Gisselquist * ldlang.c (print_output_section_statement): Show minfo size diff --git a/ld/ldlang.c b/ld/ldlang.c index 5fbea3ff9f9..1947efc158d 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -75,7 +75,6 @@ static lang_statement_list_type **stat_save_ptr = &stat_save[0]; static struct unique_sections *unique_section_list; static struct asneeded_minfo *asneeded_list_head; static unsigned int opb_shift = 0; -static bfd_boolean maybe_overlays = FALSE; /* Forward declarations. */ static void exp_init_os (etree_type *); @@ -4742,6 +4741,7 @@ lang_check_section_addresses (void) bfd_vma p_start = 0; bfd_vma p_end = 0; lang_memory_region_type *m; + bfd_boolean overlays; if (bfd_count_sections (link_info.output_bfd) <= 1) return; @@ -4763,11 +4763,14 @@ lang_check_section_addresses (void) } if (count <= 1) - return; + { + free (sections); + return; + } qsort (sections, count, sizeof (*sections), sort_sections_by_lma); - /* First check sections LMAs. There should be no overlap of LMAs on + /* First check section LMAs. There should be no overlap of LMAs on loadable sections, even with overlays. */ for (p = NULL, i = 0; i < count; i++) { @@ -4797,11 +4800,28 @@ lang_check_section_addresses (void) } } - /* Now check sections VMAs if no overlays were detected. */ - if (!maybe_overlays) + /* If any non-zero size allocated section (excluding tbss) starts at + exactly the same VMA as another such section, then we have + overlays. Overlays generated by the OVERLAY keyword will have + this property. It is possible to intentionally generate overlays + that fail this test, but it would be unusual. */ + qsort (sections, count, sizeof (*sections), sort_sections_by_vma); + overlays = FALSE; + p_start = sections[0].sec->vma; + for (i = 1; i < count; i++) { - qsort (sections, count, sizeof (*sections), sort_sections_by_vma); + s_start = sections[i].sec->vma; + if (p_start == s_start) + { + overlays = TRUE; + break; + } + p_start = s_start; + } + /* Now check section VMAs if no overlays were detected. */ + if (!overlays) + { for (p = NULL, i = 0; i < count; i++) { s = sections[i].sec; @@ -4835,7 +4855,6 @@ lang_check_section_addresses (void) if (m->had_full_message) einfo (_("%X%P: region `%s' overflowed by %ld bytes\n"), m->name_list.name, (long)(m->current - (m->origin + m->length))); - } /* Make sure the new address is within the region. We explicitly permit the @@ -5149,18 +5168,6 @@ lang_size_sections_1 if (bfd_is_abs_section (os->bfd_section) || os->ignored) break; - if (r->last_os != NULL - && !IGNORE_SECTION (os->bfd_section) - && os->bfd_section->size != 0) - { - asection *last; - - last = r->last_os->output_section_statement.bfd_section; - if (dot + TO_ADDR (os->bfd_section->size) > last->vma - && dot < last->vma + TO_ADDR (last->size)) - maybe_overlays = TRUE; - } - /* Keep track of normal sections using the default lma region. We use this to set the lma for following sections. Overlays or other linker