From: Matthew Malcomson Date: Mon, 7 Mar 2022 18:10:49 +0000 (+0000) Subject: Account for LSB on c64 e_entry in the same way as Thumb X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=90e0ccd25e17e3f81b507e13ba6acc13c53ed23f;p=thirdparty%2Fbinutils-gdb.git Account for LSB on c64 e_entry in the same way as Thumb The handling is done by putting the value that we want in a buffer and using that as the entry_symbol.name which lang_end picks up. Another option would be to find the entry symbol *after* lang_end has finished (e.g. in elfNN_aarch64_init_file_header) and add the LSB to it if that symbol is a C64 symbol. This approach was mainly chosen in order to match more closely what Thumb has done. N.b. we set the LSB based on the LSB of the entry point symbol. If the entry point symbol is in c64 code but is not an STT_FUNC (e.g. it is an STT_NOTYPE) then the LSB will not be set. This matches Morello clang behaviour. --- diff --git a/ld/emultempl/aarch64elf.em b/ld/emultempl/aarch64elf.em index eb4bc1c2471..e5ba012d08b 100644 --- a/ld/emultempl/aarch64elf.em +++ b/ld/emultempl/aarch64elf.em @@ -330,6 +330,43 @@ gld${EMULATION_NAME}_finish (void) } finish_default (); + + struct bfd_link_hash_entry * h; + struct elf_link_hash_entry * eh; + + if (!entry_symbol.name) + return; + + h = bfd_link_hash_lookup (link_info.hash, entry_symbol.name, + FALSE, FALSE, TRUE); + eh = (struct elf_link_hash_entry *)h; + if (!h || !(eh->target_internal & ST_BRANCH_TO_C64)) + return; + if (h->type != bfd_link_hash_defined + && h->type != bfd_link_hash_defweak) + return; + if (h->u.def.section->output_section == NULL) + return; + + static char buffer[67]; + bfd_vma val; + + /* Special procesing is required for a C64 entry symbol. The + bottom bit of its address must be set. */ + val = (h->u.def.value + + bfd_section_vma (h->u.def.section->output_section) + + h->u.def.section->output_offset); + + val |= 1; + + /* Now convert this value into a string and store it in entry_symbol + where the lang_end() function will pick it up. */ + buffer[0] = '0'; + buffer[1] = 'x'; + + sprintf_vma (buffer + 2, val); + + entry_symbol.name = buffer; } /* This is a convenient point to tell BFD about target specific flags. diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp index d2b5ef490e7..7d81d646c27 100644 --- a/ld/testsuite/ld-aarch64/aarch64-elf.exp +++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp @@ -269,6 +269,7 @@ run_dump_test_lp64 "morello-sec-round-data-only" run_dump_test_lp64 "morello-sec-round-include-relro" run_dump_test_lp64 "morello-pcc-bounds-include-readonly" run_dump_test_lp64 "morello-sec-round-choose-linker-syms" +run_dump_test_lp64 "morello-entry-point" run_dump_test_lp64 "morello-tlsdesc" run_dump_test_lp64 "morello-tlsdesc-static" run_dump_test_lp64 "morello-tlsdesc-staticpie" diff --git a/ld/testsuite/ld-aarch64/morello-entry-point.d b/ld/testsuite/ld-aarch64/morello-entry-point.d new file mode 100644 index 00000000000..29fb431199b --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-entry-point.d @@ -0,0 +1,10 @@ +# Checking that the entry point address of a binary with a c64 function symbol +# as the entry address is odd (i.e. has the LSB set). +#source: emit-relocs-morello-2.s +#as: -march=morello+c64 +#ld: -static +#readelf: --file-header + +#... + Entry point address: 0x.*[13579] +#pass