]> 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)
committerJohn Baldwin <jhb@FreeBSD.org>
Thu, 1 Sep 2022 22:59:25 +0000 (15:59 -0700)
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 bd38ee138bbc20092ebabbf90370f4bca0b90f71..089d898818806bcd823a958e6f6f82b3f37fe121 100644 (file)
@@ -8689,7 +8689,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;
-  bool flags_compatible = true;
+  bool flags_compatible = false;
   asection *sec;
 
   /* Check if we have the same endianess.  */
@@ -8710,6 +8710,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
@@ -8720,7 +8722,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)
@@ -8744,11 +8745,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))
     {
       bool null_input_bfd = true;
-      bool only_data_sections = true;
+      bool 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 1aeb932df450ece9c6e88662c2e5800565bb2016..ef1b39954f1f0b943fcbc43a5167e7381c3b6e08 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.*