From 052940eba6fcd2b9f359f03ee205e9cd4dfb1575 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 20 Sep 2024 11:32:26 +0800 Subject: [PATCH] ld: Ignore .note.gnu.build-id when placing orphaned notes The commits: e8e10743f7b Add --rosegment option to BFD linker to stop the '-z separate-code' from generating two read-only segments. bf6d7087de0 ld: Move the .note.build-id section to near the start of the memory map place .note.gnu.build-id before text sections when --rosegment is used. Ignore .note.gnu.build-id when placing orphaned notes if --rosegment and -z separate-code are used together to avoid putting any note sections between .note.gnu.build-id and text sections in the same PT_LOAD segment. PR ld/32191 * ldlang.c (lang_insert_orphan): Ignore .note.gnu.build-id when placing orphaned notes. * testsuite/ld-elf/pr23658-1a.d: Pass --no-rosegment to ld. * testsuite/ld-elf/pr23658-1c.d: Likewise. * testsuite/ld-elf/pr23658-1e.d: New file. * testsuite/ld-elf/pr23658-1f.d: Likewise. * testsuite/ld-i386/i386.exp: Run PR ld/32191 test. * testsuite/ld-i386/pr32191.d: New file. * testsuite/ld-x86-64/lam-u48.rd: Updated. * testsuite/ld-x86-64/lam-u57.rd: Likewise. * testsuite/ld-x86-64/pr32191-x32.d: New file. * testsuite/ld-x86-64/pr32191.d: Likewise. * testsuite/ld-x86-64/pr32191.s: Likewise. * testsuite/ld-x86-64/x86-64.exp: Run PR ld/32191 tests. Signed-off-by: H.J. Lu --- ld/ldlang.c | 14 +++++++++++++- ld/testsuite/ld-elf/pr23658-1a.d | 2 +- ld/testsuite/ld-elf/pr23658-1c.d | 2 +- ld/testsuite/ld-elf/pr23658-1e.d | 23 +++++++++++++++++++++++ ld/testsuite/ld-elf/pr23658-1f.d | 17 +++++++++++++++++ ld/testsuite/ld-i386/i386.exp | 1 + ld/testsuite/ld-i386/pr32191.d | 9 +++++++++ ld/testsuite/ld-x86-64/lam-u48.rd | 1 + ld/testsuite/ld-x86-64/lam-u57.rd | 1 + ld/testsuite/ld-x86-64/pr32191-x32.d | 9 +++++++++ ld/testsuite/ld-x86-64/pr32191.d | 9 +++++++++ ld/testsuite/ld-x86-64/pr32191.s | 5 +++++ ld/testsuite/ld-x86-64/x86-64.exp | 2 ++ 13 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 ld/testsuite/ld-elf/pr23658-1e.d create mode 100644 ld/testsuite/ld-elf/pr23658-1f.d create mode 100644 ld/testsuite/ld-i386/pr32191.d create mode 100644 ld/testsuite/ld-x86-64/pr32191-x32.d create mode 100644 ld/testsuite/ld-x86-64/pr32191.d create mode 100644 ld/testsuite/ld-x86-64/pr32191.s diff --git a/ld/ldlang.c b/ld/ldlang.c index 9e8cc224f4d..95d64fd05e2 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -2047,13 +2047,25 @@ lang_insert_orphan (asection *s, place orphan note section after non-note sections. */ first_orphan_note = NULL; + + /* NB: When --rosegment is used, the .note.gnu.build-id + section is placed before text sections. Ignore the + .note.gnu.build-id section if -z separate-code and + --rosegment are used together to avoid putting any + note sections between the .note.gnu.build-id section + and text sections in the same PT_LOAD segment. */ + bool ignore_build_id = (link_info.separate_code + && link_info.one_rosegment); + for (sec = link_info.output_bfd->sections; (sec != NULL && !bfd_is_abs_section (sec)); sec = sec->next) if (sec != snew && elf_section_type (sec) == SHT_NOTE - && (sec->flags & SEC_LOAD) != 0) + && (sec->flags & SEC_LOAD) != 0 + && (!ignore_build_id + || strcmp (sec->name, ".note.gnu.build-id") != 0)) { if (!first_orphan_note) first_orphan_note = sec; diff --git a/ld/testsuite/ld-elf/pr23658-1a.d b/ld/testsuite/ld-elf/pr23658-1a.d index 10c6ef3973b..388f7a42fa7 100644 --- a/ld/testsuite/ld-elf/pr23658-1a.d +++ b/ld/testsuite/ld-elf/pr23658-1a.d @@ -3,7 +3,7 @@ #source: pr23658-1c.s #source: pr23658-1d.s #source: start.s -#ld: --build-id +#ld: --build-id --no-rosegment #readelf: -l --wide # Since generic linker targets don't place SHT_NOTE sections as orphan, # SHT_NOTE sections aren't grouped nor sorted. diff --git a/ld/testsuite/ld-elf/pr23658-1c.d b/ld/testsuite/ld-elf/pr23658-1c.d index 87acecaabe1..6ab72dc60b3 100644 --- a/ld/testsuite/ld-elf/pr23658-1c.d +++ b/ld/testsuite/ld-elf/pr23658-1c.d @@ -3,7 +3,7 @@ #source: pr23658-1c.s #source: pr23658-1d.s #source: start.s -#ld: --build-id -shared +#ld: --build-id --no-rosegment -shared #readelf: -l --wide #target: *-*-linux* *-*-gnu* arm*-*-uclinuxfdpiceabi #xfail: ![check_shared_lib_support] diff --git a/ld/testsuite/ld-elf/pr23658-1e.d b/ld/testsuite/ld-elf/pr23658-1e.d new file mode 100644 index 00000000000..a281e48d730 --- /dev/null +++ b/ld/testsuite/ld-elf/pr23658-1e.d @@ -0,0 +1,23 @@ +#source: pr23658-1a.s +#source: pr23658-1b.s +#source: pr23658-1c.s +#source: pr23658-1d.s +#source: start.s +#ld: --build-id -z separate-code --rosegment +#readelf: -l --wide +# Since generic linker targets don't place SHT_NOTE sections as orphan, +# SHT_NOTE sections aren't grouped nor sorted. .note.gnu.build-id is +# placed before text sections and there should no other note sections +# between .note.gnu.build-id and text sections. +#xfail: [uses_genelf] +#xfail: m68hc12-* +# The following targets don't support --build-id. +#xfail: cr16-* crx-* visium-* +# The following targets place .note.gnu.build-id in unusual places. +#xfail: pru-* + +#... + +[0-9]+ +\.note.gnu.build-id + + +[0-9]+ +\.note\.4 \.note\.1 + + +[0-9]+ +\.note\.2 \.note\.3 + +#pass diff --git a/ld/testsuite/ld-elf/pr23658-1f.d b/ld/testsuite/ld-elf/pr23658-1f.d new file mode 100644 index 00000000000..18231115b50 --- /dev/null +++ b/ld/testsuite/ld-elf/pr23658-1f.d @@ -0,0 +1,17 @@ +#source: pr23658-1a.s +#source: pr23658-1b.s +#source: pr23658-1c.s +#source: pr23658-1d.s +#source: start.s +#ld: --build-id -z separate-code --rosegment -shared +# .note.gnu.build-id is placed before text sections and there should +# no other note sections between .note.gnu.build-id and text sections. +#readelf: -l --wide +#target: *-*-linux* *-*-gnu* arm*-*-uclinuxfdpiceabi +#xfail: ![check_shared_lib_support] + +#... + +[0-9]+ +\.note.gnu.build-id + + +[0-9]+ +\.note\.4 \.note\.1 + + +[0-9]+ +\.note\.2 \.note\.3 + +#pass diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp index a66d67a3244..90293226954 100644 --- a/ld/testsuite/ld-i386/i386.exp +++ b/ld/testsuite/ld-i386/i386.exp @@ -514,6 +514,7 @@ run_dump_test "pr28870" run_dump_test "pr28894" run_dump_test "pr30787" run_dump_test "pr31047" +run_dump_test "pr32191" if { !([istarget "i?86-*-linux*"] || [istarget "i?86-*-gnu*"] diff --git a/ld/testsuite/ld-i386/pr32191.d b/ld/testsuite/ld-i386/pr32191.d new file mode 100644 index 00000000000..8d7838a1311 --- /dev/null +++ b/ld/testsuite/ld-i386/pr32191.d @@ -0,0 +1,9 @@ +#source: ../ld-x86-64/pr32191.s +#as: --32 -mx86-used-note=yes +#ld: -shared -m elf_i386 -z separate-code --build-id --rosegment +#readelf: -lW + +#... + +[0-9]+ +\.note\.gnu\.build-id \.text + +[0-9]+ +\..* \.note\.gnu\.property .* +#pass diff --git a/ld/testsuite/ld-x86-64/lam-u48.rd b/ld/testsuite/ld-x86-64/lam-u48.rd index ad312627059..8fac904c064 100644 --- a/ld/testsuite/ld-x86-64/lam-u48.rd +++ b/ld/testsuite/ld-x86-64/lam-u48.rd @@ -1,3 +1,4 @@ +#... Displaying notes found in: .note.gnu.property [ ]+Owner[ ]+Data size[ ]+Description GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 diff --git a/ld/testsuite/ld-x86-64/lam-u57.rd b/ld/testsuite/ld-x86-64/lam-u57.rd index 8b77e6311c0..dd8d1dafbeb 100644 --- a/ld/testsuite/ld-x86-64/lam-u57.rd +++ b/ld/testsuite/ld-x86-64/lam-u57.rd @@ -1,3 +1,4 @@ +#... Displaying notes found in: .note.gnu.property [ ]+Owner[ ]+Data size[ ]+Description GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 diff --git a/ld/testsuite/ld-x86-64/pr32191-x32.d b/ld/testsuite/ld-x86-64/pr32191-x32.d new file mode 100644 index 00000000000..19e06a26c11 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr32191-x32.d @@ -0,0 +1,9 @@ +#source: pr32191.s +#as: --x32 -mx86-used-note=yes +#ld: -shared -m elf32_x86_64 -z separate-code --build-id --rosegment +#readelf: -lW + +#... + +[0-9]+ +\.note\.gnu\.build-id \.text + +[0-9]+ +\..* \.note\.gnu\.property .* +#pass diff --git a/ld/testsuite/ld-x86-64/pr32191.d b/ld/testsuite/ld-x86-64/pr32191.d new file mode 100644 index 00000000000..9038ccd9b35 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr32191.d @@ -0,0 +1,9 @@ +#source: pr32191.s +#as: --64 -mx86-used-note=yes +#ld: -shared -m elf_x86_64 -z separate-code --build-id --rosegment +#readelf: -lW + +#... + +[0-9]+ +\.note\.gnu\.build-id \.text + +[0-9]+ +\..* \.note\.gnu\.property .* +#pass diff --git a/ld/testsuite/ld-x86-64/pr32191.s b/ld/testsuite/ld-x86-64/pr32191.s new file mode 100644 index 00000000000..953f0de670f --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr32191.s @@ -0,0 +1,5 @@ + .text + .global foo +foo: + .nops 4 + .section .note.GNU-stack,"",@progbits diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 1a6754dc31f..bd7574d6965 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -541,6 +541,8 @@ run_dump_test "tlsie5" run_dump_test "tlsdesc3" run_dump_test "tlsdesc4" run_dump_test "tlsdesc5" +run_dump_test "pr32191" +run_dump_test "pr32191-x32" if { ![skip_sframe_tests] } { run_dump_test "sframe-simple-1"