]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Account for LSB on c64 e_entry in the same way as Thumb
authorMatthew Malcomson <matthew.malcomson@arm.com>
Mon, 7 Mar 2022 18:10:49 +0000 (18:10 +0000)
committerMatthew Malcomson <matthew.malcomson@arm.com>
Mon, 7 Mar 2022 18:10:49 +0000 (18:10 +0000)
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.

ld/emultempl/aarch64elf.em
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/morello-entry-point.d [new file with mode: 0644]

index 8a123106e3df3a0236cf818051430b5ef27eca8e..11512a127db039066f6c11e6132f7089d0528994 100644 (file)
@@ -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.
index 721d16e09bc1392fbc5e7920a080962bb4b374a2..9352db42e9913021d17a8e5dd8d7d8cf2125fe29 100644 (file)
@@ -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 (file)
index 0000000..29fb431
--- /dev/null
@@ -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