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.