From: Alex Coplan Date: Thu, 3 Feb 2022 08:59:49 +0000 (+0000) Subject: ld: Adjust bounds, base, and size for various symbols X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7df44b98ae8717adb7c20715ede7d6248e6de690;p=thirdparty%2Fbinutils-gdb.git ld: Adjust bounds, base, and size for various symbols This patch has two main goals: - Relax an existing diagnostic to permit the linker to accept capability relocations against symbols without size information. - Adjust the capability base and bounds for symbols which point into sections which may be accessed via the PCC. The Morello ABI accesses global data using ADR and ADRP, and has no special indirection to jump to other functions. Given this, the PCC must maintain its bounds and base so that during execution loading global data and jumping to other functions can be done without worrying about the current PCC permissions and bounds. To implement this, all capabilities that could be loaded into the PCC (via BLR or similar) must have a bounds and base according to the PCC. This must span all global data and text sections (i.e. .got, .text, .got.plt and the like). There is already code finding the range that the PCC should span, this patch records the information in a variable that we can query later. There are two places where we create a relocation requesting a capability to be initialised at runtime. When handling relocations which request a capability from the GOT, and when handling a CAPINIT relocation. This patch adjusts both. We can't tell from inspection which symbols would be loaded into the PCC, but we know that those symbols must point into a section which is executable. For now, we do this operation for all symbols which point into an executable section. Most RELATIVE relocations don't use the addend. Rather the VA and size we want are put in the relative fragment and the addend is zero. This is because the *base* of the capability usually matches the VA we want that capability initialised to. In these possibly-code symbols we want the base of the capability bounds to be the base of the PCC, and the VA to be something very different. Hence we make use of the addend in the RELA relocations to encode this offset. Note on implementation: c64_fixup_frag takes the base and size of a capability we want to request from the runtime and checks that these are exactly representable in a capability. This patch changes many of the capabilities we request from the runtime to have the same bounds (those of the PCC). We leave the check to look at the bounds requested by the symbol rather than to check the PCC bounds multiple times. That means that if a symbol that points into an executable section has incorrect bounds then this will trigger a linker error even though it will cause no security problem when this executes. This is a trade-off between getting extra checks that the compiler is handling object bounds sizes and erroring on non-problematic code. We have a compatibility hack that if a symbol is defined in the linker script to be directly after a given section but is *named* something like __.*_start or __start_.* then we treat it as if it is defined at the very start of the next section. The new behaviour introduced in this patch needs to take account of the above compatibility hack. This patch also updates the testsuite according to these changes. In some places the original test no longer checks what it wanted, since the base of all symbols pointing into executable sections are now the same. There we add extra symbols and things to check so we ensure that this behaviour of PCC bounds is seen and that the original behaviour is still seen on non-executable sections. This commit also includes a few tidy-ups: We adjust the base and limit that are checked in c64_fixup_frag. Originally this would calculate the base as value + addend. As discussed above the way we treat capabilities in Morello is such that the value determines the base and the addend determines the initial value pointing from that base. Hence the check that these capabilities had correct bounds was not correct. We add an extra assertion in final_link_relocate for robustness purposes. There is an existing bug in the assembler where GOT relocations against local symbols can be turned into relocations against the relevant section symbol plus an addend. This is problematic for multiple reasons, one being that the linker implementation does not have any way to associate different GOT entries with the same symbol but multiple offsets. In fact the linker ignores any offset. Here we simply add an assertion that this never happens. It turns a silent pre-existing error into a noisy one. 2022-02-03 Alex Coplan Matthew Malcomson 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. Co-authored-by: Matthew Malcomson --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 9d9224b285b..476e3a9d022 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,17 @@ +2022-02-03 Alex Coplan + Matthew Malcomson + + * 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 * elfnn-aarch64.c (elfNN_aarch64_relocate_section): Skip over TLS diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 9a3d6703a8a..96ac304b0b6 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. @@ -6377,70 +6387,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; bool 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 (); } } @@ -6448,7 +6482,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)) { @@ -6459,6 +6493,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); @@ -6470,17 +6523,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 bool +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 @@ -7080,10 +7146,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; + bool 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); @@ -7091,6 +7169,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. @@ -7111,8 +7190,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 @@ -7149,8 +7234,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 @@ -7192,7 +7284,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); @@ -7204,7 +7296,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; @@ -7397,13 +7489,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 @@ -7414,7 +7507,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/ChangeLog b/ld/ChangeLog index d471efb85c1..782e282933a 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,23 @@ +2022-02-03 Alex Coplan + Matthew Malcomson + + * 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 * testsuite/ld-aarch64/aarch64-elf.exp: Add morello-weak-tls test. diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp index 333251577ea..1aeb932df45 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)"