+2022-02-03 Alex Coplan <alex.coplan@arm.com>
+ Matthew Malcomson <matthew.malcomson@arm.com>
+
+ * 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.
+
2022-01-17 Alex Coplan <alex.coplan@arm.com>
* elfnn-aarch64.c (elfNN_aarch64_relocate_section): Skip over TLS
of the section and if necessary, adding a pad at the end of the section so
that the section following it starts only after the pad. */
+static bfd_vma pcc_low;
+static bfd_vma pcc_high;
void
elfNN_c64_resize_sections (bfd *output_bfd, struct bfd_link_info *info,
void (*c64_pad_section) (asection *, bfd_vma),
/* Layout sections since it affects the final range of PCC. */
(*htab->layout_sections_again) ();
- bfd_vma pcc_low = pcc_low_sec->vma;
- bfd_vma pcc_high = pcc_high_sec->vma + pcc_high_sec->size + padding;
+ pcc_low = pcc_low_sec->vma;
+ pcc_high = pcc_high_sec->vma + pcc_high_sec->size + padding;
if (!c64_valid_cap_range (&pcc_low, &pcc_high))
{
queue = queue->next;
free (queue_free);
}
+
+ if (pcc_low_sec)
+ {
+ if (!pcc_high_sec)
+ abort ();
+ pcc_low = pcc_low_sec->vma;
+ pcc_high = pcc_high_sec->vma + pcc_high_sec->size;
+ }
}
/* Determine and set the size of the stub section for a final link.
abort ();
}
+enum c64_section_perm_type {
+ C64_SYM_UNKNOWN = 0,
+ C64_SYM_STANDARD,
+ C64_SYM_LINKER_DEF,
+ C64_SYM_LDSCRIPT_DEF,
+ C64_SYM_LDSCRIPT_START,
+};
+
+static enum c64_section_perm_type
+c64_symbol_section_adjustment (struct elf_link_hash_entry *h, bfd_vma value,
+ asection *sym_sec, asection **ret_sec,
+ struct bfd_link_info *info)
+{
+ if (!sym_sec)
+ return C64_SYM_UNKNOWN;
+
+ *ret_sec = sym_sec;
+ if (!h)
+ return C64_SYM_STANDARD;
+
+ /* Linker defined symbols are always at the start of the section they
+ track. */
+ if (h->root.linker_def)
+ return C64_SYM_LINKER_DEF;
+ else if (h->root.ldscript_def)
+ {
+ const char *name = h->root.root.string;
+ size_t len = strlen (name);
+
+ bfd_vma size = sym_sec->size - (value - sym_sec->vma);
+ /* The special case: the symbol is at the end of the section.
+ This could either mean that it is an end symbol or it is the
+ start of the output section following the symbol. We try to
+ guess if it is a start of the next section by reading its
+ name. This is a compatibility hack, ideally linker scripts
+ should be written such that start symbols are defined within
+ the output section it intends to track. */
+ if (size == 0
+ && (len > 8 && name[0] == '_' && name[1] == '_'
+ && (!strncmp (name + 2, "start_", 6)
+ || !strcmp (name + len - 6, "_start"))))
+ {
+ asection *s = bfd_sections_find_if (info->output_bfd,
+ section_start_symbol,
+ &value);
+ if (s != NULL)
+ {
+ *ret_sec = s;
+ return C64_SYM_LDSCRIPT_START;
+ }
+ }
+ return C64_SYM_LDSCRIPT_DEF;
+ }
+ return C64_SYM_STANDARD;
+}
+
static bfd_reloc_status_type
c64_fixup_frag (bfd *input_bfd, struct bfd_link_info *info,
- bfd_reloc_code_real_type bfd_r_type, Elf_Internal_Sym *sym,
- struct elf_link_hash_entry *h, asection *sym_sec,
- bfd_byte *frag_loc, bfd_vma value, bfd_signed_vma addend)
+ Elf_Internal_Sym *sym, struct elf_link_hash_entry *h,
+ asection *sym_sec, bfd_byte *frag_loc, bfd_vma value,
+ bfd_signed_vma addend)
{
- bfd_vma size = 0;
+ BFD_ASSERT (h || sym);
+ bfd_vma size = sym ? sym->st_size : h->size;
asection *perm_sec = sym_sec;
bfd_boolean bounds_ok = FALSE;
- if (sym != NULL)
- {
- size = sym->st_size;
- if (size == 0)
- goto need_size;
- }
- else if (h != NULL)
+ if (size == 0 && sym_sec)
{
- size = h->size;
+ bounds_ok = TRUE;
+ enum c64_section_perm_type type
+ = c64_symbol_section_adjustment (h, value, sym_sec, &perm_sec, info);
- if (size == 0 && sym_sec != NULL)
+ switch (type)
{
- /* Linker defined symbols are always at the start of the section they
- track. */
- if (h->root.linker_def)
- {
- size = sym_sec->output_section->size;
- bounds_ok = TRUE;
- }
- else if (h->root.ldscript_def)
- {
- const char *name = h->root.root.string;
- size_t len = strlen (name);
-
- /* In the general case, the symbol should be able to access the
- entire output section following it. */
- size = sym_sec->size - (value - sym_sec->vma);
-
- /* The special case: the symbol is at the end of the section.
- This could either mean that it is an end symbol or it is the
- start of the output section following the symbol. We try to
- guess if it is a start of the next section by reading its
- name. This is a compatibility hack, ideally linker scripts
- should be written such that start symbols are defined within
- the output section it intends to track. */
- if (size == 0
- && (len > 8 && name[0] == '_' && name[1] == '_'
- && (!strncmp (name + 2, "start_", 6)
- || !strcmp (name + len - 6, "_start"))))
- {
- asection *s = bfd_sections_find_if (info->output_bfd,
- section_start_symbol,
- &value);
- if (s != NULL)
- {
- perm_sec = s;
- size = s->size;
- }
- }
- bounds_ok = TRUE;
- }
- else if (size == 0 && bfd_link_pic (info)
- && SYMBOL_REFERENCES_LOCAL (info, h))
- goto need_size;
+ case C64_SYM_STANDARD:
+ break;
+ case C64_SYM_LINKER_DEF:
+ size = perm_sec->output_section->size;
+ break;
+ case C64_SYM_LDSCRIPT_DEF:
+ size = perm_sec->size - (value - perm_sec->vma);
+ break;
+ case C64_SYM_LDSCRIPT_START:
+ size = perm_sec->size;
+ break;
+ default:
+ abort ();
}
}
if (addend < 0 || (bfd_vma) addend > size)
return bfd_reloc_outofrange;
- bfd_vma base = value + addend, limit = value + addend + size;
+ bfd_vma base = value, limit = value + size;
if (!bounds_ok && !c64_valid_cap_range (&base, &limit))
{
return bfd_reloc_notsupported;
}
+ if (perm_sec && perm_sec->flags & SEC_CODE)
+ {
+ /* Any symbol pointing into an executable section gets bounds according
+ to PCC. In this case the relocation is set up so that the value is
+ the base of the PCC, the addend is the offset from the PCC base to the
+ VA that we want, and the size is the length of the PCC range.
+ In this function we only use `value` to check the bounds make sense,
+ which is somewhat superfluous when we're using pcc_high and pcc_low
+ since we already enforced that in elfNN_c64_resize_sections. No harm
+ in instead checking that the bounds on the object that were requested
+ made sense even if they were overridden because this symbol points
+ into an executable section.
+
+ `size` on the other hand is part of the fragment that we output to and
+ we need to change it in order to have functions that can access global
+ data or jump to other functions. */
+ size = pcc_high - pcc_low;
+ }
+
if (perm_sec != NULL)
{
bfd_vma frag = cap_meta (size, perm_sec);
}
return bfd_reloc_continue;
+}
+
+/* Given either a local symbol SYM or global symbol H, do we need to adjust
+ capability relocations against the symbol due to the fact that it points to
+ a code section? */
+static bfd_boolean
+c64_symbol_adjust (struct elf_link_hash_entry *h,
+ bfd_vma value, asection *sym_sec, struct bfd_link_info *info,
+ bfd_vma *adjust_addr)
+{
+ asection *tmp_sec;
+ enum c64_section_perm_type type
+ = c64_symbol_section_adjustment (h, value, sym_sec, &tmp_sec, info);
+
+ if (type == C64_SYM_UNKNOWN)
+ return FALSE;
-need_size:
+ if (tmp_sec->flags & SEC_CODE)
{
- int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
- _bfd_error_handler
- /* xgettext:c-format */
- (_("%pB: relocation %s against local symbol without size info"),
- input_bfd, elfNN_aarch64_howto_table[howto_index].name);
- bfd_set_error (bfd_error_bad_value);
- return bfd_reloc_notsupported;
+ *adjust_addr = pcc_low;
+ return TRUE;
}
+
+ return FALSE;
}
/* Perform a relocation as part of a final link. The input relocation type
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 (signed_addend != 0)
+ {
+ int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: symbol plus addend can not be placed into the GOT "
+ "for relocation %s"),
+ input_bfd, elfNN_aarch64_howto_table[howto_index].name);
+ abort ();
+ }
+
if (base_got == NULL)
BFD_ASSERT (h != NULL);
if (h != NULL)
{
bfd_vma addend = 0;
+ bfd_vma frag_value;
/* If a symbol is not dynamic and is not undefined weak, bind it
locally and generate a RELATIVE relocation under PIC mode.
&& !symbol_got_offset_mark_p (input_bfd, h, r_symndx))
relative_reloc = TRUE;
+ if (c64_reloc
+ && c64_symbol_adjust (h, value, sym_sec, info, &frag_value))
+ signed_addend = (value | h->target_internal) - frag_value;
+ else
+ frag_value = value | h->target_internal;
+
value = aarch64_calculate_got_entry_vma (h, globals, info,
- value | h->target_internal,
+ frag_value,
output_bfd,
unresolved_reloc_p);
/* Record the GOT entry address which will be used when generating
if (!symbol_got_offset_mark_p (input_bfd, h, r_symndx))
{
- bfd_put_64 (output_bfd, value | sym->st_target_internal,
- base_got->contents + off);
+ bfd_vma frag_value;
+
+ if (c64_reloc
+ && c64_symbol_adjust (h, value, sym_sec, info, &frag_value))
+ signed_addend = (value | sym->st_target_internal) - frag_value;
+ else
+ frag_value = value | sym->st_target_internal;
+
+ bfd_put_64 (output_bfd, frag_value, 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
{
bfd_reloc_status_type ret;
- ret = c64_fixup_frag (input_bfd, info, bfd_r_type, sym, h,
+ ret = c64_fixup_frag (input_bfd, info, sym, h,
sym_sec, base_got->contents + off + 8,
orig_value, 0);
if (bfd_link_executable (info) && !bfd_link_pic (info))
s = globals->srelcaps;
- outrel.r_addend = 0;
+ outrel.r_addend = signed_addend;
}
else
outrel.r_addend = orig_value;
bfd_reloc_status_type ret;
- ret = c64_fixup_frag (input_bfd, info, bfd_r_type, sym, h, sym_sec,
+ ret = c64_fixup_frag (input_bfd, info, sym, h, sym_sec,
hit_data + 8, value, signed_addend);
if (ret != bfd_reloc_continue)
return ret;
outrel.r_addend = signed_addend;
+ value |= (h != NULL ? h->target_internal : sym->st_target_internal);
/* Emit a dynamic relocation if we are building PIC. */
if (h != NULL
else
outrel.r_info = ELFNN_R_INFO (0, MORELLO_R (RELATIVE));
- value |= (h != NULL ? h->target_internal : sym->st_target_internal);
+ /* Symbols without size information get bounds to the
+ whole section: adjust the base of the capability to the
+ start of the section and set the addend to obtain the
+ correct address for the symbol. */
+ bfd_vma new_value;
+ if (c64_symbol_adjust (h, value, sym_sec, info, &new_value))
+ {
+ outrel.r_addend += (value - new_value);
+ value = new_value;
+ }
asection *s = globals->srelcaps;
+2022-02-03 Alex Coplan <alex.coplan@arm.com>
+ Matthew Malcomson <matthew.malcomson@arm.com>
+
+ * 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.
+
2022-01-17 Alex Coplan <alex.coplan@arm.com>
* testsuite/ld-aarch64/aarch64-elf.exp: Add morello-weak-tls test.
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-relocs-morello-7"
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-sizeless-local-syms"
+run_dump_test_lp64 "morello-sizeless-global-syms"
+run_dump_test_lp64 "morello-sizeless-got-syms"
run_dump_test_lp64 "morello-capinit"
run_dump_test_lp64 "morello-stubs"
# 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.
+# Have tried to mitigate the flakyness of the test with a linker script that
+# aligns .text and the GOT to 12 bits so that the ldr addends are just offsets
+# into the GOT and we are likely to get .text at 0x1000.
#source: emit-relocs-morello-6.s
#as: -march=morello+c64
-#ld: -Ttext-segment 0x0 -pie -static
-#objdump: -DR -j .got -j .text
+#ld: -Ttext-segment 0x100000 -T emit-relocs-morello-7.ld -pie -static
+#objdump: -DR -j .got -j .text -j .data
.*: file format .*
Disassembly of section \.text:
-00000000000001e8 <_start>:
- 1e8: c240c400 ldr c0, \[c0, #784\]
- 1ec: c240c000 ldr c0, \[c0, #768\]
+0000000000100100 <_start>:
+ 100100: c2400c00 ldr c0, \[c0, #48\]
+ 100104: c2400800 ldr c0, \[c0, #32\]
+ 100108: c2401000 ldr c0, \[c0, #64\]
+ 10010c: c2400400 ldr c0, \[c0, #16\]
+
+Disassembly of section \.data:
+
+00000000001001e8 <data_obj>:
+ 1001e8: 0000000a .*
+
+00000000001001ec <data_func>:
+ 1001ec: 0000000a .*
Disassembly of section \.got:
-00000000000102f0 <\.got>:
- 102f0: 000101f0 \.inst 0x000101f0 ; undefined
+0000000000101000 <\.got>:
+ 101000: 00100000 .*
\.\.\.
- 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: .*
+ 101010: 001001ed .*
+ 101010: R_MORELLO_RELATIVE \*ABS\*
+ 101014: 00000000 .*
+ 101018: 00000402 .*
+ 10101c: 00000000 .*
+ 101020: 00100100 .*
+ 101020: R_MORELLO_RELATIVE \*ABS\*
+ 101024: 00000000 .*
+ 101028: 000f5001 .*
+ 10102c: 00000000 .*
+ 101030: 00100100 .*
+ 101030: R_MORELLO_RELATIVE \*ABS\*\+0x1
+ 101034: 00000000 .*
+ 101038: 000f5001 .*
+ 10103c: 00000000 .*
+ 101040: 001001e8 .*
+ 101040: R_MORELLO_RELATIVE \*ABS\*
+ 101044: 00000000 .*
+ 101048: 00000402 .*
+ 10104c: 00000000 .*
# - GOT fragment contains address required.
# - GOT fragment has LSB set if relocation is a function symbol.
.arch morello+c64
+
+ .data
+ .global data_obj
+data_obj:
+ .word 10
+ .size data_obj, .-data_obj
+
+ # Very odd to see, but still is nice to check we have internal consistency.
+ .type data_func,@function
+ .global data_func
+data_func:
+ .word 10
+ .size data_func, 4
+
.text
.global _start
ldr c0, [c0, :got_lo12:_start]
ldr c0, [c0, :got_lo12:obj]
+ ldr c0, [c0, :got_lo12:data_obj]
+ ldr c0, [c0, :got_lo12:data_func]
# 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
+#ld: -Ttext-segment 0x100000 -Temit-relocs-morello-7.ld -static
+#objdump: -D -j .rela.dyn -j .got -j .text -j .data
.*: file format .*
+Disassembly of section \.text:
+
+0000000000100000 <_start>:
+ 100000: c2400c00 ldr c0, \[c0, #48\]
+ 100004: c2400800 ldr c0, \[c0, #32\]
+ 100008: c2401000 ldr c0, \[c0, #64\]
+ 10000c: c2400400 ldr c0, \[c0, #16\]
+
Disassembly of section \.rela\.dyn:
-0000000000000000 <__rela_dyn_start>:
- 0: 00010060 .*
- 4: 00000000 .*
- 8: 0000e803 .*
+0000000000100010 <__rela_dyn_start>:
+ 100010: 00101030 .*
+ 100014: 00000000 .*
+ 100018: 0000e803 .*
+ 10001c: 00000000 .*
+ 100020: 00000001 .*
+ 100024: 00000000 .*
+ 100028: 00101020 .*
+ 10002c: 00000000 .*
+ 100030: 0000e803 .*
\.\.\.
- 18: 00010050 .*
- 1c: 00000000 .*
- 20: 0000e803 .*
+ 100040: 00101040 .*
+ 100044: 00000000 .*
+ 100048: 0000e803 .*
+ \.\.\.
+ 100058: 00101010 .*
+ 10005c: 00000000 .*
+ 100060: 0000e803 .*
\.\.\.
-Disassembly of section \.text:
+Disassembly of section \.data:
+
+0000000000100070 <data_obj>:
+ 100070: 0000000a .*
-0000000000000030 <_start>:
- 30: c2401800 ldr c0, \[c0, #96\]
- 34: c2401400 ldr c0, \[c0, #80\]
+0000000000100074 <data_func>:
+ 100074: 0000000a .*
Disassembly of section \.got:
-0000000000010040 <_GLOBAL_OFFSET_TABLE_>:
+0000000000101000 <_GLOBAL_OFFSET_TABLE_>:
\.\.\.
- 10050: 00000030 .*
- 10054: 00000000 .*
- 10058: 00000101 .*
- 1005c: 00000000 .*
- 10060: 00000031 .*
- 10064: 00000000 .*
- 10068: 00000c01 .*
- 1006c: 00000000 .*
+ 101010: 00100075 .*
+ 101014: 00000000 .*
+ 101018: 00000402 .*
+ 10101c: 00000000 .*
+ 101020: 00100000 .*
+ 101024: 00000000 .*
+ 101028: 00105001 .*
+ 10102c: 00000000 .*
+ 101030: 00100000 .*
+ 101034: 00000000 .*
+ 101038: 00105001 .*
+ 10103c: 00000000 .*
+ 101040: 00100070 .*
+ 101044: 00000000 .*
+ 101048: 00000402 .*
+ 10104c: 00000000 .*
--- /dev/null
+# Checking that the "compatibility hack" around symbols named with _start is
+# working.
+#
+# Use known offsets into the GOT. Have ensured that the GOT is 12bit aligned
+# in the linker script, which means we know that the lo12 relocations should
+# all have a known value (assuming a constant order of entries into the GOT).
+#
+# Need this since a large point of this test is to demonstrate that different
+# symbols with the same address end up having different valued relocations, so
+# we want to ensure a direct link between the relevant relocations and their
+# GOT entries.
+#
+# Point here is that the __text_start and __data_other symbols should end up
+# pointing into the text section, which should mean that they have PCC bounds
+# and their value includes an addend. These are the symbols used in the first
+# and last LDR's in the function.
+#
+# Meanwhile, the __text_other symbol should have bounds of everything remaining
+# in the section *before* it (which is nothing), and the __data_start symbol
+# should have bounds spanning the entire section *after* it (which is the data
+# section).
+#
+#source: emit-relocs-morello-7.s
+#as: -march=morello+c64
+#ld: -static -pie -T emit-relocs-morello-7.ld
+#objdump: -DR -j .text -j .data -j .got
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+.* <obj>:
+.*: c2400400 ldr c0, \[c0, #16\]
+.*: c2401000 ldr c0, \[c0, #64\]
+.*: c2400c00 ldr c0, \[c0, #48\]
+.*: c2400800 ldr c0, \[c0, #32\]
+
+Disassembly of section \.data:
+
+.* <\.data>:
+.*: 0000000a .*
+
+Disassembly of section \.got:
+
+0000000000001000 <\.got>:
+ 1000: 00000120 .*
+ \.\.\.
+ 1010: 000001e8 .*
+ 1010: R_MORELLO_RELATIVE \*ABS\*\+0x38
+ 1014: 00000000 .*
+ 1018: 000e6801 .*
+ 101c: 00000000 .*
+ 1020: 000001e8 .*
+ 1020: R_MORELLO_RELATIVE \*ABS\*\+0x48
+ 1024: 00000000 .*
+ 1028: 000e6801 .*
+ 102c: 00000000 .*
+ 1030: 00000230 .*
+ 1030: R_MORELLO_RELATIVE \*ABS\*
+ 1034: 00000000 .*
+ 1038: 00000d01 .*
+ 103c: 00000000 .*
+ 1040: 00000220 .*
+ 1040: R_MORELLO_RELATIVE \*ABS\*
+ 1044: 00000000 .*
+ 1048: 00000002 .*
+ 104c: 00000000 .*
+
--- /dev/null
+SECTIONS {
+ . = SEGMENT_START("text-segment", SIZEOF_HEADERS);
+ .dynamic : { *(.dynamic) }
+ .othersection : { *(.othersection) }
+ __text_start = .;
+ __text_other = .;
+ .text : { *(.text) }
+ __data_start = .;
+ __data_other = .;
+ .data : { *(.data) }
+ . = ALIGN(0x1000);
+ .got : { *(.got) }
+}
--- /dev/null
+# Want to test the special "compatibility hack" where we treat a linker script
+# defined symbol with a name of the form __.*_start or __start_.* which is at
+# the very end of a section as being at the *start* of the next section.
+#
+# This is required now that symbols have permissions and bounds according to
+# their section.
+# Checking LD128 relocations against a linker script defined symbol which
+# should get this compatibility hack (and some linker script defined symbols
+# that should not get the compatibility hack).
+.arch morello+c64
+ .section othersection,"aw"
+ .asciz "Hello there ;-)"
+ .data
+ .word 10
+ .text
+
+obj:
+
+ ldr c0, [c0, :got_lo12:__text_start]
+ ldr c0, [c0, :got_lo12:__text_other]
+ ldr c0, [c0, :got_lo12:__data_start]
+ ldr c0, [c0, :got_lo12:__data_other]
+# This testsuite is used largely to check our handling of linker script defined
+# symbols. In the general case we want to be able to access the entire output
+# section following this symbol (i.e. we treat this symbol as a start symbol).
+#
+# There is an exception for a symbol that points into an executable section --
+# we want this to have the bounds of the PCC as we see it.
+#
+# There is also an exception for a symbol which is *outside* of an output
+# section where we have a compatibility hack to try and guess whether it
+# represents the start of the next section or end of the previous section.
#source: morello-capinit.s
#as: -march=morello+c64
#ld: -static -pie -T morello-capinit.ld
-#objdump: -DR -j .data
+#objdump: -DR -j .inspectionsection
.*: file format .*
-Disassembly of section \.data:
+Disassembly of section \.inspectionsection:
[0-9a-f]+ <ct_outer_start>:
.*: [0-9a-f]+ .*
- .*: R_MORELLO_RELATIVE \*ABS\*
+ .*: R_MORELLO_RELATIVE \*ABS\*\+0x[0-9a-f]+
.*: 00000000 .*
-.*: 00000c01 .*
+.*: 00027001 .*
.*: 00000000 .*
[0-9a-f]+ <ct_start>:
.*: [0-9a-f]+ .*
- .*: R_MORELLO_RELATIVE \*ABS\*
+ .*: R_MORELLO_RELATIVE \*ABS\*\+0x[0-9a-f]+
.*: 00000000 .*
-.*: 00000c01 .*
+.*: 00027001 .*
.*: 00000000 .*
[0-9a-f]+ <ct1_start>:
.*: [0-9a-f]+ .*
- .*: R_MORELLO_RELATIVE \*ABS\*
+ .*: R_MORELLO_RELATIVE \*ABS\*\+0x[0-9a-f]+
.*: 00000000 .*
-.*: 00000801 .*
+.*: 00027001 .*
.*: 00000000 .*
[0-9a-f]+ <ct1_end>:
.*: [0-9a-f]+ .*
- .*: R_MORELLO_RELATIVE \*ABS\*
+ .*: R_MORELLO_RELATIVE \*ABS\*\+0x[0-9a-f]+
.*: 00000000 .*
-.*: 00000401 .*
+.*: 00027001 .*
.*: 00000000 .*
[0-9a-f]+ <ct_end>:
+.*: [0-9a-f]+ .*
+ .*: R_MORELLO_RELATIVE \*ABS\*\+0x[0-9a-f]+
+.*: 00000000 .*
+.*: 00027001 .*
+.*: 00000000 .*
+
+[0-9a-f]+ <cd_outer_start>:
+.*: [0-9a-f]+ .*
+ .*: R_MORELLO_RELATIVE \*ABS\*
+.*: 00000000 .*
+.*: 00000c02 .*
+.*: 00000000 .*
+
+[0-9a-f]+ <cd_start>:
+.*: [0-9a-f]+ .*
+ .*: R_MORELLO_RELATIVE \*ABS\*
+.*: 00000000 .*
+.*: 00000c02 .*
+.*: 00000000 .*
+
+[0-9a-f]+ <cd1_start>:
+.*: [0-9a-f]+ .*
+ .*: R_MORELLO_RELATIVE \*ABS\*
+.*: 00000000 .*
+.*: 00000802 .*
+.*: 00000000 .*
+
+[0-9a-f]+ <cd1_end>:
+.*: [0-9a-f]+ .*
+ .*: R_MORELLO_RELATIVE \*ABS\*
+.*: 00000000 .*
+.*: 00000402 .*
+.*: 00000000 .*
+
+[0-9a-f]+ <cd_end>:
.*: [0-9a-f]+ .*
.*: R_MORELLO_RELATIVE \*ABS\*
.*: 00000000 .*
-.*: 00000001 .*
+.*: 00000002 .*
.*: 00000000 .*
[0-9a-f]+ <cdynamic>:
.plt : { *(.plt) }
.got : { *(.got) }
.got : { *(.got) }
- .data : { *(.data) }
+ __outer_data_start = .;
+ .data_total :
+ {
+ data_start = .;
+ *(.data)
+ data1_start = .;
+ *(.data.1)
+ data1_end = .;
+ *(.data.2)
+ __data_end = .;
+ }
+ .inspectionsection : { *(.inspectionsection) }
}
.data
+obj1:
+ .4byte 0
+.section .data.1
+obj2:
+ .4byte 0
+.section .data.2
+obj3:
+ .4byte 0
+.section .inspectionsection,"aw"
.align 4
ct_outer_start:
.capinit __outer_text_start
.capinit __text_end
.8byte 0
.8byte 0
+cd_outer_start:
+ .capinit __outer_data_start
+ .8byte 0
+ .8byte 0
+cd_start:
+ .capinit data_start
+ .8byte 0
+ .8byte 0
+cd1_start:
+ .capinit data1_start
+ .8byte 0
+ .8byte 0
+cd1_end:
+ .capinit data1_end
+ .8byte 0
+ .8byte 0
+cd_end:
+ .capinit __data_end
+ .8byte 0
+ .8byte 0
cdynamic:
.capinit _DYNAMIC
.8byte 0
--- /dev/null
+#source: morello-sizeless-global-syms.s
+#as: -march=morello+c64
+#ld: -static -pie
+#objdump: -DRz -j .data -j .bss
+
+.*: file format elf64-littleaarch64
+
+
+Disassembly of section \.data:
+
+[0-9a-f]+ <ptr3>:
+ [0-9a-f]+: 00010440.*
+ [0-9a-f]+: R_MORELLO_RELATIVE \*ABS\*
+ [0-9a-f]+: 00000000.*
+ [0-9a-f]+: 00000002.*
+ [0-9a-f]+: 00000000.*
+
+[0-9a-f]+ <ptr2>:
+ [0-9a-f]+: 00010444.*
+ [0-9a-f]+: R_MORELLO_RELATIVE \*ABS\*
+ [0-9a-f]+: 00000000.*
+ [0-9a-f]+: 00000002.*
+ [0-9a-f]+: 00000000.*
+
+[0-9a-f]+ <ptr1>:
+ [0-9a-f]+: 00010448.*
+ [0-9a-f]+: R_MORELLO_RELATIVE \*ABS\*
+ [0-9a-f]+: 00000000.*
+ [0-9a-f]+: 00000002.*
+ [0-9a-f]+: 00000000.*
+
+Disassembly of section .bss:
+
+0000000000010440 <baz>:
+ [0-9a-f]+: 00000000.*
+
+[0-9a-f]+ <bar>:
+ [0-9a-f]+: 00000000.*
+
+[0-9a-f]+ <foo>:
+ [0-9a-f]+: 00000000.*
+ [0-9a-f]+: 00000000.*
--- /dev/null
+ .arch morello+crc+c64
+ .file "global.c"
+ .text
+ .align 2
+ .global _start
+ .type _start, %function
+_start:
+ adrp c0, :got:ptr1
+ ldr c0, [c0, #:got_lo12:ptr1]
+ ldr c2, [c0]
+ adrp c0, :got:ptr2
+ ldr c0, [c0, #:got_lo12:ptr2]
+ ldr c6, [c0]
+ adrp c0, :got:ptr3
+ ldr c0, [c0, #:got_lo12:ptr3]
+ ldr c4, [c0]
+ ldr w0, [c6]
+ ldr w1, [c4]
+ add w0, w0, w1
+ str w0, [c2]
+ ret
+ .size _start, .-_start
+ .global ptr3
+ .global ptr2
+ .global ptr1
+ .global baz
+ .global bar
+ .global foo
+ .bss
+ .align 2
+ .type baz, %object
+baz:
+ .zero 4
+ .type bar, %object
+bar:
+ .zero 4
+ .type foo, %object
+foo:
+ .zero 4
+ .section .data.rel.local,"aw"
+ .align 4
+ .type ptr3, %object
+ .size ptr3, 16
+ptr3:
+ .capinit baz
+ .xword 0
+ .xword 0
+ .type ptr2, %object
+ .size ptr2, 16
+ptr2:
+ .capinit bar
+ .xword 0
+ .xword 0
+ .type ptr1, %object
+ .size ptr1, 16
+ptr1:
+ .capinit foo
+ .xword 0
+ .xword 0
+ .ident "GCC: (unknown) 11.0.0 20200826 (experimental)"
--- /dev/null
+#source: morello-sizeless-got-syms.s
+#as: -march=morello+c64
+#ld: -static -pie
+#objdump: -DRz -j .text -j .got -j .bss
+
+.*: file format elf64-littleaarch64
+
+Disassembly of section \.text:
+
+[0-9a-f]+ <get_foo>:
+ [0-9a-f]+: 90800080 adrp c0, 10000 .*
+ [0-9a-f]+: c240d800 ldr c0, \[c0, #864\]
+ [0-9a-f]+: c2c253c0 ret c30
+
+[0-9a-f]+ <get_bar>:
+ [0-9a-f]+: 90800080 adrp c0, 10000 .*
+ [0-9a-f]+: c240dc00 ldr c0, \[c0, #880\]
+ [0-9a-f]+: c2c253c0 ret c30
+
+[0-9a-f]+ <get_baz>:
+ [0-9a-f]+: 90800080 adrp c0, 10000 .*
+ [0-9a-f]+: c240d400 ldr c0, \[c0, #848\]
+ [0-9a-f]+: c2c253c0 ret c30
+
+[0-9a-f]+ <_start>:
+.*
+
+Disassembly of section \.got:
+
+0000000000010340 <\.got>:
+ [0-9a-f]+: .*
+ [0-9a-f]+: .*
+ [0-9a-f]+: .*
+ [0-9a-f]+: .*
+ [0-9a-f]+: 000103b0 .*
+ [0-9a-f]+: R_MORELLO_RELATIVE \*ABS\*
+ [0-9a-f]+: 00000000 .*
+ [0-9a-f]+: 00000002 .*
+ [0-9a-f]+: 00000000 .*
+ [0-9a-f]+: 000103b8 .*
+ [0-9a-f]+: R_MORELLO_RELATIVE \*ABS\*
+ [0-9a-f]+: 00000000 .*
+ [0-9a-f]+: 00000002 .*
+ [0-9a-f]+: 00000000 .*
+ [0-9a-f]+: 000103b4 .*
+ [0-9a-f]+: R_MORELLO_RELATIVE \*ABS\*
+ [0-9a-f]+: 00000000 .*
+ [0-9a-f]+: 00000002 .*
+ [0-9a-f]+: 00000000 .*
+
+Disassembly of section .bss:
+
+00000000000103b0 <baz>:
+ [0-9a-f]+: 00000000 .*
+
+[0-9a-f]+ <bar>:
+ [0-9a-f]+: 00000000 .*
+
+[0-9a-f]+ <foo>:
+ [0-9a-f]+: 00000000 .*
+ [0-9a-f]+: 00000000 .*
--- /dev/null
+ .arch morello+crc+c64
+ .file "got.c"
+ .text
+ .align 2
+ .global get_foo
+ .type get_foo, %function
+get_foo:
+ adrp c0, :got:foo
+ ldr c0, [c0, #:got_lo12:foo]
+ ret
+ .size get_foo, .-get_foo
+ .align 2
+ .global get_bar
+ .type get_bar, %function
+get_bar:
+ adrp c0, :got:bar
+ ldr c0, [c0, #:got_lo12:bar]
+ ret
+ .size get_bar, .-get_bar
+ .align 2
+ .global get_baz
+ .type get_baz, %function
+get_baz:
+ adrp c0, :got:baz
+ ldr c0, [c0, #:got_lo12:baz]
+ ret
+ .size get_baz, .-get_baz
+ .align 2
+ .global _start
+ .type _start, %function
+_start:
+ ret
+ .size _start, .-_start
+ .global baz
+ .global bar
+ .global foo
+ .bss
+ .align 2
+ .type baz, %object
+baz:
+ .zero 4
+ .type bar, %object
+bar:
+ .zero 4
+ .type foo, %object
+foo:
+ .zero 4
+ .ident "GCC: (unknown) 11.0.0 20200826 (experimental)"
--- /dev/null
+#source: morello-sizeless-local-syms.s
+#as: -march=morello+c64
+#ld: -static -pie
+#objdump: -DRz -j .data -j .bss
+
+.*: file format elf64-littleaarch64
+
+
+Disassembly of section .data:
+
+[0-9a-f]+ <ptr3>:
+ [0-9a-f]+: 00010440.*
+ [0-9a-f]+: R_MORELLO_RELATIVE \*ABS\*
+ [0-9a-f]+: 00000000.*
+ [0-9a-f]+: 00000002.*
+ [0-9a-f]+: 00000000.*
+
+[0-9a-f]+ <ptr2>:
+ [0-9a-f]+: 00010444.*
+ [0-9a-f]+: R_MORELLO_RELATIVE \*ABS\*
+ [0-9a-f]+: 00000000.*
+ [0-9a-f]+: 00000002.*
+ [0-9a-f]+: 00000000.*
+
+[0-9a-f]+ <ptr1>:
+ [0-9a-f]+: 00010448.*
+ [0-9a-f]+: R_MORELLO_RELATIVE \*ABS\*
+ [0-9a-f]+: 00000000.*
+ [0-9a-f]+: 00000002.*
+ [0-9a-f]+: 00000000.*
+
+Disassembly of section .bss:
+
+0000000000010440 <baz>:
+ [0-9a-f]+: 00000000.*
+
+[0-9a-f]+ <bar>:
+ [0-9a-f]+: 00000000.*
+
+[0-9a-f]+ <foo>:
+ [0-9a-f]+: 00000000.*
+ [0-9a-f]+: 00000000.*
--- /dev/null
+ .arch morello+crc+c64
+ .file "local.c"
+ .text
+ .align 2
+ .global _start
+ .type _start, %function
+_start:
+ adrp c0, :got:ptr1
+ ldr c0, [c0, #:got_lo12:ptr1]
+ ldr c2, [c0]
+ adrp c0, :got:ptr2
+ ldr c0, [c0, #:got_lo12:ptr2]
+ ldr c6, [c0]
+ adrp c0, :got:ptr3
+ ldr c0, [c0, #:got_lo12:ptr3]
+ ldr c4, [c0]
+ ldr w0, [c6]
+ ldr w1, [c4]
+ add w0, w0, w1
+ str w0, [c2]
+ ret
+ .size _start, .-_start
+ .global ptr3
+ .global ptr2
+ .global ptr1
+ .bss
+ .align 2
+ .type baz, %object
+baz:
+ .zero 4
+ .type bar, %object
+bar:
+ .zero 4
+ .type foo, %object
+foo:
+ .zero 4
+ .section .data.rel.local,"aw"
+ .align 4
+ .type ptr3, %object
+ .size ptr3, 16
+ptr3:
+ .capinit baz
+ .xword 0
+ .xword 0
+ .type ptr2, %object
+ .size ptr2, 16
+ptr2:
+ .capinit bar
+ .xword 0
+ .xword 0
+ .type ptr1, %object
+ .size ptr1, 16
+ptr1:
+ .capinit foo
+ .xword 0
+ .xword 0
+ .ident "GCC: (unknown) 11.0.0 20200826 (experimental)"