From 00ef0d31ac92f61336d4f9eceab342fd88ad7e5e Mon Sep 17 00:00:00 2001 From: Matthew Malcomson Date: Mon, 7 Feb 2022 16:54:55 +0000 Subject: [PATCH] Error linking binaries with differing e_flags. 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 | 15 +++++++++++---- ld/testsuite/ld-aarch64/aarch64-elf.exp | 1 + .../morello-disallow-merged-binaries-code.s | 11 +++++++++++ .../morello-disallow-merged-binaries-data.s | 8 ++++++++ .../ld-aarch64/morello-disallow-merged-binaries.d | 4 ++++ 5 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 ld/testsuite/ld-aarch64/morello-disallow-merged-binaries-code.s create mode 100644 ld/testsuite/ld-aarch64/morello-disallow-merged-binaries-data.s create mode 100644 ld/testsuite/ld-aarch64/morello-disallow-merged-binaries.d diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index bd38ee138bb..089d8988188 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -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) { diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp index 1aeb932df45..ef1b39954f1 100644 --- a/ld/testsuite/ld-aarch64/aarch64-elf.exp +++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp @@ -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 index 00000000000..83a7291c911 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-disallow-merged-binaries-code.s @@ -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 index 00000000000..a9be82acddb --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-disallow-merged-binaries-data.s @@ -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 index 00000000000..ddb44c59764 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-disallow-merged-binaries.d @@ -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.* -- 2.47.2