diff options
-rw-r--r-- | bfd/ChangeLog | 7 | ||||
-rw-r--r-- | bfd/elflink.c | 82 | ||||
-rw-r--r-- | ld/ChangeLog | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-gc/gc.exp | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-gc/pr20882.d | 10 | ||||
-rw-r--r-- | ld/testsuite/ld-gc/pr20882a.s | 11 | ||||
-rw-r--r-- | ld/testsuite/ld-gc/pr20882b.s | 8 | ||||
-rw-r--r-- | ld/testsuite/ld-gc/pr20882c.s | 8 |
8 files changed, 108 insertions, 28 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 532ba0c..31b3982 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2017-05-17 H.J. Lu <hongjiu.lu@intel.com> + + PR ld/20882 + * elflink.c (elf_gc_mark_debug_section): New function. + (_bfd_elf_gc_mark_extra_sections): Mark any debug sections + referenced by kept debug sections. + 2017-05-16 Alan Modra <amodra@gmail.com> * elf-m10300.c: Rename occurrences of non_ir_ref. diff --git a/bfd/elflink.c b/bfd/elflink.c index 60e0a32..bc10428 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -12669,6 +12669,24 @@ _bfd_elf_gc_mark_hook (asection *sec, return NULL; } +/* Return the global debug definition section. */ + +static asection * +elf_gc_mark_debug_section (asection *sec ATTRIBUTE_UNUSED, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + Elf_Internal_Rela *rel ATTRIBUTE_UNUSED, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym ATTRIBUTE_UNUSED) +{ + if (h != NULL + && (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + && (h->root.u.def.section->flags & SEC_DEBUGGING) != 0) + return h->root.u.def.section; + + return NULL; +} + /* For undefined __start_<name> and __stop_<name> symbols, return the first input section matching <name>. Return NULL otherwise. */ @@ -12930,6 +12948,7 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info, asection *isec; bfd_boolean some_kept; bfd_boolean debug_frag_seen; + bfd_boolean has_kept_debug_info; if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) continue; @@ -12937,7 +12956,7 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info, /* Ensure all linker created sections are kept, see if any other section is already marked, and note if we have any fragmented debug sections. */ - debug_frag_seen = some_kept = FALSE; + debug_frag_seen = some_kept = has_kept_debug_info = FALSE; for (isec = ibfd->sections; isec != NULL; isec = isec->next) { if ((isec->flags & SEC_LINKER_CREATED) != 0) @@ -12967,45 +12986,52 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info, || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0) && elf_next_in_group (isec) == NULL) isec->gc_mark = 1; + if (isec->gc_mark && (isec->flags & SEC_DEBUGGING) != 0) + has_kept_debug_info = TRUE; } - if (! debug_frag_seen) - continue; - /* Look for CODE sections which are going to be discarded, and find and discard any fragmented debug sections which are associated with that code section. */ - for (isec = ibfd->sections; isec != NULL; isec = isec->next) - if ((isec->flags & SEC_CODE) != 0 - && isec->gc_mark == 0) - { - unsigned int ilen; - asection *dsec; + if (debug_frag_seen) + for (isec = ibfd->sections; isec != NULL; isec = isec->next) + if ((isec->flags & SEC_CODE) != 0 + && isec->gc_mark == 0) + { + unsigned int ilen; + asection *dsec; - ilen = strlen (isec->name); + ilen = strlen (isec->name); - /* Association is determined by the name of the debug section - containing the name of the code section as a suffix. For - example .debug_line.text.foo is a debug section associated - with .text.foo. */ - for (dsec = ibfd->sections; dsec != NULL; dsec = dsec->next) - { - unsigned int dlen; + /* Association is determined by the name of the debug + section containing the name of the code section as + a suffix. For example .debug_line.text.foo is a + debug section associated with .text.foo. */ + for (dsec = ibfd->sections; dsec != NULL; dsec = dsec->next) + { + unsigned int dlen; - if (dsec->gc_mark == 0 - || (dsec->flags & SEC_DEBUGGING) == 0) - continue; + if (dsec->gc_mark == 0 + || (dsec->flags & SEC_DEBUGGING) == 0) + continue; - dlen = strlen (dsec->name); + dlen = strlen (dsec->name); - if (dlen > ilen - && strncmp (dsec->name + (dlen - ilen), - isec->name, ilen) == 0) - { + if (dlen > ilen + && strncmp (dsec->name + (dlen - ilen), + isec->name, ilen) == 0) dsec->gc_mark = 0; - } - } + } } + + /* Mark debug sections referenced by kept debug sections. */ + if (has_kept_debug_info) + for (isec = ibfd->sections; isec != NULL; isec = isec->next) + if (isec->gc_mark + && (isec->flags & SEC_DEBUGGING) != 0) + if (!_bfd_elf_gc_mark (info, isec, + elf_gc_mark_debug_section)) + return FALSE; } return TRUE; } diff --git a/ld/ChangeLog b/ld/ChangeLog index 2034a1a..b71bc16 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,12 @@ +2017-05-17 H.J. Lu <hongjiu.lu@intel.com> + + PR ld/20882 + * testsuite/ld-gc/gc.exp: Run pr20882. + * testsuite/ld-gc/pr20882.d: New file. + * testsuite/ld-gc/pr20882a.s: Likewise. + * testsuite/ld-gc/pr20882b.s: Likewise. + * testsuite/ld-gc/pr20882c.s: Likewise. + 2017-05-16 H.J. Lu <hongjiu.lu@intel.com> PR ld/21481 diff --git a/ld/testsuite/ld-gc/gc.exp b/ld/testsuite/ld-gc/gc.exp index ba4f70b..ba5c46b 100644 --- a/ld/testsuite/ld-gc/gc.exp +++ b/ld/testsuite/ld-gc/gc.exp @@ -104,6 +104,7 @@ run_dump_test "start" run_dump_test "pr19167" if { [is_elf_format] } then { run_dump_test "all-debug-sections" + run_dump_test "pr20882" } if { [is_elf_format] && [check_shared_lib_support] } then { diff --git a/ld/testsuite/ld-gc/pr20882.d b/ld/testsuite/ld-gc/pr20882.d new file mode 100644 index 0000000..55fa141 --- /dev/null +++ b/ld/testsuite/ld-gc/pr20882.d @@ -0,0 +1,10 @@ +#name: --gc-sections with relocations in debug section +#source: pr20882a.s +#source: pr20882b.s +#source: pr20882c.s +#as: -gdwarf-sections +#ld: --gc-sections -e main +#readelf: -x .debug_info + +#... + +0x0+ [0-9a-f ]+ 28 +.+\( diff --git a/ld/testsuite/ld-gc/pr20882a.s b/ld/testsuite/ld-gc/pr20882a.s new file mode 100644 index 0000000..3348ba9 --- /dev/null +++ b/ld/testsuite/ld-gc/pr20882a.s @@ -0,0 +1,11 @@ + .text + .globl main + .type main, %function +main: + .byte 0 + + .section .debug_info,"",%progbits + .dc.a t.c.4903c230+2 + + .section .debug_line,"",%progbits + .byte 0 diff --git a/ld/testsuite/ld-gc/pr20882b.s b/ld/testsuite/ld-gc/pr20882b.s new file mode 100644 index 0000000..fed521c --- /dev/null +++ b/ld/testsuite/ld-gc/pr20882b.s @@ -0,0 +1,8 @@ + .section .debug_info,"",%progbits + .hidden t.c.4903c230 + .globl t.c.4903c230 +t.c.4903c230: + .byte 0x28 + + .section .debug_line,"",%progbits + .byte 0 diff --git a/ld/testsuite/ld-gc/pr20882c.s b/ld/testsuite/ld-gc/pr20882c.s new file mode 100644 index 0000000..a77edad --- /dev/null +++ b/ld/testsuite/ld-gc/pr20882c.s @@ -0,0 +1,8 @@ + .section .debug_info,"",%progbits + .hidden t.c.4903c231 + .globl t.c.4903c231 +t.c.4903c231: + .byte 0x29 + + .section .debug_line,"",%progbits + .byte 0 |