]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Error linking binaries with differing e_flags.
authorMatthew Malcomson <matthew.malcomson@arm.com>
Mon, 7 Feb 2022 16:54:55 +0000 (16:54 +0000)
committerMatthew Malcomson <matthew.malcomson@arm.com>
Wed, 9 Feb 2022 10:35:00 +0000 (10:35 +0000)
This commit is partly changing two existing (believed buggy) behaviours
in elfNN_aarch64_merge_private_bfd_data and partly accounting for a
capability-specific requirement.

The existing behaviours in elfNN_aarch64_merge_private_bfd_data were:
1) It returned `TRUE` by default.  This effectively ignored the ELF
   flags on the binaries, despite there being code looking at them.
2) We do not mark the output BFD as initialised until we see flags with
   non-default architecture and flags.  This can't tell the difference
   between linking default objects to non-default objects if the default
   objects are given first on the command line.

The capability-specific requirement is:
- This function originally returned early if the object file getting
  merged into the existing output object file is not dynamic and has no
  code sections.  The code reasoned that differing ELF flags did not
  matter in this case since there was no code that would be expecting
  it.
  For capabilities the binary compatibility is still important.
  Data sections now contain capabilities as pointers, got sections now
  have a different got element size.
  Hence we avoid this short-circuit if any of the flags we're checking
  are the CHERI_PURECAP flag.

bfd/elfnn-aarch64.c
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/morello-disallow-merged-binaries-code.s [new file with mode: 0644]
ld/testsuite/ld-aarch64/morello-disallow-merged-binaries-data.s [new file with mode: 0644]
ld/testsuite/ld-aarch64/morello-disallow-merged-binaries.d [new file with mode: 0644]

index 939fac197d5dab3dcee8b9d820957e68419ca0af..8b69c03c4a2f66a7f3d4a6dc88494c00ac72646b 100644 (file)
@@ -8686,7 +8686,7 @@ elfNN_aarch64_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
   bfd *obfd = info->output_bfd;
   flagword out_flags;
   flagword in_flags;
-  bfd_boolean flags_compatible = TRUE;
+  bfd_boolean flags_compatible = FALSE;
   asection *sec;
 
   /* Check if we have the same endianess.  */
@@ -8707,6 +8707,8 @@ elfNN_aarch64_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 
   if (!elf_flags_init (obfd))
     {
+      elf_flags_init (obfd) = TRUE;
+
       /* If the input is the default architecture and had the default
         flags then do not bother setting the flags for the output
         architecture, instead allow future merges to do this.  If no
@@ -8717,7 +8719,6 @@ elfNN_aarch64_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
          && elf_elfheader (ibfd)->e_flags == 0)
        return TRUE;
 
-      elf_flags_init (obfd) = TRUE;
       elf_elfheader (obfd)->e_flags = in_flags;
 
       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
@@ -8741,11 +8742,17 @@ elfNN_aarch64_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
      Also check to see if there are no code sections in the input.
      In this case there is no need to check for code specific flags.
      XXX - do we need to worry about floating-point format compatability
-     in data sections ?  */
+     in data sections ?
+
+     We definitely need to check for data sections if one set of flags is
+     targetting the PURECAP abi and another is not.  Pointers being
+     capabilities in data sections can not be glossed over.  */
   if (!(ibfd->flags & DYNAMIC))
     {
       bfd_boolean null_input_bfd = TRUE;
-      bfd_boolean only_data_sections = TRUE;
+      bfd_boolean only_data_sections
+       = !(in_flags & EF_AARCH64_CHERI_PURECAP
+           || out_flags & EF_AARCH64_CHERI_PURECAP);
 
       for (sec = ibfd->sections; sec != NULL; sec = sec->next)
        {
index c40eba959421ac6d5e97f11d95a5900fa8e5b2bf..9168a810fc57783dd122ce40b6385dddc6888042 100644 (file)
@@ -255,6 +255,7 @@ run_dump_test_lp64 "emit-morello-reloc-markers-3"
 run_dump_test_lp64 "morello-sizeless-local-syms"
 run_dump_test_lp64 "morello-sizeless-global-syms"
 run_dump_test_lp64 "morello-sizeless-got-syms"
+run_dump_test_lp64 "morello-disallow-merged-binaries"
 
 run_dump_test_lp64 "morello-capinit"
 run_dump_test_lp64 "morello-stubs"
diff --git a/ld/testsuite/ld-aarch64/morello-disallow-merged-binaries-code.s b/ld/testsuite/ld-aarch64/morello-disallow-merged-binaries-code.s
new file mode 100644 (file)
index 0000000..83a7291
--- /dev/null
@@ -0,0 +1,11 @@
+       .file   "very-basic-test.c"
+       .text
+       .align  2
+       .global _start
+       .type   _start, %function
+_start:
+       adrp    c0, :got:extobj
+       ldr     c0, [c0, #:got_lo12:extobj]
+       ldr     w0, [c0]
+       ret
+       .size   _start, .-_start
diff --git a/ld/testsuite/ld-aarch64/morello-disallow-merged-binaries-data.s b/ld/testsuite/ld-aarch64/morello-disallow-merged-binaries-data.s
new file mode 100644 (file)
index 0000000..a9be82a
--- /dev/null
@@ -0,0 +1,8 @@
+       .text
+       .global extobj
+       .data
+       .align  2
+       .type   extobj, %object
+       .size   extobj, 4
+extobj:
+       .word   1
diff --git a/ld/testsuite/ld-aarch64/morello-disallow-merged-binaries.d b/ld/testsuite/ld-aarch64/morello-disallow-merged-binaries.d
new file mode 100644 (file)
index 0000000..ddb44c5
--- /dev/null
@@ -0,0 +1,4 @@
+#source: morello-disallow-merged-binaries-data.s -march=morello
+#source: morello-disallow-merged-binaries-code.s -march=morello+c64
+#ld: -static
+#error: .*failed to merge target specific data.*