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.
############### Attachment also inlined for ease of reply ###############
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index b460ea4764965da3b770ff6528730b4248377b16..1a65e6e5a64e115a99be8a707651ea1786b3fcdc 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -8715,7 +8715,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. */
@@ -8736,6 +8736,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
@@ -8746,7 +8748,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)
@@ -8770,11 +8771,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)
{
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index c40eba959421ac6d5e97f11d95a5900fa8e5b2bf..9168a810fc57783dd122ce40b6385dddc6888042 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 0000000000000000000000000000000000000000..83a7291c911f83f5ae611a3db7afbf95e2f0b10d
--- /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 0000000000000000000000000000000000000000..a9be82acddbb258ca8a27ea4b16adb62c786411d
--- /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 0000000000000000000000000000000000000000..ddb44c59764c71a5ea23a381ae02615f52a8e571
--- /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.*
The reasoning behind only warning for symbols which have a size which
cannot be precisely bounded is that there is nothing *requiring* precise
bounds, GCC knowingly avoids changing the size of some symbols for
precise bounds (TLS and symbols with user-specified alignment and
user-specified section), and LLD only warns on imprecise bounds rather
than erroring.
N.b. the reasoning for GCC avoiding padding in these cases is explained
in the commit message of b302420cb55 in the GCC branch
vendors/ARM/heads/morello.
All in all it's not something that we want in our toolchain as a
requirement, and it's not something that other toolchains have as a
requirement, so there doesn't seem to be much of a reason to include it.
In order to make this warning a little nicer for anyone reading it, we
add the name of the symbol to the warning. Update the testsuite to
account for this.
Co-Author: Alex Coplan <alex.coplan(a)arm.com>
############### Attachment also inlined for ease of reply ###############
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index cd54beec7b7d9f6b6977634dcd82501b80ab6cd4..939fac197d5dab3dcee8b9d820957e68419ca0af 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -6460,6 +6460,18 @@ c64_fixup_frag (bfd *input_bfd, struct bfd_link_info *info,
asection *perm_sec = sym_sec;
bfd_boolean bounds_ok = FALSE;
+ const char *sym_name;
+
+ if (sym)
+ {
+ Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd);
+ sym_name = (bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ sym->st_name));
+ }
+ else
+ sym_name = h->root.root.string;
+
if (size == 0 && sym_sec)
{
bounds_ok = TRUE;
@@ -6492,11 +6504,13 @@ c64_fixup_frag (bfd *input_bfd, struct bfd_link_info *info,
if (!bounds_ok && !c64_valid_cap_range (&base, &limit))
{
+ /* Just warn about this. It's not a requirement that bounds on
+ objects should be precise, so there's no reason to error out on
+ such an object. */
/* xgettext:c-format */
- _bfd_error_handler (_("%pB: capability range may exceed object bounds"),
- input_bfd);
- bfd_set_error (bfd_error_bad_value);
- return bfd_reloc_notsupported;
+ _bfd_error_handler
+ (_("%pB: capability range for '%s' may exceed object bounds"),
+ input_bfd, sym_name);
}
if (perm_sec && perm_sec->flags & SEC_CODE)
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-5.d b/ld/testsuite/ld-aarch64/emit-relocs-morello-5.d
index 05bbef145e03786dbb489b40441e78fbff69ddb5..7fa7909bdffd47c6877df709ad74d17bf0fc9c1f 100644
--- a/ld/testsuite/ld-aarch64/emit-relocs-morello-5.d
+++ b/ld/testsuite/ld-aarch64/emit-relocs-morello-5.d
@@ -1,6 +1,4 @@
#source: emit-relocs-morello-5.s
#as: -march=morello+c64
#ld: -static
-#error: .*: capability range may exceed object bounds
-#error: .*: in function `_start':.*
-#error: .*: dangerous relocation: unsupported relocation
+#warning: .*: capability range for 'bigarray' may exceed object bounds
Hi,
This is a respin of the following patch:
https://op-lists.linaro.org/archives/list/gnu-morello@op-lists.linaro.org/t…
In this version we drop the adjustment of the bounds given to symbols
without size information: we now leave these with zero bounds and drop
the diagnostic to allow the linker to accept capability relocations
against such symbols.
The new proposed commit message is below.
Regression tested on aarch64-none-elf, OK for the Morello branch?
Thanks,
Alex
------------------------------------------------------------------------
This patch has two main goals:
- Relax an existing diagnostic to permit the linker to accept
capability relocations against symbols without size information.
- Adjust the capability base and bounds for symbols which point into
sections which may be accessed via the PCC.
The Morello ABI accesses global data using ADR and ADRP, and has no
special indirection to jump to other functions. Given this, the PCC
must maintain its bounds and base so that during execution loading
global data and jumping to other functions can be done without worrying
about the current PCC permissions and bounds.
To implement this, all capabilities that could be loaded into the PCC
(via BLR or similar) must have a bounds and base according to the PCC.
This must span all global data and text sections (i.e. .got, .text,
.got.plt and the like).
There is already code finding the range that the PCC should span, this
patch records the information in a variable that we can query later.
There are two places where we create a relocation requesting a
capability to be initialised at runtime. When handling relocations
which request a capability from the GOT, and when handling a CAPINIT
relocation. This patch adjusts both.
We can't tell from inspection which symbols would be loaded into the
PCC, but we know that those symbols must point into a section which is
executable. For now, we do this operation for all symbols which point
into an executable section.
Most RELATIVE relocations don't use the addend. Rather the VA and size
we want are put in the relative fragment and the addend is zero.
This is because the *base* of the capability usually matches the VA we
want that capability initialised to.
In these possibly-code symbols we want the base of the capability bounds
to be the base of the PCC, and the VA to be something very different.
Hence we make use of the addend in the RELA relocations to encode this
offset.
Note on implementation:
c64_fixup_frag takes the base and size of a capability we want to
request from the runtime and checks that these are exactly representable
in a capability. This patch changes many of the capabilities we request
from the runtime to have the same bounds (those of the PCC). We leave
the check to look at the bounds requested by the symbol rather than to
check the PCC bounds multiple times. That means that if a symbol that
points into an executable section has incorrect bounds then this will
trigger a linker error even though it will cause no security problem
when this executes. This is a trade-off between getting extra checks
that the compiler is handling object bounds sizes and erroring on
non-problematic code.
We have a compatibility hack that if a symbol is defined in the linker
script to be directly after a given section but is *named* something
like __.*_start or __start_.* then we treat it as if it is defined at
the very start of the next section. The new behaviour introduced in
this patch needs to take account of the above compatibility hack.
This patch also updates the testsuite according to these changes.
In some places the original test no longer checks what it wanted, since
the base of all symbols pointing into executable sections are now the
same. There we add extra symbols and things to check so we ensure that
this behaviour of PCC bounds is seen and that the original behaviour is
still seen on non-executable sections.
This commit also includes a few tidy-ups:
We adjust the base and limit that are checked in c64_fixup_frag.
Originally this would calculate the base as value + addend. As
discussed above the way we treat capabilities in Morello is such that
the value determines the base and the addend determines the initial
value pointing from that base. Hence the check that these capabilities
had correct bounds was not correct.
We add an extra assertion in final_link_relocate for robustness
purposes. There is an existing bug in the assembler where GOT
relocations against local symbols can be turned into relocations against
the relevant section symbol plus an addend. This is problematic for
multiple reasons, one being that the linker implementation does not have
any way to associate different GOT entries with the same symbol but
multiple offsets. In fact the linker ignores any offset. Here we
simply add an assertion that this never happens. It turns a silent
pre-existing error into a noisy one.
2022-02-01 Alex Coplan <alex.coplan(a)arm.com>
Matthew Malcomson <matthew.malcomson(a)arm.com>
bfd/ChangeLog:
* elfnn-aarch64.c (pcc_low): New.
(pcc_high): New.
(elfNN_c64_resize_sections): Update new global variables
pcc_{low,high} instead of local variables to track PCC span.
(enum c64_section_perm_type): New.
(c64_symbol_section_adjustment): New.
(c64_fixup_frag): Rework to calculate size appropriately for
symbols that need adjustment.
(c64_symbol_adjust): New. Use it ...
(elfNN_aarch64_final_link_relocate): ... here.
ld/ChangeLog:
* testsuite/ld-aarch64/aarch64-elf.exp: Add new tests.
* testsuite/ld-aarch64/emit-relocs-morello-6.d: New test.
* testsuite/ld-aarch64/emit-relocs-morello-6.s: Assembly.
* testsuite/ld-aarch64/emit-relocs-morello-6b.d: New test.
* testsuite/ld-aarch64/emit-relocs-morello-7.d: New test.
* testsuite/ld-aarch64/emit-relocs-morello-7.ld: Linker script thereof.
* testsuite/ld-aarch64/emit-relocs-morello-7.s: Assembly.
* testsuite/ld-aarch64/morello-capinit.d: New test.
* testsuite/ld-aarch64/morello-capinit.ld: Linker script.
* testsuite/ld-aarch64/morello-capinit.s: Assembly.
* testsuite/ld-aarch64/morello-sizeless-global-syms.d: New test.
* testsuite/ld-aarch64/morello-sizeless-global-syms.s: Assembly.
* testsuite/ld-aarch64/morello-sizeless-got-syms.d: New test.
* testsuite/ld-aarch64/morello-sizeless-got-syms.s: Assembly.
* testsuite/ld-aarch64/morello-sizeless-local-syms.d: New test.
* testsuite/ld-aarch64/morello-sizeless-local-syms.s: Assembly.
Trying to link code against newlib with the current BFD Morello linker
we get quite a lot of cases of the error below.
"relocation truncated to fit: R_MORELLO_LD128_GOT_LO12_NC against symbol
`<whatever>' defined in .text.<whatever> section in <filename>"
This happens because the relocation gets transformed into a relocation
pointing into the GOT in elfNN_aarch64_final_link_relocate, but the
h->target_internal flag that indicates whether this is a C64 function
symbol or not is then added to the *end* value rather than the value
that is stored in the GOT.
This then correctly falls foul of a check in _bfd_aarch64_elf_put_addend
that ensures the value we get from this relocation is 8-byte aligned
since it must be pointing to the start of a valid entry in the GOT.
Here we ensure that this LSB is set on the value newly added into the
GOT rather than on the offset pointing into the GOT. This both means
that loading function symbols from the GOT will have the LSB correctly
set (hence we stay in C64 mode when branching to this function as we
should) and it means that the error about a misaligned GOT address is
fixed.
In this patch we also ensure that we add a dynamic relocation to
initialise the correct GOT entry when we are resolving a MORELLO
relocation that requires an entry in the GOT.
This was already handled in the case of a global symbol, but had not
been handled in the case of a local symbol. This is why we set
`relative_reloc` to TRUE in if resolving a MORELLO GOT relocation
against a static executable.
In writing the testcase for this patch we found an existing bug to do
with static relocations of this kind (of this kind meaning that are
handled in this case statement). The assembler often chooses to create
the relocation against the section symbol rather than the original
symbol, and make up for that by giving the relocation an addend. The
linker does not have any mechanism to create "symbol plus addend"
entries in the GOT -- it indexes into the GOT based on the symbol only.
Hence all relocations which are a section symbol plus addend end up
pointing at one value in the GOT just containing the value of the
symbol.
We do not fix this existing bug, but just note it given that this is in the
same area.
############### Attachment also inlined for ease of reply ###############
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 5c78fb54f919ddc7877b69da21f4594ade8ee98b..5fabfa32117fb20364aeefe949e21043c4731f24 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -7091,6 +7091,9 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1:
off = symbol_got_offset (input_bfd, h, r_symndx);
base_got = globals->root.sgot;
+ bfd_boolean c64_reloc =
+ (bfd_r_type == BFD_RELOC_MORELLO_LD128_GOT_LO12_NC
+ || bfd_r_type == BFD_RELOC_MORELLO_ADR_GOT_PAGE);
if (base_got == NULL)
BFD_ASSERT (h != NULL);
@@ -7099,9 +7102,6 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
if (h != NULL)
{
bfd_vma addend = 0;
- bfd_boolean c64_reloc =
- (bfd_r_type == BFD_RELOC_MORELLO_LD128_GOT_LO12_NC
- || bfd_r_type == BFD_RELOC_MORELLO_ADR_GOT_PAGE);
/* If a symbol is not dynamic and is not undefined weak, bind it
locally and generate a RELATIVE relocation under PIC mode.
@@ -7122,7 +7122,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
&& !symbol_got_offset_mark_p (input_bfd, h, r_symndx))
relative_reloc = TRUE;
- value = aarch64_calculate_got_entry_vma (h, globals, info, value,
+ value = aarch64_calculate_got_entry_vma (h, globals, info,
+ value | h->target_internal,
output_bfd,
unresolved_reloc_p);
/* Record the GOT entry address which will be used when generating
@@ -7136,7 +7137,6 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
place, value,
addend, weak_undef_p);
- value |= h->target_internal;
}
else
{
@@ -7160,14 +7160,17 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
if (!symbol_got_offset_mark_p (input_bfd, h, r_symndx))
{
- bfd_put_64 (output_bfd, value, base_got->contents + off);
+ bfd_put_64 (output_bfd, value | sym->st_target_internal,
+ base_got->contents + off);
/* For local symbol, we have done absolute relocation in static
linking stage. While for shared library, we need to update the
content of GOT entry according to the shared object's runtime
base address. So, we need to generate a R_AARCH64_RELATIVE reloc
for dynamic linker. */
- if (bfd_link_pic (info))
+ if (bfd_link_pic (info)
+ || (!bfd_link_pic (info) && bfd_link_executable (info)
+ && c64_reloc))
relative_reloc = TRUE;
symbol_got_offset_mark (input_bfd, h, r_symndx);
@@ -7183,8 +7186,6 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
place, value,
addend, weak_undef_p);
-
- value |= sym->st_target_internal;
}
if (relative_reloc)
@@ -7198,8 +7199,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
/* For a C64 relative relocation, also add size and permissions into
the frag. */
- if (bfd_r_type == BFD_RELOC_MORELLO_LD128_GOT_LO12_NC
- || bfd_r_type == BFD_RELOC_MORELLO_ADR_GOT_PAGE)
+ if (c64_reloc)
{
bfd_reloc_status_type ret;
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index 8de7bdfc6376e3ee0b750eb6429f18d6f4a92017..6b42dcfeddeb8426ce0c3aff19cd6ba904ddf2a8 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -246,6 +246,8 @@ run_dump_test_lp64 "emit-relocs-morello-3"
run_dump_test_lp64 "emit-relocs-morello-3-a64c"
run_dump_test_lp64 "emit-relocs-morello-4"
run_dump_test_lp64 "emit-relocs-morello-5"
+run_dump_test_lp64 "emit-relocs-morello-6"
+run_dump_test_lp64 "emit-relocs-morello-6b"
run_dump_test_lp64 "emit-morello-reloc-markers-1"
run_dump_test_lp64 "emit-morello-reloc-markers-2"
run_dump_test_lp64 "emit-morello-reloc-markers-3"
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-6.d b/ld/testsuite/ld-aarch64/emit-relocs-morello-6.d
new file mode 100644
index 0000000000000000000000000000000000000000..d97a59a916bda27854933362ba00afa174bb6886
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-morello-6.d
@@ -0,0 +1,44 @@
+# Check handling relocations into the got that require a GOT entry.
+# This case handles PIE binaries.
+#
+# This testcase uses exact values in order to check that of the two GOT entries
+# created, the one that is referenced by the first instruction in _start is
+# the one which has the LSB set in its value.
+#
+# It's difficult to check this in the DejaGNU testsuite without checking for
+# specific values that we know are good. However this is susceptible to
+# defaults changing where the .text and .got sections end up.
+#
+# If this testcase prooves to be too flaky while the linker gets updated then
+# we should look harder for some solution, but for now we'll take this
+# tradeoff.
+#source: emit-relocs-morello-6.s
+#as: -march=morello+c64
+#ld: -Ttext-segment 0x0 -pie -static
+#objdump: -DR -j .got -j .text
+
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+00000000000001e8 <_start>:
+ 1e8: c240c400 ldr c0, \[c0, #784\]
+ 1ec: c240c000 ldr c0, \[c0, #768\]
+
+Disassembly of section \.got:
+
+00000000000102f0 <\.got>:
+ 102f0: 000101f0 \.inst 0x000101f0 ; undefined
+ \.\.\.
+ 10300: 000001e8 udf #488
+ 10300: R_MORELLO_RELATIVE \*ABS\*
+ 10304: 00000000 udf #0
+ 10308: .*
+ 1030c: .*
+ 10310: 000001e9 udf #489
+ 10310: R_MORELLO_RELATIVE \*ABS\*
+ 10314: .*
+ 10318: .*
+ 1031c: .*
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-6.s b/ld/testsuite/ld-aarch64/emit-relocs-morello-6.s
new file mode 100644
index 0000000000000000000000000000000000000000..eafc9968c522450d832ec0b0ac68df9ada5cb446
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-morello-6.s
@@ -0,0 +1,20 @@
+# Checking
+# - LD128 relocation has been resolved to GOT location.
+# - Relocation at that GOT location is introduced.
+# - GOT fragment contains address required.
+# - GOT fragment has LSB set if relocation is a function symbol.
+.arch morello+c64
+ .text
+ .global _start
+
+ .type _start,@function
+_start:
+ .size _start,12
+
+ .type obj,@object
+ .global obj
+ .size obj,1
+obj:
+
+ ldr c0, [c0, :got_lo12:_start]
+ ldr c0, [c0, :got_lo12:obj]
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-6b.d b/ld/testsuite/ld-aarch64/emit-relocs-morello-6b.d
new file mode 100644
index 0000000000000000000000000000000000000000..3d2ca260156ea4e83d99cce8962cf42fe9b19151
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-morello-6b.d
@@ -0,0 +1,56 @@
+# Check handling relocations into the got that require a GOT entry.
+# This case handles non-PIE binaries.
+#
+# This testcase uses exact values in order to check that of the two GOT entries
+# created, the one that is referenced by the first instruction in _start is
+# the one which has the LSB set in its value.
+#
+# It's difficult to check this in the DejaGNU testsuite without checking for
+# specific values that we know are good. However this is susceptible to
+# defaults changing where the .text and .got sections end up.
+#
+# If this testcase prooves to be too flaky while the linker gets updated then
+# we should look harder for some solution, but for now we'll take this
+# tradeoff.
+#
+# Here we have to use a format which dumps the hex of the relocation section
+# since objdump does not show us dynamic relocations on a non-dynamic binary.
+#source: emit-relocs-morello-6.s
+#as: -march=morello+c64
+#ld: -Ttext-segment 0x0 -static
+#objdump: -D -j .rela.dyn -j .got -j .text
+
+
+.*: file format .*
+
+
+Disassembly of section \.rela\.dyn:
+
+0000000000000000 <__rela_dyn_start>:
+ 0: 00010060 .*
+ 4: 00000000 .*
+ 8: 0000e803 .*
+ \.\.\.
+ 18: 00010050 .*
+ 1c: 00000000 .*
+ 20: 0000e803 .*
+ \.\.\.
+
+Disassembly of section \.text:
+
+0000000000000030 <_start>:
+ 30: c2401800 ldr c0, \[c0, #96\]
+ 34: c2401400 ldr c0, \[c0, #80\]
+
+Disassembly of section \.got:
+
+0000000000010040 <_GLOBAL_OFFSET_TABLE_>:
+ \.\.\.
+ 10050: 00000030 .*
+ 10054: 00000000 .*
+ 10058: 00000101 .*
+ 1005c: 00000000 .*
+ 10060: 00000031 .*
+ 10064: 00000000 .*
+ 10068: 00000c01 .*
+ 1006c: 00000000 .*
Hi,
This patch adjusts capability relocations against two classes of symbols:
- Symbols which point into sections which may be accessed via the PCC.
- Symbols without size information.
For the latter, we emit a warning and adjust the capability relocation
and fragment such that the resulting capability has bounds permitting
access to the entire section. This matches the behaviour of LLD.
For the former, we adjust them as described in the following
explanation.
The Morello ABI accesses global data using ADR and ADRP, and has no
special indirection to jump to other functions. Given this, the PCC
must maintain its bounds and base so that during execution loading
global data and jumping to other functions can be done without worrying
about the current PCC permissions and bounds.
To implement this, all capabilities that could be loaded into the PCC
(via BLR or similar) must have a bounds and base according to the PCC.
This must span all global data and text sections (i.e. .got, .text,
.got.plt and the like).
There is already code finding the range that the PCC should span, this
patch records the information in a variable that we can query later.
There are two places where we create a relocation requesting a
capability to be initialised at runtime. When handling relocations
which request a capability from the GOT, and when handling a CAPINIT
relocation. This patch adjusts both.
We can't tell from inspection which symbols would be loaded into the
PCC, but we know that those symbols must point into a section which is
executable. Hence we do this operation for all symbols which point into
an executable section.
Most RELATIVE relocations don't use the addend. Rather the VA and size
we want are put in the relative fragment and the addend is zero.
This is because the *base* of the capability usually matches the VA we
want that capability initialised to.
In these possibly-code symbols we want the base of the capability bounds
to be the base of the PCC, and the VA to be something very different.
Hence we make use of the addend in the RELA relocations to encode this
offset.
Note on implementation:
c64_fixup_frag takes the base and size of a capability we want to
request from the runtime and checks that these are exactly representable
in a capability. This patch changes many of the capabilities we request
from the runtime to have the same bounds (those of the PCC). We leave
the check to look at the bounds requested by the symbol rather than to
check the PCC bounds multiple times. That means that if a symbol that
points into an executable section has incorrect bounds then this will
trigger a linker error even though it will cause no security problem
when this executes. This is a trade-off between getting extra checks
that the compiler is handling object bounds sizes and erroring on
non-problematic code.
We have a compatibility hack that if a symbol is defined in the linker
script to be directly after a given section but is *named* something
like __.*_start or __start_.* then we treat it as if it is defined at
the very start of the next section. The new behaviour introduced in
this patch needs to take account of the above compatibility hack.
Hence we define a helper function to perform the relevent adjustment.
It would be nice to also use the helper function so that it can be used
in elfNN_c64_resize_sections, but that function will already need
updating to account for the fact that zero-sized symbols found in the
input will span entire sections. Hence we leave this function for then,
since the manner in which we would use this helper function may change.
This patch also updates the entire testsuite according to these changes.
In some places the original test no longer checks what it wanted, since
the base of all symbols pointing into executable sections are now the
same. There we add extra symbols and things to check so we ensure that
this behaviour of PCC bounds is seen and that the original behaviour is
still seen on non-executable sections.
This commit also includes a few tidy-ups:
We adjust the base and limit that are checked in c64_fixup_frag.
Originally this would calculate the base as value + addend. As
discussed above the way we treat capabilities in Morello is such that
the value determines the base and the addend determines the initial
value pointing from that base. Hence the check that these capabilities
had correct bounds was not correct.
We add an extra assertion in final_link_relocate for robustness
purposes. There is an existing bug in the assembler where GOT
relocations against local symbols can be turned into relocations against
the relevant section symbol plus an addend. This is problematic for
multiple reasons, one being that the linker implementation does not have
any way to associate different GOT entries with the same symbol but
multiple offsets. In fact the linker ignores any offset. Here we
simply add an assertion that this never happens. It turns a silent
pre-existing error into a noisy one.
Regression tested on aarch64-none-elf, OK for
users/ARM/morello-binutils-gdb-master?
Thanks,
Alex
2022-01-19 Alex Coplan <alex.coplan(a)arm.com>
Matthew Malcolmson <matthew.malcolmson(a)arm.com>
bfd/ChangeLog:
* elfnn-aarch64.c (pcc_low): New.
(pcc_high): New.
(elfNN_c64_resize_sections): Update new global variables
pcc_{low,high} instead of local variables to track PCC span.
(enum c64_section_perm_type): New.
(c64_symbol_section_adjustment): New.
(c64_fixup_frag): Rework to calculate size appropriately for
symbols that need adjustment.
(c64_symbol_adjust): New. Use it ...
(elfNN_aarch64_final_link_relocate): ... here.
ld/ChangeLog:
* testsuite/ld-aarch64/aarch64-elf.exp: Add new tests.
* testsuite/ld-aarch64/emit-relocs-morello-6.d: New test.
* testsuite/ld-aarch64/emit-relocs-morello-6.s: Assembly.
* testsuite/ld-aarch64/emit-relocs-morello-6b.d: New test.
* testsuite/ld-aarch64/emit-relocs-morello-7.d: New test.
* testsuite/ld-aarch64/emit-relocs-morello-7.ld: Linker script thereof.
* testsuite/ld-aarch64/emit-relocs-morello-7.s: Assembly.
* testsuite/ld-aarch64/morello-capinit.d: New test.
* testsuite/ld-aarch64/morello-capinit.ld: Linker script.
* testsuite/ld-aarch64/morello-capinit.s: Assembly.
* testsuite/ld-aarch64/morello-sizeless-global-syms.d: New test.
* testsuite/ld-aarch64/morello-sizeless-global-syms.s: Assembly.
* testsuite/ld-aarch64/morello-sizeless-got-syms.d: New test.
* testsuite/ld-aarch64/morello-sizeless-got-syms.s: Assembly.
* testsuite/ld-aarch64/morello-sizeless-local-syms.d: New test.
* testsuite/ld-aarch64/morello-sizeless-local-syms.s: Assembly.
Hi,
This patch adjusts capability relocations against two classes of symbols:
- Symbols which point into sections which may be accessed via the PCC.
- Symbols without size information.
For the latter, we emit a warning and adjust the capability relocation
and fragment such that the resulting capability has bounds permitting
access to the entire section. This matches the behaviour of LLD.
For the former, we adjust them as described in the following
explanation.
The Morello ABI accesses global data using ADR and ADRP, and has no
special indirection to jump to other functions. Given this, the PCC
must maintain its bounds and base so that during execution loading
global data and jumping to other functions can be done without worrying
about the current PCC permissions and bounds.
To implement this, all capabilities that could be loaded into the PCC
(via BLR or similar) must have a bounds and base according to the PCC.
This must span all global data and text sections (i.e. .got, .text,
.got.plt and the like).
There is already code finding the range that the PCC should span, this
patch records the information in a variable that we can query later.
There are two places where we create a relocation requesting a
capability to be initialised at runtime. When handling relocations
which request a capability from the GOT, and when handling a CAPINIT
relocation. This patch adjusts both.
We can't tell from inspection which symbols would be loaded into the
PCC, but we know that those symbols must point into a section which is
executable. Hence we do this operation for all symbols which point into
an executable section.
Most RELATIVE relocations don't use the addend. Rather the VA and size
we want are put in the relative fragment and the addend is zero.
This is because the *base* of the capability usually matches the VA we
want that capability initialised to.
In these possibly-code symbols we want the base of the capability bounds
to be the base of the PCC, and the VA to be something very different.
Hence we make use of the addend in the RELA relocations to encode this
offset.
Note on implementation:
c64_fixup_frag takes the base and size of a capability we want to
request from the runtime and checks that these are exactly representable
in a capability. This patch changes many of the capabilities we request
from the runtime to have the same bounds (those of the PCC). We leave
the check to look at the bounds requested by the symbol rather than to
check the PCC bounds multiple times. That means that if a symbol that
points into an executable section has incorrect bounds then this will
trigger a linker error even though it will cause no security problem
when this executes. This is a trade-off between getting extra checks
that the compiler is handling object bounds sizes and erroring on
non-problematic code.
We have a compatibility hack that if a symbol is defined in the linker
script to be directly after a given section but is *named* something
like __.*_start or __start_.* then we treat it as if it is defined at
the very start of the next section. The new behaviour introduced in
this patch needs to take account of the above compatibility hack.
Hence we define a helper function to perform the relevent adjustment.
It would be nice to also use the helper function so that it can be used
in elfNN_c64_resize_sections, but that function will already need
updating to account for the fact that zero-sized symbols found in the
input will span entire sections. Hence we leave this function for then,
since the manner in which we would use this helper function may change.
This patch also updates the entire testsuite according to these changes.
In some places the original test no longer checks what it wanted, since
the base of all symbols pointing into executable sections are now the
same. There we add extra symbols and things to check so we ensure that
this behaviour of PCC bounds is seen and that the original behaviour is
still seen on non-executable sections.
This commit also includes a few tidy-ups:
We adjust the base and limit that are checked in c64_fixup_frag.
Originally this would calculate the base as value + addend. As
discussed above the way we treat capabilities in Morello is such that
the value determines the base and the addend determines the initial
value pointing from that base. Hence the check that these capabilities
had correct bounds was not correct.
We add an extra assertion in final_link_relocate for robustness
purposes. There is an existing bug in the assembler where GOT
relocations against local symbols can be turned into relocations against
the relevant section symbol plus an addend. This is problematic for
multiple reasons, one being that the linker implementation does not have
any way to associate different GOT entries with the same symbol but
multiple offsets. In fact the linker ignores any offset. Here we
simply add an assertion that this never happens. It turns a silent
pre-existing error into a noisy one.
Regression tested on aarch64-none-elf, OK for
users/ARM/morello-binutils-gdb-master?
Thanks,
Alex
2022-01-21 Alex Coplan <alex.coplan(a)arm.com>
Matthew Malcomson <matthew.malcomson(a)arm.com>
bfd/ChangeLog:
* elfnn-aarch64.c (pcc_low): New.
(pcc_high): New.
(elfNN_c64_resize_sections): Update new global variables
pcc_{low,high} instead of local variables to track PCC span.
(enum c64_section_perm_type): New.
(c64_symbol_section_adjustment): New.
(c64_fixup_frag): Rework to calculate size appropriately for
symbols that need adjustment.
(c64_symbol_adjust): New. Use it ...
(elfNN_aarch64_final_link_relocate): ... here.
ld/ChangeLog:
* testsuite/ld-aarch64/aarch64-elf.exp: Add new tests.
* testsuite/ld-aarch64/emit-relocs-morello-6.d: New test.
* testsuite/ld-aarch64/emit-relocs-morello-6.s: Assembly.
* testsuite/ld-aarch64/emit-relocs-morello-6b.d: New test.
* testsuite/ld-aarch64/emit-relocs-morello-7.d: New test.
* testsuite/ld-aarch64/emit-relocs-morello-7.ld: Linker script thereof.
* testsuite/ld-aarch64/emit-relocs-morello-7.s: Assembly.
* testsuite/ld-aarch64/morello-capinit.d: New test.
* testsuite/ld-aarch64/morello-capinit.ld: Linker script.
* testsuite/ld-aarch64/morello-capinit.s: Assembly.
* testsuite/ld-aarch64/morello-sizeless-global-syms.d: New test.
* testsuite/ld-aarch64/morello-sizeless-global-syms.s: Assembly.
* testsuite/ld-aarch64/morello-sizeless-got-syms.d: New test.
* testsuite/ld-aarch64/morello-sizeless-got-syms.s: Assembly.
* testsuite/ld-aarch64/morello-sizeless-local-syms.d: New test.
* testsuite/ld-aarch64/morello-sizeless-local-syms.s: Assembly.
The name has been changed in LLVM, so we adjust it in binutils to match.
We also move where these symbols are created. Previously they were
created in elfNN_aarch64_always_size_sections, but we move this to
elfNN_aarch64_size_dynamic_sections.
We do the moving since these symbols are supposed to span all dynamic
capability relocations stored in the .rela.dyn section for static
executables. In the case of a static binary we place relocations for
the GOT into this section as well as internal relocations.
These relocations for the GOT are handled in
elfNN_aarch64_size_dynamic_sections, which is called *after*
elfNN_aarch64_always_size_sections. The size of this section is only
fully known after those GOT relocations are managed, so the position
these symbols should be placed in is only known at that point. Hence we
only initialise the __rela_dyn* symbols at that point.
2021-10-06 Matthew Malcomson <matthew.malcomson(a)arm.com>
ChangeLog:
* bfd/elfnn-aarch64.c (elfNN_aarch64_always_size_sections): Move
initialisation of __rela_dyn* symbols ...
(elfNN_aarch64_size_dynamic_sections): ... to here.
* ld/testsuite/ld-aarch64/aarch64-elf.exp: Run new tests.
* ld/testsuite/ld-aarch64/emit-morello-reloc-markers-1.d: New test.
* ld/testsuite/ld-aarch64/emit-morello-reloc-markers-1.s: New test.
* ld/testsuite/ld-aarch64/emit-morello-reloc-markers-2.d: New test.
* ld/testsuite/ld-aarch64/emit-morello-reloc-markers-2.s: New test.
* ld/testsuite/ld-aarch64/emit-morello-reloc-markers-3.d: New test.
* ld/testsuite/ld-aarch64/emit-morello-reloc-markers-3.s: New test.
############### Attachment also inlined for ease of reply ###############
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 73ffdad33bc8d5bf9cf2e2d84a606e8d183695f7..5c78fb54f919ddc7877b69da21f4594ade8ee98b 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -10355,6 +10355,23 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd,
elfNN_aarch64_allocate_local_ifunc_dynrelocs,
info);
+ if (bfd_link_executable (info)
+ && !bfd_link_pic (info)
+ && htab->srelcaps
+ && htab->srelcaps->size > 0)
+ {
+ struct elf_link_hash_entry *h;
+
+ h = _bfd_elf_define_linkage_sym (output_bfd, info,
+ htab->srelcaps,
+ "__rela_dyn_start");
+ h = _bfd_elf_define_linkage_sym (output_bfd, info,
+ htab->srelcaps,
+ "__rela_dyn_end");
+
+ h->root.u.def.value = htab->srelcaps->vma + htab->srelcaps->size;
+ }
+
/* For every jump slot reserved in the sgotplt, reloc_count is
incremented. However, when we reserve space for TLS descriptors,
it's not incremented, so in order to compute the space reserved
@@ -10668,25 +10685,6 @@ elfNN_aarch64_always_size_sections (bfd *output_bfd,
if (bfd_link_relocatable (info))
return TRUE;
- struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
-
- if (bfd_link_executable (info)
- && !bfd_link_pic (info)
- && htab->srelcaps
- && htab->srelcaps->size > 0)
- {
- struct elf_link_hash_entry *h;
-
- h = _bfd_elf_define_linkage_sym (output_bfd, info,
- htab->srelcaps,
- "__cap_dynrelocs_start");
- h = _bfd_elf_define_linkage_sym (output_bfd, info,
- htab->srelcaps,
- "__cap_dynrelocs_end");
-
- h->root.u.def.value = htab->srelcaps->vma + htab->srelcaps->size;
- }
-
tls_sec = elf_hash_table (info)->tls_sec;
if (tls_sec)
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index 228cfe224c57efc1cac6c694d304d8186e8749d6..8de7bdfc6376e3ee0b750eb6429f18d6f4a92017 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -246,6 +246,9 @@ run_dump_test_lp64 "emit-relocs-morello-3"
run_dump_test_lp64 "emit-relocs-morello-3-a64c"
run_dump_test_lp64 "emit-relocs-morello-4"
run_dump_test_lp64 "emit-relocs-morello-5"
+run_dump_test_lp64 "emit-morello-reloc-markers-1"
+run_dump_test_lp64 "emit-morello-reloc-markers-2"
+run_dump_test_lp64 "emit-morello-reloc-markers-3"
run_dump_test_lp64 "morello-capinit"
run_dump_test_lp64 "morello-stubs"
diff --git a/ld/testsuite/ld-aarch64/emit-morello-reloc-markers-1.d b/ld/testsuite/ld-aarch64/emit-morello-reloc-markers-1.d
new file mode 100644
index 0000000000000000000000000000000000000000..b8474f996fee97befacaf2f3366e2f1ef6a6885d
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-morello-reloc-markers-1.d
@@ -0,0 +1,19 @@
+# The aim here is to test that
+# a) We generate the __rela_dyn_{start,end} symbols.
+# b) They span the entire .rela.dyn section.
+# This particular case (the -1 file) is in case of there being no .got symbols.
+#source: emit-morello-reloc-markers-1.s
+#as: -march=morello+c64
+#ld: -Ttext-segment 0x0 -static
+#objdump: --syms --section-headers --section=.rela.dyn --section=.got
+
+.*: file format .*
+
+Sections:
+Idx Name Size VMA LMA File off Algn
+ 0 \.rela\.dyn 00000018 0000000000000000 0000000000000000 00010000 2\*\*3
+ CONTENTS, ALLOC, LOAD, READONLY, DATA
+SYMBOL TABLE:
+0000000000000000 l d \.rela\.dyn 0000000000000000 \.rela\.dyn
+0000000000000018 l O \.rela\.dyn 0000000000000000 __rela_dyn_end
+0000000000000000 l O \.rela\.dyn 0000000000000000 __rela_dyn_start
diff --git a/ld/testsuite/ld-aarch64/emit-morello-reloc-markers-1.s b/ld/testsuite/ld-aarch64/emit-morello-reloc-markers-1.s
new file mode 100644
index 0000000000000000000000000000000000000000..b445fe1a2f6212fc838f7b7ed3b03e95b1ae6bb1
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-morello-reloc-markers-1.s
@@ -0,0 +1,28 @@
+ .arch morello+crc+c64
+ .file "very-basic-test.c"
+ .text
+ .data
+ .align 2
+ .type retval, %object
+ .size retval, 4
+retval:
+ .word 1
+ .text
+ .align 2
+ .global _start
+ .type _start, %function
+_start:
+ adrp c0, .LC0
+ add c0, c0, :lo12:.LC0
+ ldr c0, [c0]
+ ldr w0, [c0]
+ ret
+ .size _start, .-_start
+ .section .data.rel.ro.local,"aw"
+ .align 4
+ .type .LC0, %object
+ .size .LC0, 16
+.LC0:
+ .capinit retval
+ .xword 0
+ .xword 0
diff --git a/ld/testsuite/ld-aarch64/emit-morello-reloc-markers-2.d b/ld/testsuite/ld-aarch64/emit-morello-reloc-markers-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..c2fcd5001fb2bc99977d7407ef9ed9165f440a44
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-morello-reloc-markers-2.d
@@ -0,0 +1,25 @@
+# The aim here is to test that
+# a) We generate the __rela_dyn_{start,end} symbols.
+# b) They span the entire .rela.dyn section.
+# This particular case (the -2 file) is in case of there both .got symbols and
+# local symbols that require relocations.
+#source: emit-morello-reloc-markers-2.s
+#as: -march=morello+c64
+#ld: -Ttext-segment 0x0 -static
+#objdump: --syms --section-headers --section=.rela.dyn --section=.got
+
+.*: file format .*
+
+Sections:
+Idx Name Size VMA LMA File off Algn
+ 0 \.rela\.dyn 00000030 0000000000000000 0000000000000000 00010000 2\*\*3
+ CONTENTS, ALLOC, LOAD, READONLY, DATA
+ .* \.got .*
+.*
+
+SYMBOL TABLE:
+0000000000000000 l d \.rela\.dyn 0000000000000000 \.rela\.dyn
+.*
+0000000000000030 l O \.rela\.dyn 0000000000000000 __rela_dyn_end
+0000000000000000 l O \.rela\.dyn 0000000000000000 __rela_dyn_start
+#pass
diff --git a/ld/testsuite/ld-aarch64/emit-morello-reloc-markers-2.s b/ld/testsuite/ld-aarch64/emit-morello-reloc-markers-2.s
new file mode 100644
index 0000000000000000000000000000000000000000..3bdee480836df4b1bd0592edcfa92c08cda554bb
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-morello-reloc-markers-2.s
@@ -0,0 +1,38 @@
+ .arch morello+crc+c64
+ .file "very-basic-test.c"
+ .text
+ .data
+ .align 2
+ .type retval, %object
+ .size retval, 4
+retval:
+ .word 1
+ .global other
+ .align 2
+ .type other, %object
+ .size other, 4
+other:
+ .word 1
+ .text
+ .align 2
+ .global _start
+ .type _start, %function
+_start:
+ adrp c0, .LC0
+ add c0, c0, :lo12:.LC0
+ ldr c0, [c0]
+ ldr w1, [c0]
+ adrp c0, :got:other
+ ldr c0, [c0, #:got_lo12:other]
+ ldr w0, [c0]
+ add w0, w1, w0
+ ret
+ .size _start, .-_start
+ .section .data.rel.ro.local,"aw"
+ .align 4
+ .type .LC0, %object
+ .size .LC0, 16
+.LC0:
+ .capinit retval
+ .xword 0
+ .xword 0
diff --git a/ld/testsuite/ld-aarch64/emit-morello-reloc-markers-3.d b/ld/testsuite/ld-aarch64/emit-morello-reloc-markers-3.d
new file mode 100644
index 0000000000000000000000000000000000000000..8ebf8420ca354daa4166883329526ce711a3793a
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-morello-reloc-markers-3.d
@@ -0,0 +1,25 @@
+# The aim here is to test that
+# a) We generate the __rela_dyn_{start,end} symbols.
+# b) They span the entire .rela.dyn section.
+# This particular case (the -3 file) is in case of there being only .got
+# symbols that need dynamic relocations.
+#source: emit-morello-reloc-markers-3.s
+#as: -march=morello+c64
+#ld: -Ttext-segment 0x0 -static
+#objdump: --syms --section-headers --section=.rela.dyn --section=.got
+
+.*: file format .*
+
+Sections:
+Idx Name Size VMA LMA File off Algn
+ 0 \.rela\.dyn 00000018 0000000000000000 0000000000000000 00010000 2\*\*3
+ CONTENTS, ALLOC, LOAD, READONLY, DATA
+ .* \.got .*
+.*
+
+SYMBOL TABLE:
+0000000000000000 l d \.rela\.dyn 0000000000000000 \.rela\.dyn
+.*
+0000000000000018 l O \.rela\.dyn 0000000000000000 __rela_dyn_end
+0000000000000000 l O \.rela\.dyn 0000000000000000 __rela_dyn_start
+#pass
diff --git a/ld/testsuite/ld-aarch64/emit-morello-reloc-markers-3.s b/ld/testsuite/ld-aarch64/emit-morello-reloc-markers-3.s
new file mode 100644
index 0000000000000000000000000000000000000000..b6cd8015432c6b7632e3b24fb1ae6e703588287e
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-morello-reloc-markers-3.s
@@ -0,0 +1,20 @@
+ .arch morello+crc+c64
+ .file "very-basic-test.c"
+ .text
+ .global retval
+ .data
+ .align 2
+ .type retval, %object
+ .size retval, 4
+retval:
+ .word 1
+ .text
+ .align 2
+ .global _start
+ .type _start, %function
+_start:
+ adrp c0, :got:retval
+ ldr c0, [c0, #:got_lo12:retval]
+ ldr w0, [c0]
+ ret
+ .size _start, .-_start
Hi,
The behaviour of weak undef thread-local variables is not well defined.
TLS relocations against weak undef symbols are not handled properly by
the linker, and in some cases cause the linker to crash (notably when
linking glibc for purecap Morello). This patch simply ignores these and
emits a warning to that effect. This is a compromise to enable progress
for Morello.
Regression tested an aarch64-none-elf cross, OK for
users/ARM/morello-binutils-gdb-master?
Thanks,
Alex
bfd/ChangeLog:
2021-12-08 Alex Coplan <alex.coplan(a)arm.com>
* elfnn-aarch64.c (elfNN_aarch64_relocate_section): Skip over TLS
relocations against weak undef symbols.
(elfNN_aarch64_check_relocs): Likewise, but also warn.
ld/ChangeLog:
2021-12-08 Alex Coplan <alex.coplan(a)arm.com>
* testsuite/ld-aarch64/aarch64-elf.exp: Add morello-weak-tls test.
* testsuite/ld-aarch64/morello-weak-tls.d: New test.
* testsuite/ld-aarch64/morello-weak-tls.s: New test.
* testsuite/ld-aarch64/weak-tls.d: Update test wrt new behaviour.
Hi,
Prior to this patch, we were failing to validate scbnds instructions
properly in multiple ways. The code in tc-aarch64.c:parse_operands
failed to check if the expression parsing code actually returned a
constant (O_constant) immediate. For sufficiently large immediates this
would result in O_big instead and this was not handled.
Moreover, the code to coerce the immediate form into the immediate +
shift form of the instruction was buggy in multiple ways: using the
wrong mask to check if the lower bits were set and checking the wrong
variable.
Finally, the code in operand_general_constraint_met_p was only checking
if the immediate is in range for the shifted case: it should be checking
this in both cases.
As well as fixing these issues, this patch improves the error messages
in a couple of cases and adds tests for various valid and invalid cases.
Regression tested on aarch64-linux-gnu, OK for Morello branch?
Thanks,
Alex
gas/ChangeLog:
2021-11-10 Alex Coplan <alex.coplan(a)arm.com>
* config/tc-aarch64.c (parse_shift): Improve error message for
O_big expressions.
(parse_operands): In AARCH64_OPND_A64C_IMM6_EXT case, handle
parse_shifter_operand_imm returning non-O_constant
expressions; fix logic for coercion to the shifted form.
* testsuite/gas/aarch64/scbnds-immed.d: New test.
* testsuite/gas/aarch64/scbnds-immed.s: Assembly thereof.
* testsuite/gas/aarch64/scbnds-invalid.d: New test.
* testsuite/gas/aarch64/scbnds-invalid.l: Error output thereof.
* testsuite/gas/aarch64/scbnds-invalid.s: Assembly thereof.
opcodes/ChangeLog:
2021-11-10 Alex Coplan <alex.coplan(a)arm.com>
* aarch64-opc.c (operand_general_constraint_met_p): Always check
if the immediate is in range for AARCH64_OPND_A64C_IMM6_EXT.