diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index ed8d8719dc28fb11ac9ee2d2e78b0f88a425f2ca..9f8cb7d3a78336aa0922c2635d577e9c2157301b 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -11252,6 +11252,7 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd, if (htab->root.dynamic_sections_created) { + const char *name; ElfNN_External_Dyn *dyncon, *dynconend; if (sdyn == NULL || htab->root.sgot == NULL) @@ -11298,6 +11299,27 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd, dyn.d_un.d_ptr = s->output_section->vma + s->output_offset + htab->root.tlsdesc_got; break; + + /* Set the bottom bit of DT_INIT/FINI if the + corresponding function is C64. */ + case DT_INIT: + name = info->init_function; + goto get_sym; + case DT_FINI: + name = info->fini_function; +get_sym: + /* If it wasn't set by elf_bfd_final_link + then there is nothing to adjust. */ + if (dyn.d_un.d_val != 0) + { + struct elf_link_hash_entry * eh; + + eh = elf_link_hash_lookup (elf_hash_table (info), name, + FALSE, FALSE, TRUE); + if (eh != NULL) + dyn.d_un.d_val |= eh->target_internal; + } + break; } bfd_elfNN_swap_dyn_out (output_bfd, &dyn, dyncon); diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp index 9b745e3976f856432f29f12a1c974f0fa7411dfa..3e9cf4147f3012a12a0535bee3f6f7bc4c109a12 100644 --- a/ld/testsuite/ld-aarch64/aarch64-elf.exp +++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp @@ -281,6 +281,7 @@ if { [ld_assemble $as $srcdir/$subdir/morello-dynamic-relocs-lib.s tmpdir/morell run_dump_test_lp64 "morello-dynamic-relocs" } +run_dump_test_lp64 "morello-dt-init-fini" run_dump_test_lp64 "morello-capinit" run_dump_test_lp64 "morello-stubs" diff --git a/ld/testsuite/ld-aarch64/morello-dt-init-fini.d b/ld/testsuite/ld-aarch64/morello-dt-init-fini.d new file mode 100644 index 0000000000000000000000000000000000000000..d530a288b661a056d9d50077c7aa5d45658ebea6 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-dt-init-fini.d @@ -0,0 +1,23 @@ +# Checking that the DT_INIT and DT_FINI entries in the dynamic section include +# the LSB when referring to functions which include the LSB. +#as: -march=morello+c64 +#ld: -shared +#readelf: --symbols --dynamic --wide + +Dynamic section at offset .* + Tag Type Name/Value +#record: INIT_LOC +#... + 0x000000000000000c \(INIT\) 0x([0-9a-f]+) +#record: FINI_LOC +#... + 0x000000000000000d \(FINI\) 0x([0-9a-f]+) +#... +Symbol table '.symtab' contains 18 entries: + Num: Value Size Type Bind Vis Ndx Name +#check: INIT_ADDR string tolower $INIT_LOC +#check: FINI_ADDR string tolower $FINI_LOC +#... +.*: 0+INIT_ADDR 0 FUNC LOCAL DEFAULT .* _init +.*: 0+FINI_ADDR 0 FUNC LOCAL DEFAULT .* _fini +#pass diff --git a/ld/testsuite/ld-aarch64/morello-dt-init-fini.s b/ld/testsuite/ld-aarch64/morello-dt-init-fini.s new file mode 100644 index 0000000000000000000000000000000000000000..71a5b645b91f958cd3798b134e5970bee6bd7243 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-dt-init-fini.s @@ -0,0 +1,13 @@ + .section .init,"ax",%progbits + .global _init + .hidden _init + .type _init, %function +_init: + ret + + .section .fini,"ax",%progbits + .global _fini + .hidden _fini + .type _fini, %function +_fini: + ret