diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 45f0782db80..c35d1e42833 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -4884,6 +4884,8 @@ record_section_change (asection *sec, struct sec_change_queue **queue) 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), @@ -5052,8 +5054,8 @@ elfNN_c64_resize_sections (bfd *output_bfd, struct bfd_link_info *info, /* 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)) { @@ -5073,6 +5075,14 @@ elfNN_c64_resize_sections (bfd *output_bfd, struct bfd_link_info *info, 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. @@ -6374,70 +6384,94 @@ cap_meta (size_t size, const asection *sec) 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 (); } } @@ -6445,7 +6479,7 @@ c64_fixup_frag (bfd *input_bfd, struct bfd_link_info *info, 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)) { @@ -6456,6 +6490,25 @@ c64_fixup_frag (bfd *input_bfd, struct bfd_link_info *info, 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); @@ -6467,17 +6520,30 @@ c64_fixup_frag (bfd *input_bfd, struct bfd_link_info *info, } 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 @@ -7077,10 +7143,22 @@ 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 (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); @@ -7088,6 +7166,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, 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. @@ -7108,8 +7187,14 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, && !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 @@ -7146,8 +7231,15 @@ 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 | 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 @@ -7189,7 +7281,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, { 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); @@ -7201,7 +7293,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, 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; @@ -7394,13 +7486,14 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, 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 @@ -7411,7 +7504,16 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, 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; diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp index ea8ab347b12..c40eba95942 100644 --- a/ld/testsuite/ld-aarch64/aarch64-elf.exp +++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp @@ -248,9 +248,13 @@ 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-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" diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-6.d b/ld/testsuite/ld-aarch64/emit-relocs-morello-6.d index d97a59a916b..e41e42ed5ff 100644 --- a/ld/testsuite/ld-aarch64/emit-relocs-morello-6.d +++ b/ld/testsuite/ld-aarch64/emit-relocs-morello-6.d @@ -5,17 +5,13 @@ # 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 .* @@ -23,22 +19,42 @@ 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 : + 1001e8: 0000000a .* + +00000000001001ec : + 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 .* diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-6.s b/ld/testsuite/ld-aarch64/emit-relocs-morello-6.s index eafc9968c52..779a7a422e2 100644 --- a/ld/testsuite/ld-aarch64/emit-relocs-morello-6.s +++ b/ld/testsuite/ld-aarch64/emit-relocs-morello-6.s @@ -4,6 +4,20 @@ # - 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 @@ -18,3 +32,5 @@ obj: 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] diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-6b.d b/ld/testsuite/ld-aarch64/emit-relocs-morello-6b.d index 3d2ca260156..943b339a6d1 100644 --- a/ld/testsuite/ld-aarch64/emit-relocs-morello-6b.d +++ b/ld/testsuite/ld-aarch64/emit-relocs-morello-6b.d @@ -17,40 +17,68 @@ # 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 : + 100070: 0000000a .* -0000000000000030 <_start>: - 30: c2401800 ldr c0, \[c0, #96\] - 34: c2401400 ldr c0, \[c0, #80\] +0000000000100074 : + 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 .* diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-7.d b/ld/testsuite/ld-aarch64/emit-relocs-morello-7.d new file mode 100644 index 00000000000..69913f8c573 --- /dev/null +++ b/ld/testsuite/ld-aarch64/emit-relocs-morello-7.d @@ -0,0 +1,69 @@ +# 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: + +.* : +.*: 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 .* + diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-7.ld b/ld/testsuite/ld-aarch64/emit-relocs-morello-7.ld new file mode 100644 index 00000000000..1402e98ef08 --- /dev/null +++ b/ld/testsuite/ld-aarch64/emit-relocs-morello-7.ld @@ -0,0 +1,13 @@ +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) } +} diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-7.s b/ld/testsuite/ld-aarch64/emit-relocs-morello-7.s new file mode 100644 index 00000000000..3ed82287423 --- /dev/null +++ b/ld/testsuite/ld-aarch64/emit-relocs-morello-7.s @@ -0,0 +1,22 @@ +# 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] diff --git a/ld/testsuite/ld-aarch64/morello-capinit.d b/ld/testsuite/ld-aarch64/morello-capinit.d index d4a25e3b66b..9035351d215 100644 --- a/ld/testsuite/ld-aarch64/morello-capinit.d +++ b/ld/testsuite/ld-aarch64/morello-capinit.d @@ -1,46 +1,91 @@ +# 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]+ : .*: [0-9a-f]+ .* - .*: R_MORELLO_RELATIVE \*ABS\* + .*: R_MORELLO_RELATIVE \*ABS\*\+0x[0-9a-f]+ .*: 00000000 .* -.*: 00000c01 .* +.*: 00027001 .* .*: 00000000 .* [0-9a-f]+ : .*: [0-9a-f]+ .* - .*: R_MORELLO_RELATIVE \*ABS\* + .*: R_MORELLO_RELATIVE \*ABS\*\+0x[0-9a-f]+ .*: 00000000 .* -.*: 00000c01 .* +.*: 00027001 .* .*: 00000000 .* [0-9a-f]+ : .*: [0-9a-f]+ .* - .*: R_MORELLO_RELATIVE \*ABS\* + .*: R_MORELLO_RELATIVE \*ABS\*\+0x[0-9a-f]+ .*: 00000000 .* -.*: 00000801 .* +.*: 00027001 .* .*: 00000000 .* [0-9a-f]+ : .*: [0-9a-f]+ .* - .*: R_MORELLO_RELATIVE \*ABS\* + .*: R_MORELLO_RELATIVE \*ABS\*\+0x[0-9a-f]+ .*: 00000000 .* -.*: 00000401 .* +.*: 00027001 .* .*: 00000000 .* [0-9a-f]+ : +.*: [0-9a-f]+ .* + .*: R_MORELLO_RELATIVE \*ABS\*\+0x[0-9a-f]+ +.*: 00000000 .* +.*: 00027001 .* +.*: 00000000 .* + +[0-9a-f]+ : +.*: [0-9a-f]+ .* + .*: R_MORELLO_RELATIVE \*ABS\* +.*: 00000000 .* +.*: 00000c02 .* +.*: 00000000 .* + +[0-9a-f]+ : +.*: [0-9a-f]+ .* + .*: R_MORELLO_RELATIVE \*ABS\* +.*: 00000000 .* +.*: 00000c02 .* +.*: 00000000 .* + +[0-9a-f]+ : +.*: [0-9a-f]+ .* + .*: R_MORELLO_RELATIVE \*ABS\* +.*: 00000000 .* +.*: 00000802 .* +.*: 00000000 .* + +[0-9a-f]+ : +.*: [0-9a-f]+ .* + .*: R_MORELLO_RELATIVE \*ABS\* +.*: 00000000 .* +.*: 00000402 .* +.*: 00000000 .* + +[0-9a-f]+ : .*: [0-9a-f]+ .* .*: R_MORELLO_RELATIVE \*ABS\* .*: 00000000 .* -.*: 00000001 .* +.*: 00000002 .* .*: 00000000 .* [0-9a-f]+ : diff --git a/ld/testsuite/ld-aarch64/morello-capinit.ld b/ld/testsuite/ld-aarch64/morello-capinit.ld index 4a73401b839..977b7e83be0 100644 --- a/ld/testsuite/ld-aarch64/morello-capinit.ld +++ b/ld/testsuite/ld-aarch64/morello-capinit.ld @@ -15,5 +15,16 @@ SECTIONS { .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) } } diff --git a/ld/testsuite/ld-aarch64/morello-capinit.s b/ld/testsuite/ld-aarch64/morello-capinit.s index e2bbdbc4441..b700533e7a9 100644 --- a/ld/testsuite/ld-aarch64/morello-capinit.s +++ b/ld/testsuite/ld-aarch64/morello-capinit.s @@ -1,4 +1,13 @@ .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 @@ -20,6 +29,26 @@ ct_end: .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 diff --git a/ld/testsuite/ld-aarch64/morello-sizeless-global-syms.d b/ld/testsuite/ld-aarch64/morello-sizeless-global-syms.d new file mode 100644 index 00000000000..5765c204366 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-sizeless-global-syms.d @@ -0,0 +1,42 @@ +#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]+ : + [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]+ : + [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]+ : + [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 : + [0-9a-f]+: 00000000.* + +[0-9a-f]+ : + [0-9a-f]+: 00000000.* + +[0-9a-f]+ : + [0-9a-f]+: 00000000.* + [0-9a-f]+: 00000000.* diff --git a/ld/testsuite/ld-aarch64/morello-sizeless-global-syms.s b/ld/testsuite/ld-aarch64/morello-sizeless-global-syms.s new file mode 100644 index 00000000000..42a582dce9f --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-sizeless-global-syms.s @@ -0,0 +1,60 @@ + .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)" diff --git a/ld/testsuite/ld-aarch64/morello-sizeless-got-syms.d b/ld/testsuite/ld-aarch64/morello-sizeless-got-syms.d new file mode 100644 index 00000000000..7c5276b3c5f --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-sizeless-got-syms.d @@ -0,0 +1,61 @@ +#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]+ : + [0-9a-f]+: 90800080 adrp c0, 10000 .* + [0-9a-f]+: c240d800 ldr c0, \[c0, #864\] + [0-9a-f]+: c2c253c0 ret c30 + +[0-9a-f]+ : + [0-9a-f]+: 90800080 adrp c0, 10000 .* + [0-9a-f]+: c240dc00 ldr c0, \[c0, #880\] + [0-9a-f]+: c2c253c0 ret c30 + +[0-9a-f]+ : + [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 : + [0-9a-f]+: 00000000 .* + +[0-9a-f]+ : + [0-9a-f]+: 00000000 .* + +[0-9a-f]+ : + [0-9a-f]+: 00000000 .* + [0-9a-f]+: 00000000 .* diff --git a/ld/testsuite/ld-aarch64/morello-sizeless-got-syms.s b/ld/testsuite/ld-aarch64/morello-sizeless-got-syms.s new file mode 100644 index 00000000000..3f3883176b4 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-sizeless-got-syms.s @@ -0,0 +1,48 @@ + .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)" diff --git a/ld/testsuite/ld-aarch64/morello-sizeless-local-syms.d b/ld/testsuite/ld-aarch64/morello-sizeless-local-syms.d new file mode 100644 index 00000000000..30a7823bb65 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-sizeless-local-syms.d @@ -0,0 +1,42 @@ +#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]+ : + [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]+ : + [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]+ : + [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 : + [0-9a-f]+: 00000000.* + +[0-9a-f]+ : + [0-9a-f]+: 00000000.* + +[0-9a-f]+ : + [0-9a-f]+: 00000000.* + [0-9a-f]+: 00000000.* diff --git a/ld/testsuite/ld-aarch64/morello-sizeless-local-syms.s b/ld/testsuite/ld-aarch64/morello-sizeless-local-syms.s new file mode 100644 index 00000000000..64ac5ccd806 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-sizeless-local-syms.s @@ -0,0 +1,57 @@ + .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)"