Originally we believed we had accounted for these symbols within the existing if conditional. It turns out that with `-pie --no-dynamic-linker` on the command line (which causes the `link_info` member `dynamic_undefined_weak` to be set to 0) such symbols can bypass elfNN_aarch64_allocate_dynrelocs putting these symbols into the dynamic symbol table. Hence we can have such symbols without a dynamic index and our existing conditionals need to be adjusted.
On further inspection we notice that GOT entries for *hidden* undefined weak symbols were still getting RELATIVE relocations. This is quite unnecessary since it's known that the entry should be the NULL capability, but on top of that it relies on the runtime to have a special case to not add the load displacement to RELATIVE relocations with completely zero fragments.
We make two logical adjustments. The first is that in our handling of CAPINIT relocations we add a clause to avoid emitting a relocation for any undefined weak symbol which we know for certain should end up with the NULL capability at runtime. In this clause we ensure that the fragment is completely zero.
The second is around handling GOT entries. For these we ensure that elfNN_aarch64_allocate_dynrelocs does not allocate a dynamic relocation for the GOT entry of such symbols and that elfNN_aarch64_final_link_relocate leaves the GOT entry empty and without any relocation.
N.b. in implementing this change the conditionals became quite confusing. We split them up quite unnecessarily into different else/if statements for clarity at the expense of verbosity.
We also add tests to check the behaviour of undefined weak symbols for dynamically linked PDE's/PIE's/static executables/shared objects.
N.b.2 We also add an extra assert in final_link_relocate. This function deals with GOT entries for symbols both in the internal hash table and not in the hash table. Binutils decides whether symbols should be in the hash table or not based on their binding. WEAK binding symbols are put in the hash table. That said, final_link_relocate has a `weak_undef_p` local flag to describe whether a given symbol is weak undefined or not. This flag is defined for both symbols in the hash table and symbols not in the hash table.
I believe that the only time we have weak_undef_p set in final_link_relocate when the relevant symbol is not in the hash table is when we have "removed" a relocation from our work list by modifying it to be a R_AARCH64_NONE relocation against the STN_UNDEF symbol (e.g. during TLS relaxation).
Such cases would not fall into the GOT relocation clause. Hence I don't think we can ever see weak_undef_p symbols which are not in the hash table in this clause. It's worth an assertion to catch the possibility that this is wrong.
############### Attachment also inlined for ease of reply ###############
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index dd1c28ad7e4352d9407b1b7a1d863a0cb293a9a4..68c88bce0b475a6af2097c3993f9a5753a774fdb 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -292,6 +292,16 @@ (((htab)->root.srelplt == NULL) ? 0 \ : (htab)->root.srelplt->reloc_count * GOT_ENTRY_SIZE (htab))
+/* The only time that we want the value of a symbol but do not want a + relocation for it in Morello is when that symbol is undefined weak. In this + case we just need the zero capability and there's no point emitting a + relocation for it when we can get an untagged zero capability by just + loading some zeros. */ +#define c64_needs_relocation(info, h) \ + (!((h)->root.type == bfd_link_hash_undefweak \ + && (UNDEFWEAK_NO_DYNAMIC_RELOC ((info), (h)) \ + || !elf_hash_table ((info))->dynamic_sections_created))) + /* The first entry in a procedure linkage table looks like this if the distance between the PLTGOT and the PLT is < 4GB use these PLT entries. Note that the dynamic linker gets &PLTGOT[2] @@ -7240,58 +7250,61 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
NOTE: one symbol may be referenced by several relocations, we should only generate one RELATIVE relocation for that symbol. - Therefore, check GOT offset mark first. - - NOTE2: Symbol references via GOT in C64 should always have - relocations of some kind. Here we try to catch any such GOT - reference which would not otherwise be caught by - finish_dynamic_symbol. */ - if (((h->dynindx == -1 - && !h->forced_local - && h->root.type != bfd_link_hash_undefweak - && bfd_link_pic (info)) - || (!bfd_link_pic (info) - && !WILL_CALL_FINISH_DYNAMIC_SYMBOL - (is_dynamic, bfd_link_pic (info), h) - && bfd_link_executable (info) && c64_reloc)) + Therefore, check GOT offset mark first. */ + if (h->dynindx == -1 + && !h->forced_local + && h->root.type != bfd_link_hash_undefweak + && bfd_link_pic (info) && !symbol_got_offset_mark_p (input_bfd, h, r_symndx)) { - /* If we would call finish_dynamic_symbol for this symbol then we - should not be introducing a relocation for the GOT entry - (that function handles creating relocations for the GOT entry - in the usual case, this bit of code is to handle special - cases where the relocation would not otherwise be generated). - */ + /* Here we look for symbols which are not going to have their + relocations added by finish_dynamic_symbol, but which still + need a dynamic relocation because we're compiling for PIC. + + Action on this clause and the one below is the same. + Written that way to make the three different cases and their + interpretation clear. */ BFD_ASSERT (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dynamic, bfd_link_pic (info), h)); relative_reloc = TRUE; c64_needs_frag_fixup = c64_reloc ? TRUE : FALSE; } - /* If this is a dynamic symbol that binds locally then the generic - code and elfNN_aarch64_finish_dynamic_symbol will already handle - creating the RELATIVE reloc pointing into the GOT for this symbol. - That means that this function does not need to handle *creating* - such a relocation. This function does already handle setting the - base value as the fragment for that relocation, hence we should - ensure that we set the fragment correctly for C64 code (i.e. - including the required permissions and bounds). */ - else if (c64_reloc - && WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dynamic, - bfd_link_pic (info), h) + else if (!c64_reloc || !c64_needs_relocation (info, h)) + { + /* Symbol references via GOT in C64 should always have + relocations of some kind unless they are undefined weak + symbols which cannot be provided at runtime. In those cases + we need a plain zero. + + This clause catches the case when we're not relocating for + GOT, or when we're relocating an undefined weak symbol. */ + } + else if (!bfd_link_pic (info) + && !WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dynamic, + bfd_link_pic (info), h) + && bfd_link_executable (info) + && !symbol_got_offset_mark_p (input_bfd, h, r_symndx)) + { + /* This clause is here to catch any c64 entries in the GOT which + need a relocation, but whose relocation will not be provided + by finish_dynamic_symbol. */ + relative_reloc = TRUE; + c64_needs_frag_fixup = TRUE; + } + else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dynamic, + bfd_link_pic (info), h) && bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h)) { - /* We believe that if `h` were undefined weak it would not have - SYMBOL_REFERENCES_LOCAL return true. However this is not 100% - clear based purely on the members that we check in the code. - The reason it matters is if we could have a - SYMBOL_REFERENCES_LOCAL symbol which is also - !UNDEFWEAK_NO_DYNAMIC_RELOC then the check above would - determine that we need to fix up the fragment for the RELATIVE - relocation that elfNN_aarch64_finish_dynamic_symbol will - create, but in actual fact elfNN_aarch64_finish_dynamic_symbol - would not create that relocation. */ - BFD_ASSERT (!UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)); + /* If this is a dynamic symbol that binds locally then the + generic code and elfNN_aarch64_finish_dynamic_symbol will + already handle creating the RELATIVE reloc pointing into the + GOT for this symbol. That means that this function does not + need to handle *creating* such a relocation. We already + handle setting the base value in the fragment for that + relocation below, but we also need to make sure we set the + rest of the fragment correctly for C64 code (i.e. including + the required permissions and bounds). */ c64_needs_frag_fixup = TRUE; }
@@ -7364,6 +7377,18 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, || (!bfd_link_pic (info) && bfd_link_executable (info) && c64_reloc)) { + /* We have not handled the case for weak undefined symbols in + this clause. That is because we believe there can not be + weak undefined symbols as we reach this clause. We believe + that any symbol with WEAK binding in an object file would be + put into the hash table (and hence go into the `h != NULL` + clause above). The only time that `weak_undef_p` should be + set for something not in the hash table is when we have + removed a relocation by marking it as against the undefined + symbol (e.g. during TLS relaxation). We only ever do that + while also setting the relocation to R_AARCH64_NONE, so we + would not see it in this clause. */ + BFD_ASSERT (!weak_undef_p); relative_reloc = TRUE; c64_needs_frag_fixup = c64_reloc ? TRUE : FALSE; } @@ -7613,12 +7638,25 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
outrel.r_addend = signed_addend;
+ if (h && !c64_needs_relocation (info, h)) + { + /* If we know this symbol does not need a C64 dynamic relocation + then it must be because this is an undefined weak symbol which + can not find a definition at runtime. + + To handle that we just ensure that we've put a zero into the + binary file at this point and mark the relocation as resolved. + */ + value = 0; + *unresolved_reloc_p = FALSE; + break; + } /* Emit a dynamic relocation if we are handling a symbol which the dynamic linker will be told about. */ - if (h != NULL - && h->dynindx != -1 - && globals->root.dynamic_sections_created - && !SYMBOL_REFERENCES_LOCAL (info, h)) + else if (h != NULL + && h->dynindx != -1 + && globals->root.dynamic_sections_created + && !SYMBOL_REFERENCES_LOCAL (info, h)) { outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type); /* Dynamic symbols will be handled by the dynamic loader. Hence @@ -9674,6 +9712,10 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, break;
case BFD_RELOC_MORELLO_CAPINIT: + if (h && !c64_needs_relocation (info, h)) + /* If this symbol does not need a relocation, then there's no + reason to increase the srelcaps size for a relocation. */ + break; if (htab->srelcaps == NULL) { if (htab->root.dynobj == NULL) @@ -10232,23 +10274,37 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) { h->got.offset = htab->root.sgot->size; htab->root.sgot->size += GOT_ENTRY_SIZE (htab); - if (((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT - || h->root.type != bfd_link_hash_undefweak) - && (bfd_link_pic (info) - || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)) - /* Undefined weak symbol in static PIE resolves to 0 without - any dynamic relocations. */ - && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) - /* Any capability relocations required in a dynamic binary - should go in the srelgot. */ - || (htab->c64_rel && dyn)) + + if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + || h->root.type != bfd_link_hash_undefweak) + && (bfd_link_pic (info) + || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)) + /* Undefined weak symbol in static PIE resolves to 0 without + any dynamic relocations. */ + && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) + { + htab->root.srelgot->size += RELOC_SIZE (htab); + } + else if (!htab->c64_rel || !c64_needs_relocation (info, h)) + { + /* Either not relocating for C64, and hence all problematic + relocations are handled above, or this is an undefined weak + symbol that we know will not be resolved to anything by the + runtime do not need a relocation. */ + } + else if (dyn) { + /* Any capability relocations required in a dynamic binary + should go in the srelgot. N.b. many capability relocations + would be caught by the first clause in this if chain. */ htab->root.srelgot->size += RELOC_SIZE (htab); } - else if (bfd_link_executable (info) && htab->c64_rel) + else if (bfd_link_executable (info)) { /* If we have a capability relocation that is not handled by the - case above then this must be a statically linked executable. */ + case above then this must be a statically linked executable. + We want capability relocations in a statically linked + executable to go in the srelcaps section. */ BFD_ASSERT (!bfd_link_pic (info) && !dyn); htab->srelcaps->size += RELOC_SIZE (htab); } diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp index 235df2872084b5115239b671c5107b56a36b446f..f6d579dab0ad88ee9e778a09cf7e3bf69a2f0be7 100644 --- a/ld/testsuite/ld-aarch64/aarch64-elf.exp +++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp @@ -301,6 +301,15 @@ if { [ld_assemble_flags $as -march=morello+c64 $srcdir/$subdir/morello-dynamic-r run_dump_test_lp64 "morello-dataptr-code-and-data" }
+if { [ld_assemble_flags $as -march=morello+c64 $srcdir/$subdir/morello-weakdefinitions.s tmpdir/morello-weakdefinitions.o] + && [ld_link $ld tmpdir/morello-weakdefinitions.so "--shared tmpdir/morello-weakdefinitions.o"] } { + run_dump_test_lp64 "morello-undefweak-relocs-PDE" +} +run_dump_test_lp64 "morello-undefweak-relocs-no-dyn-linker" +run_dump_test_lp64 "morello-undefweak-relocs-PIE" +run_dump_test_lp64 "morello-undefweak-relocs-static" +run_dump_test_lp64 "morello-undefweak-relocs-static-relocs" + run_dump_test_lp64 "morello-static-got" run_dump_test_lp64 "morello-dynamic-got" run_dump_test_lp64 "morello-dt-init-fini" diff --git a/ld/testsuite/ld-aarch64/morello-undefweak-relocs-PDE.d b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-PDE.d new file mode 100644 index 0000000000000000000000000000000000000000..a209418cf2406e2d64afd95f6092c45c9122aec5 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-PDE.d @@ -0,0 +1,61 @@ +# Exercise a corner case of handling morello GOT relocations against weak undef +# symbols. +# +# What we want to check is: +# 1) The adrp/ldr insns point to the relevant entries in the GOT. +# 2) There are relocations for all except the hidden weak undef symbol in the +# GOT (the only symbol which can never be given a value at runtime since +# it is hidden). +# 3) The GOT entry for this weak undefined symbol is zero. +# 4) The values in .data are initialized as zero. +# 5) There are relocations to initialize the non-hidden .data variables and +# no relocation to initialize the value of the hidden symbol. +# +# (1) is checked by ensuring that the adrp/ldr combinations point to increments +# of 0x10 past the start of the got section. +# (2) and (3) are checked by the fact that objdump prints nothing except +# relocations for the non-hidden symbols after the first line in the .got +# section. +# (4) and (5) is checked by the fact that objdump prints nothing except +# relocations for the non-hidden symbols for the data section contents. +#source: morello-undefweak-relocs.s +#as: -march=morello+c64 +#ld: tmpdir/morello-weakdefinitions.so +#objdump: -DR -j .got -j .data -j .text + +.*: file format .* + + +Disassembly of section .text: + +.* <_start>: +#record: GOTPAGE +.* adrp c0, ([0-9a-f]+) .* +#record: GOTOFFSET +.* ldr c0, [c0, #([0-9]+)] +#check: PAGEG string tolower $GOTPAGE +#check: GOTOFF2 expr "$GOTOFFSET - 0x10" +#check: GOTOFF3 expr "$GOTOFFSET - 0x20" +.* adrp c0, PAGEG .* +.* ldr c0, [c0, #GOTOFF2] +.* adrp c0, PAGEG .* +.* ldr c0, [c0, #GOTOFF3] +.* ret c30 + +Disassembly of section .got: + +.* <_GLOBAL_OFFSET_TABLE_>: +#check: GOTSTART format %x [expr "0x$GOTPAGE + $GOTOFFSET - 0x30"] +#check: GOTGLOBAL format %x [expr "0x$GOTPAGE + $GOTOFFSET"] +#check: GOTLOCAL format %x [expr "0x$GOTPAGE + $GOTOFFSET - 0x20"] + *GOTSTART: .* + ... + GOTLOCAL: R_MORELLO_GLOB_DAT localsym + GOTGLOBAL: R_MORELLO_GLOB_DAT globalsym + +Disassembly of section .data: + +.* <.*>: + ... + [0-9a-f]*: R_MORELLO_CAPINIT globalsym + [0-9a-f]*: R_MORELLO_CAPINIT localsym diff --git a/ld/testsuite/ld-aarch64/morello-undefweak-relocs-PIE.d b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-PIE.d new file mode 100644 index 0000000000000000000000000000000000000000..1ef2021def59fd021599acbbc0df4cf4916a3c73 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-PIE.d @@ -0,0 +1,61 @@ +# Exercise a corner case of handling morello GOT relocations against weak undef +# symbols. +# +# What we want to check is: +# 1) The adrp/ldr insns point to the relevant entries in the GOT. +# 2) There are relocations for all except the hidden weak undef symbol in the +# GOT (the only symbol which can never be given a value at runtime since +# it is hidden). +# 3) The GOT entry for this weak undefined symbol is zero. +# 4) The values in .data are initialized as zero. +# 5) There are relocations to initialize the non-hidden .data variables and +# no relocation to initialize the value of the hidden symbol. +# +# (1) is checked by ensuring that the adrp/ldr combinations point to increments +# of 0x10 past the start of the got section. +# (2) and (3) are checked by the fact that objdump prints nothing except +# relocations for the non-hidden symbols after the first line in the .got +# section. +# (4) and (5) is checked by the fact that objdump prints nothing excepet +# relocations for the non-hidden symbols for the data section contents. +#source: morello-undefweak-relocs.s +#as: -march=morello+c64 +#ld: -pie +#objdump: -DR -j .got -j .data -j .text + +.*: file format .* + + +Disassembly of section .text: + +.* <_start>: +#record: GOTPAGE +.* adrp c0, ([0-9a-f]+) .* +#record: GOTOFFSET +.* ldr c0, [c0, #([0-9]+)] +#check: PAGEG string tolower $GOTPAGE +#check: GOTOFF2 expr "$GOTOFFSET - 0x10" +#check: GOTOFF3 expr "$GOTOFFSET - 0x20" +.* adrp c0, PAGEG .* +.* ldr c0, [c0, #GOTOFF2] +.* adrp c0, PAGEG .* +.* ldr c0, [c0, #GOTOFF3] +.* ret c30 + +Disassembly of section .got: + +.* <.got>: +#check: GOTSTART format %x [expr "0x$GOTPAGE + $GOTOFFSET - 0x30"] +#check: GOTGLOBAL format %x [expr "0x$GOTPAGE + $GOTOFFSET"] +#check: GOTLOCAL format %x [expr "0x$GOTPAGE + $GOTOFFSET - 0x20"] + *GOTSTART: .* + ... + GOTLOCAL: R_MORELLO_GLOB_DAT localsym + GOTGLOBAL: R_MORELLO_GLOB_DAT globalsym + +Disassembly of section .data: + +.* <.*>: + ... + [0-9a-f]*: R_MORELLO_CAPINIT globalsym + [0-9a-f]*: R_MORELLO_CAPINIT localsym diff --git a/ld/testsuite/ld-aarch64/morello-undefweak-relocs-no-dyn-linker.d b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-no-dyn-linker.d new file mode 100644 index 0000000000000000000000000000000000000000..8e562d41f9d3c87fa48dcd524fcb4d95ec765a83 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-no-dyn-linker.d @@ -0,0 +1,50 @@ +# Exercise a corner case of handling morello GOT relocations against weak undef +# symbols. +# +# What we want to check is: +# 1) The adrp/ldr insns point to the relevant entries in the GOT. +# 2) There are no relocations in the GOT. +# 3) The GOT entries used by these weak undefined symbols are all zero. +# 4) The values in .data are all zero. +# +# (1) is checked by ensuring that the adrp/ldr combinations point to increments +# of 0x10 past the start of the got section. +# (2) and (3) are checked by the fact that objdump prints nothing after the +# first entry in the .got section (the pointer to the dynamic section). +# (4) is checked by the fact that objdump prints nothing for the data section +# contents. +#source: morello-undefweak-relocs.s +#as: -march=morello+c64 +#ld: -pie --no-dynamic-linker +#objdump: -DR -j .got -j .data -j .text + +.*: file format .* + + +Disassembly of section .text: + +.* <_start>: +#record: GOTPAGE +.* adrp c0, ([0-9a-f]+) .* +#record: GOTOFFSET +.* ldr c0, [c0, #([0-9]+)] +#check: PAGEG string tolower $GOTPAGE +#check: GOTOFF2 expr "$GOTOFFSET - 0x10" +#check: GOTOFF3 expr "$GOTOFFSET - 0x20" +.* adrp c0, PAGEG .* +.* ldr c0, [c0, #GOTOFF2] +.* adrp c0, PAGEG .* +.* ldr c0, [c0, #GOTOFF3] +.* ret c30 + +Disassembly of section .got: + +.* <.got>: +#check: GOTSTART format %x [expr "0x$GOTPAGE + $GOTOFFSET - 0x30"] + GOTSTART: .* + ... + +Disassembly of section .data: + +.* <.*>: + ... diff --git a/ld/testsuite/ld-aarch64/morello-undefweak-relocs-static-relocs.d b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-static-relocs.d new file mode 100644 index 0000000000000000000000000000000000000000..7c81233db93d4a462c1792dc94fbe1e9fb13f532 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-static-relocs.d @@ -0,0 +1,16 @@ +# Exercise handling morello relocations against weak undef symbols. +# +# What we want to check is: +# 1) The adrp/ldr instructions point to entries in the GOT. +# 2) There are no relocations in the GOT. +# 3) The GOT entries for weak undefined symbols are zero. +# 4) The values in .data are zero. +# +# The testcase morello-undefweak-relocs-static.d checks all except that there +# are no relocations in the file. This testcase checks that last part. +#source: morello-undefweak-relocs.s +#as: -march=morello+c64 +#ld: -static +#readelf: --relocs + +There are no relocations in this file. diff --git a/ld/testsuite/ld-aarch64/morello-undefweak-relocs-static.d b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-static.d new file mode 100644 index 0000000000000000000000000000000000000000..a7c5556d7b9d86946a346f2a0f7ccbaa2ba57bd0 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-static.d @@ -0,0 +1,51 @@ +# Exercise handling morello relocations against weak undef symbols. +# +# What we want to check is: +# 1) The adrp/ldr instructions point to entries in the GOT. +# 2) There are no relocations in the GOT. +# 3) The GOT entries for weak undefined symbols are zero. +# 4) The values in .data are zero. +# +# (1) is checked by ensuring that the adrp/ldr combinations point to increments +# of 0x10 past the start of the got section. +# (3) is checked by the fact that objdump prints for the .got section. +# (4) is checked by the fact that objdump prints nothing for the data section +# contents. +# +# Since objdump refuses to print out dynamic relocations for non-dynamic +# executables, we check (2) in a separate testcase. +#source: morello-undefweak-relocs.s +#as: -march=morello+c64 +#ld: -static +#objdump: -D -j .got -j .data -j .text + + +.*: file format .* + + +Disassembly of section .text: + +.* <_start>: +#record: GOTPAGE +.* adrp c0, ([0-9a-f]+) .* +#record: GOTOFFSET +.* ldr c0, [c0, #([0-9]+)] +#check: PAGEG string tolower $GOTPAGE +#check: GOTOFF2 expr "$GOTOFFSET - 0x10" +#check: GOTOFF3 expr "$GOTOFFSET - 0x20" +.* adrp c0, PAGEG .* +.* ldr c0, [c0, #GOTOFF2] +.* adrp c0, PAGEG .* +.* ldr c0, [c0, #GOTOFF3] +.* ret c30 + +Disassembly of section .got: + +#check: GOTSTART format %x [expr "0x$GOTPAGE + $GOTOFFSET - 0x30"] +0*GOTSTART <_GLOBAL_OFFSET_TABLE_>: + ... + +Disassembly of section .data: + +.* <.*>: + ... diff --git a/ld/testsuite/ld-aarch64/morello-undefweak-relocs.s b/ld/testsuite/ld-aarch64/morello-undefweak-relocs.s new file mode 100644 index 0000000000000000000000000000000000000000..7912c01aaa4fdce5ef3e8af526cfa8a0eda3d3ae --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-undefweak-relocs.s @@ -0,0 +1,21 @@ + .weak globalsym + .global globalsym + .weak localsym + .weak hiddensym + .hidden hiddensym + + .data + .chericap globalsym + .chericap localsym + .chericap hiddensym + + .text + .globl _start +_start: + adrp c0, :got:globalsym + ldr c0, [c0, #:got_lo12:globalsym] + adrp c0, :got:hiddensym + ldr c0, [c0, #:got_lo12:hiddensym] + adrp c0, :got:localsym + ldr c0, [c0, #:got_lo12:localsym] + ret diff --git a/ld/testsuite/ld-aarch64/morello-weakdefinitions.s b/ld/testsuite/ld-aarch64/morello-weakdefinitions.s new file mode 100644 index 0000000000000000000000000000000000000000..5fba13ec7d48d5aecf0b89089689420a65a457b6 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-weakdefinitions.s @@ -0,0 +1,18 @@ +# N.b. It should not matter what is contained in this file for the tests we +# run. What we want to show is that the behavior of weak undefined symbols is +# correct for dynamically linked PDE's. That requires linking to a shared +# object which is the point of this separate assembly file. + .global globalsym + .type globalsym, %object +globalsym: + .xword 100 + + .global hiddensym + .type hiddensym, %object +hiddensym: + .xword 100 + + .global localsym + .type localsym, %object +localsym: + .xword 100
gnu-morello@op-lists.linaro.org