From d2ef37ebd9f771d06edf1fdea37970f60b242b2d Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 7 Dec 2018 08:30:30 -0800 Subject: [PATCH] elf: Report property change when merging properties With merging properties, report property change in linker map file, like Merging program properties Removed property 0xc0010000 to merge /usr/lib/gcc/x86_64-redhat-linux/8/../../../../lib64/crt1.o (0x0) and /usr/lib/gcc/x86_64-redhat-linux/8/../../../../lib64/crti.o (0x0) Removed property 0xc0000002 to merge /usr/lib/gcc/x86_64-redhat-linux/8/../../../../lib64/crt1.o (0x3) and x.o (not found) Removed property 0xc0000000 to merge /usr/lib/gcc/x86_64-redhat-linux/8/../../../../lib64/crt1.o (not found) and /usr/lib64/libc_nonshared.a(elf-init.oS) (0x0) Removed property 0xc0000001 to merge /usr/lib/gcc/x86_64-redhat-linux/8/../../../../lib64/crt1.o (not found) and /usr/lib64/libc_nonshared.a(elf-init.oS) (0x0) bfd/ * elf-properties.c (elf_find_and_remove_property): Add a bfd_boolean argument to indicate if the property should be removed. (elf_merge_gnu_property_list): Updated. Report property change in linker map file. (elf_get_gnu_property_section_size): Skip property_remove properties. (elf_write_gnu_properties): Likewise. (_bfd_elf_link_setup_gnu_properties): Report property merge in linker map file. Pass abfd to elf_merge_gnu_property_list. include/ * bfdlink.h (bfd_link_info): Add has_map_file. ld/ * NEWS: Updated for property change report. * ld.texi: Document property change report. * ldmain.c (main): Set link_info.has_map_file to TRUE when linker map file is used. * testsuite/ld-scripts/rgn-over1.d: Updated. * testsuite/ld-scripts/rgn-over2.d: Likewise. * testsuite/ld-scripts/rgn-over3.d: Likewise. * testsuite/ld-scripts/rgn-over4.d: Likewise. * testsuite/ld-scripts/rgn-over5.d: Likewise. * testsuite/ld-scripts/rgn-over6.d: Likewise. * testsuite/ld-scripts/rgn-over7.d: Likewise. * testsuite/ld-x86-64/property-x86-ibt1a-x32.d: Check linker map file. * testsuite/ld-x86-64/property-x86-ibt1a.d: Likewise. * testsuite/ld-x86-64/property-x86-ibt1a.map: New file. --- bfd/ChangeLog | 13 ++ bfd/elf-properties.c | 176 ++++++++++++++---- include/ChangeLog | 4 + include/bfdlink.h | 3 + ld/ChangeLog | 18 ++ ld/NEWS | 2 + ld/ld.texi | 22 +++ ld/ldmain.c | 1 + ld/testsuite/ld-scripts/rgn-over1.d | 1 + ld/testsuite/ld-scripts/rgn-over2.d | 1 + ld/testsuite/ld-scripts/rgn-over3.d | 1 + ld/testsuite/ld-scripts/rgn-over4.d | 1 + ld/testsuite/ld-scripts/rgn-over5.d | 1 + ld/testsuite/ld-scripts/rgn-over6.d | 1 + ld/testsuite/ld-scripts/rgn-over7.d | 1 + .../ld-x86-64/property-x86-ibt1a-x32.d | 3 +- ld/testsuite/ld-x86-64/property-x86-ibt1a.d | 3 +- ld/testsuite/ld-x86-64/property-x86-ibt1a.map | 3 + 18 files changed, 219 insertions(+), 36 deletions(-) create mode 100644 ld/testsuite/ld-x86-64/property-x86-ibt1a.map diff --git a/bfd/ChangeLog b/bfd/ChangeLog index b7d671765f3..1e82b939e11 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,16 @@ +2018-12-07 H.J. Lu + + * elf-properties.c (elf_find_and_remove_property): Add a + bfd_boolean argument to indicate if the property should be + removed. + (elf_merge_gnu_property_list): Updated. Report + property change in linker map file. + (elf_get_gnu_property_section_size): Skip property_remove + properties. + (elf_write_gnu_properties): Likewise. + (_bfd_elf_link_setup_gnu_properties): Report property merge + in linker map file. Pass abfd to elf_merge_gnu_property_list. + 2018-12-07 Alan Modra PR 23952 diff --git a/bfd/elf-properties.c b/bfd/elf-properties.c index cd44ed6194b..ec36210006a 100644 --- a/bfd/elf-properties.c +++ b/bfd/elf-properties.c @@ -241,7 +241,7 @@ elf_merge_gnu_properties (struct bfd_link_info *info, bfd *abfd, static elf_property * elf_find_and_remove_property (elf_property_list **listp, - unsigned int type) + unsigned int type, bfd_boolean remove) { elf_property_list *list; @@ -250,7 +250,8 @@ elf_find_and_remove_property (elf_property_list **listp, if (type == list->property.pr_type) { /* Remove this property. */ - *listp = list->next; + if (remove) + *listp = list->next; return &list->property; } else if (type < list->property.pr_type) @@ -261,47 +262,144 @@ elf_find_and_remove_property (elf_property_list **listp, return NULL; } -/* Merge GNU property list *LISTP with ABFD. */ +/* Merge GNU property list *LISTP in ABFD with FIRST_PBFD. */ static void -elf_merge_gnu_property_list (struct bfd_link_info *info, bfd *abfd, - elf_property_list **listp) +elf_merge_gnu_property_list (struct bfd_link_info *info, bfd *first_pbfd, + bfd *abfd, elf_property_list **listp) { elf_property_list *p, **lastp; elf_property *pr; + bfd_boolean number_p; + bfd_vma number = 0; - /* Merge each GNU property in ABFD with the one on *LISTP. */ - lastp = &elf_properties (abfd); + /* Merge each GNU property in FIRST_PBFD with the one on *LISTP. */ + lastp = &elf_properties (first_pbfd); for (p = *lastp; p; p = p->next) + if (p->property.pr_kind != property_remove) + { + if (p->property.pr_kind == property_number) + { + number_p = TRUE; + number = p->property.u.number; + } + else + number_p = FALSE; + pr = elf_find_and_remove_property (listp, p->property.pr_type, + TRUE); + /* Pass NULL to elf_merge_gnu_properties for the property which + isn't on *LISTP. */ + elf_merge_gnu_properties (info, first_pbfd, &p->property, pr); + if (p->property.pr_kind == property_remove) + { + if (info->has_map_file) + { + if (number_p) + { + if (pr != NULL) + info->callbacks->minfo + (_("Removed property %W to merge %pB (0x%v) " + "and %pB (0x%v)\n"), + (bfd_vma) p->property.pr_type, first_pbfd, + number, abfd, pr->u.number); + else + info->callbacks->minfo + (_("Removed property %W to merge %pB (0x%v) " + "and %pB (not found)\n"), + (bfd_vma) p->property.pr_type, first_pbfd, + number, abfd); + } + else + { + if (pr != NULL) + info->callbacks->minfo + (_("Removed property %W to merge %pB and %pB\n"), + (bfd_vma) p->property.pr_type, first_pbfd, abfd); + else + info->callbacks->minfo + (_("Removed property %W to merge %pB and %pB " + "(not found)\n"), + (bfd_vma) p->property.pr_type, first_pbfd, abfd); + } + } + else + { + /* Remove this property. */ + *lastp = p->next; + continue; + } + } + else if (number_p) + { + if (pr != NULL) + { + if (p->property.u.number != number + || p->property.u.number != pr->u.number) + info->callbacks->minfo + (_("Updated property %W (0x%v) to merge %pB (0x%v) " + "and %pB (0x%v)\n"), + (bfd_vma) p->property.pr_type, p->property.u.number, + first_pbfd, number, abfd, pr->u.number); + } + else + { + if (p->property.u.number != number) + info->callbacks->minfo + (_("Updated property %W (%v) to merge %pB (0x%v) " + "and %pB (not found)\n"), + (bfd_vma) p->property.pr_type, p->property.u.number, + first_pbfd, number, abfd); + } + } + lastp = &p->next; + } + + /* Merge the remaining properties on *LISTP with FIRST_PBFD. */ + for (p = *listp; p != NULL; p = p->next) { - pr = elf_find_and_remove_property (listp, p->property.pr_type); - /* Pass NULL to elf_merge_gnu_properties for the property which - isn't on *LISTP. */ - elf_merge_gnu_properties (info, abfd, &p->property, pr); - if (p->property.pr_kind == property_remove) + if (p->property.pr_kind == property_number) { - /* Remove this property. */ - *lastp = p->next; - continue; + number_p = TRUE; + number = p->property.u.number; } - lastp = &p->next; - } - - /* Merge the remaining properties on *LISTP with ABFD. */ - for (p = *listp; p != NULL; p = p->next) - if (elf_merge_gnu_properties (info, abfd, NULL, &p->property)) - { - if (p->property.pr_type == GNU_PROPERTY_NO_COPY_ON_PROTECTED) - elf_has_no_copy_on_protected (abfd) = TRUE; + else + number_p = FALSE; - pr = _bfd_elf_get_property (abfd, p->property.pr_type, - p->property.pr_datasz); - /* It must be a new property. */ - if (pr->pr_kind != property_unknown) - abort (); - /* Add a new property. */ - *pr = p->property; - } + if (elf_merge_gnu_properties (info, first_pbfd, NULL, &p->property)) + { + if (p->property.pr_type == GNU_PROPERTY_NO_COPY_ON_PROTECTED) + elf_has_no_copy_on_protected (first_pbfd) = TRUE; + + pr = _bfd_elf_get_property (first_pbfd, p->property.pr_type, + p->property.pr_datasz); + /* It must be a new property. */ + if (pr->pr_kind != property_unknown) + abort (); + /* Add a new property. */ + *pr = p->property; + } + else + { + pr = elf_find_and_remove_property (&elf_properties (first_pbfd), + p->property.pr_type, + FALSE); + if (pr == NULL) + { + if (number_p) + info->callbacks->minfo + (_("Removed property %W to merge %pB (not found) and " + "%pB (0x%v)\n"), + (bfd_vma) p->property.pr_type, first_pbfd, abfd, + number); + else + info->callbacks->minfo + (_("Removed property %W to merge %pB and %pB\n"), + (bfd_vma) p->property.pr_type, first_pbfd, abfd); + } + else if (pr->pr_kind != property_remove) + abort (); + } + } } /* Get GNU property section size. */ @@ -319,8 +417,11 @@ elf_get_gnu_property_section_size (elf_property_list *list, size = descsz; for (; list != NULL; list = list->next) { - /* There are 4 byte type + 4 byte datasz for each property. */ unsigned int datasz; + /* Check if this property should be skipped. */ + if (list->property.pr_kind == property_remove) + continue; + /* There are 4 byte type + 4 byte datasz for each property. */ if (list->property.pr_type == GNU_PROPERTY_STACK_SIZE) datasz = align_size; else @@ -355,6 +456,9 @@ elf_write_gnu_properties (bfd *abfd, bfd_byte *contents, size = descsz; for (; list != NULL; list = list->next) { + /* Check if this property should be skipped. */ + if (list->property.pr_kind == property_remove) + continue; /* There are 4 byte type + 4 byte datasz for each property. */ if (list->property.pr_type == GNU_PROPERTY_STACK_SIZE) datasz = align_size; @@ -445,6 +549,10 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info) return NULL; /* Merge .note.gnu.property sections. */ + info->callbacks->minfo (_("\n")); + info->callbacks->minfo (_("Merging program properties\n")); + info->callbacks->minfo (_("\n")); + for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next) if (abfd != first_pbfd && (abfd->flags & (DYNAMIC | BFD_PLUGIN)) == 0) @@ -471,7 +579,7 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info) when all properties are from ELF objects with different machine code or class. */ if (first_pbfd != NULL) - elf_merge_gnu_property_list (info, first_pbfd, listp); + elf_merge_gnu_property_list (info, first_pbfd, abfd, listp); if (list != NULL) { diff --git a/include/ChangeLog b/include/ChangeLog index 69f73576571..7cae69810ac 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2018-12-07 H.J. Lu + + * bfdlink.h (bfd_link_info): Add has_map_file. + 2018-12-07 Nick Clifton * demangle.h (DMGL_NO_RECURSE_LIMIT): Define. diff --git a/include/bfdlink.h b/include/bfdlink.h index 630f7342a95..d66188e6ee5 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -506,6 +506,9 @@ struct bfd_link_info /* TRUE if common symbols should be treated as undefined. */ unsigned int inhibit_common_definition : 1; + /* TRUE if "-Map map" is passed to linker. */ + unsigned int has_map_file : 1; + /* The 1-byte NOP for x86 call instruction. */ char call_nop_byte; diff --git a/ld/ChangeLog b/ld/ChangeLog index 51382253d6c..c8c48c5c1a3 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,21 @@ +2018-12-07 H.J. Lu + + * NEWS: Updated for property change report. + * ld.texi: Document property change report. + * ldmain.c (main): Set link_info.has_map_file to TRUE when + linker map file is used. + * testsuite/ld-scripts/rgn-over1.d: Updated. + * testsuite/ld-scripts/rgn-over2.d: Likewise. + * testsuite/ld-scripts/rgn-over3.d: Likewise. + * testsuite/ld-scripts/rgn-over4.d: Likewise. + * testsuite/ld-scripts/rgn-over5.d: Likewise. + * testsuite/ld-scripts/rgn-over6.d: Likewise. + * testsuite/ld-scripts/rgn-over7.d: Likewise. + * testsuite/ld-x86-64/property-x86-ibt1a-x32.d: Check linker map + file. + * testsuite/ld-x86-64/property-x86-ibt1a.d: Likewise. + * testsuite/ld-x86-64/property-x86-ibt1a.map: New file. + 2018-12-04 H.J. Lu PR ld/23372 diff --git a/ld/NEWS b/ld/NEWS index e2e87defee3..502966635e0 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -1,5 +1,7 @@ -*- text -*- +* Report property change in linker map file when merging GNU properties. + * Add support for the C-SKY processor series. Changes in 2.31: diff --git a/ld/ld.texi b/ld/ld.texi index 985c591d6ad..83a322c992d 100644 --- a/ld/ld.texi +++ b/ld/ld.texi @@ -759,6 +759,28 @@ option is used: See @ref{Expressions} for more information about expressions in linker scripts. + +@item How GNU properties are merged. + +When linker merges input .note.gnu.property sections into one output +.note.gnu.property section, some properties are removed or updated, +which are reported in the link map as + +@smallexample +Removed property 0xc0000002 to merge foo.o (0x1) and bar.o (not found) +@end smallexample + +It indicates that property 0xc0000002 is removed from output when +merging properties in @file{foo.o}, whose property 0xc0000002 value +is 0x1, and @file{bar.o}, which doesn't have property 0xc0000002. + +@smallexample +Updated property 0xc0000002 (0x1) to merge foo.o (0x1) and bar.o (0x1) +@end smallexample + +It indicates that property 0xc0010001 value is updated to 0x1 in output +when merging properties in @file{foo.o}, whose 0xc0010001 property value +is 0x1, and @file{bar.o}, whose 0xc0010001 property value is 0x1. @end itemize @kindex -n diff --git a/ld/ldmain.c b/ld/ldmain.c index 24a40aa1ffc..b7f51abc75b 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -434,6 +434,7 @@ main (int argc, char **argv) config.map_filename); } } + link_info.has_map_file = TRUE; } lang_process (); diff --git a/ld/testsuite/ld-scripts/rgn-over1.d b/ld/testsuite/ld-scripts/rgn-over1.d index 54892be41d8..902380ee98f 100644 --- a/ld/testsuite/ld-scripts/rgn-over1.d +++ b/ld/testsuite/ld-scripts/rgn-over1.d @@ -3,6 +3,7 @@ # ld: -T rgn-over1.t -Map tmpdir/rgn-over1.map # error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section \`.text' will not fit in region `r1'\n[^ \n]*?ld[^:\n]*?: region `r1' overflowed by 16 bytes\Z +#... Discarded input sections #... Memory\s+Configuration diff --git a/ld/testsuite/ld-scripts/rgn-over2.d b/ld/testsuite/ld-scripts/rgn-over2.d index 1a5afea8d5f..1d7a8f93ac5 100644 --- a/ld/testsuite/ld-scripts/rgn-over2.d +++ b/ld/testsuite/ld-scripts/rgn-over2.d @@ -3,6 +3,7 @@ # ld: -T rgn-over2.t -Map tmpdir/rgn-over2.map # error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.data' will not fit in region `r1'\n[^ \n]*?ld[^:\n]*?: region `r1' overflowed by 4 bytes\Z +#... Discarded input sections #... Memory\s+Configuration diff --git a/ld/testsuite/ld-scripts/rgn-over3.d b/ld/testsuite/ld-scripts/rgn-over3.d index 76fa7c53b3b..58d1a279cf2 100644 --- a/ld/testsuite/ld-scripts/rgn-over3.d +++ b/ld/testsuite/ld-scripts/rgn-over3.d @@ -3,6 +3,7 @@ # ld: -T rgn-over3.t -Map tmpdir/rgn-over3.map # error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.text' will not fit in region `r1'\n[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.data' will not fit in region `r2'\n[^ \n]*?ld[^:\n]*?: region `r1' overflowed by 4 bytes\n[^ \n]*?ld[^:\n]*?: region `r2' overflowed by 4 bytes\Z +#... Discarded input sections #... Memory\s+Configuration diff --git a/ld/testsuite/ld-scripts/rgn-over4.d b/ld/testsuite/ld-scripts/rgn-over4.d index 1087aec58c4..8ae150dca5b 100644 --- a/ld/testsuite/ld-scripts/rgn-over4.d +++ b/ld/testsuite/ld-scripts/rgn-over4.d @@ -3,6 +3,7 @@ # ld: -T rgn-over4.t -Map tmpdir/rgn-over4.map # error: \A[^ \n]*?ld[^:\n]*?: [^:\n]*?section `\.text' will not fit in region `r1'\n[^ \n]*?ld[^:\n]*?: region `r1' overflowed by 16 bytes\Z +#... Discarded input sections #... Memory\s+Configuration diff --git a/ld/testsuite/ld-scripts/rgn-over5.d b/ld/testsuite/ld-scripts/rgn-over5.d index 734d9feed67..10a7658534b 100644 --- a/ld/testsuite/ld-scripts/rgn-over5.d +++ b/ld/testsuite/ld-scripts/rgn-over5.d @@ -3,6 +3,7 @@ # ld: -T rgn-over5.t -Map tmpdir/rgn-over5.map # error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.text' will not fit in region `v1'\n[^ \n]*?ld[^:\n]*?: region `v1' overflowed by 16 bytes\Z +#... Discarded input sections #... Memory\s+Configuration diff --git a/ld/testsuite/ld-scripts/rgn-over6.d b/ld/testsuite/ld-scripts/rgn-over6.d index 00b41d05630..66c5a16216b 100644 --- a/ld/testsuite/ld-scripts/rgn-over6.d +++ b/ld/testsuite/ld-scripts/rgn-over6.d @@ -3,6 +3,7 @@ # ld: -T rgn-over6.t -Map tmpdir/rgn-over6.map # error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.text' will not fit in region `r1'\n[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.text' will not fit in region `v1'\n[^ \n]*?ld[^:\n]*?: region `r1' overflowed by 16 bytes\n[^ \n]*?ld[^:\n]*?: region `v1' overflowed by 16 bytes\Z +#... Discarded input sections #... Memory\s+Configuration diff --git a/ld/testsuite/ld-scripts/rgn-over7.d b/ld/testsuite/ld-scripts/rgn-over7.d index 74abb5c1bcd..3fc70cf885c 100644 --- a/ld/testsuite/ld-scripts/rgn-over7.d +++ b/ld/testsuite/ld-scripts/rgn-over7.d @@ -3,6 +3,7 @@ # ld: -T rgn-over7.t -Map tmpdir/rgn-over7.map # error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.text' will not fit in region `r1'\n[^ \n]*?ld[^:\n]*?: section \.data LMA \[0+1008,0+1013\] overlaps section \.text LMA \[0+1000,0+100b\]\n[^ \n]*?ld[^:\n]*?: region `r1' overflowed by 4 bytes\Z +#... Discarded input sections #... Memory\s+Configuration diff --git a/ld/testsuite/ld-x86-64/property-x86-ibt1a-x32.d b/ld/testsuite/ld-x86-64/property-x86-ibt1a-x32.d index 7a95401ac3d..d05ab1dce50 100644 --- a/ld/testsuite/ld-x86-64/property-x86-ibt1a-x32.d +++ b/ld/testsuite/ld-x86-64/property-x86-ibt1a-x32.d @@ -1,8 +1,9 @@ #source: property-x86-empty.s #source: property-x86-ibt.s #as: --x32 -mx86-used-note=yes -#ld: -r -m elf32_x86_64 +#ld: -r -m elf32_x86_64 -Map tmpdir/property-x86-ibt1a-x32.map #readelf: -n +#map: property-x86-ibt1a.map Displaying notes found in: .note.gnu.property Owner Data size Description diff --git a/ld/testsuite/ld-x86-64/property-x86-ibt1a.d b/ld/testsuite/ld-x86-64/property-x86-ibt1a.d index e989a8a8177..f8d6a063b48 100644 --- a/ld/testsuite/ld-x86-64/property-x86-ibt1a.d +++ b/ld/testsuite/ld-x86-64/property-x86-ibt1a.d @@ -1,8 +1,9 @@ #source: property-x86-empty.s #source: property-x86-ibt.s #as: --64 -defsym __64_bit__=1 -mx86-used-note=yes -#ld: -r -melf_x86_64 +#ld: -r -melf_x86_64 -Map tmpdir/property-x86-ibt1a.map #readelf: -n +#map: property-x86-ibt1a.map Displaying notes found in: .note.gnu.property Owner Data size Description diff --git a/ld/testsuite/ld-x86-64/property-x86-ibt1a.map b/ld/testsuite/ld-x86-64/property-x86-ibt1a.map new file mode 100644 index 00000000000..976c835d67e --- /dev/null +++ b/ld/testsuite/ld-x86-64/property-x86-ibt1a.map @@ -0,0 +1,3 @@ +#... +Removed property 0xc0000002 to merge tmpdir/property-x86-empty.o \(0x0\) and tmpdir/property-x86-ibt.o \(0x1\) +#pass -- 2.30.2