From: Alan Modra Date: Wed, 26 Jan 2022 00:01:36 +0000 (+1030) Subject: PowerPC64 treatment of absolute symbols X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3a3a4c1fe4ccb1914d29fbf8f5930d55aacec78f;p=binutils-gdb.git PowerPC64 treatment of absolute symbols Supporting -static-pie on PowerPC64 requires the linker to properly treat SHN_ABS symbols for cases like glibc's _nl_current_LC_CTYPE_used absolute symbol. I've been slow to fix the linker on powerpc because there is some chance that this will break some shared libraries or PIEs. bfd/ * elf64-ppc.c (ppc64_elf_check_relocs): Consolidate local sym handling code. Don't count dyn relocs against non-dynamic absolute symbols. (dec_dynrel_count): Adjust to suit. (ppc64_elf_edit_toc): Don't remove entries for absolute symbols when pic. (allocate_got): Don't allocate space for got relocs against non-dynamic absolute syms. (ppc64_elf_layout_multitoc): Likewise. (got_and_plt_relr): Likewise. (ppc64_elf_size_dynamic_sections): Likewise for local got. (got_and_plt_relr_for_local_syms): Likewise. (ppc64_elf_size_stubs): Don't allocate space for relr either. (ppc64_elf_relocate_section): Don't write relocs against non-dynamic absolute symbols. Don't optimise got and toc code sequences loading absolute symbol entries. ld/ * testsuite/ld-powerpc/abs-reloc.s, * testsuite/ld-powerpc/abs-static.d, * testsuite/ld-powerpc/abs-static.r, * testsuite/ld-powerpc/abs-pie.d, * testsuite/ld-powerpc/abs-pie.r, * testsuite/ld-powerpc/abs-shared.d, * testsuite/ld-powerpc/abs-shared.r, * testsuite/ld-powerpc/abs-pie-relr.d, * testsuite/ld-powerpc/abs-pie-relr.r, * testsuite/ld-powerpc/abs-shared-relr.d, * testsuite/ld-powerpc/abs-shared-relr.r: New tests. * testsuite/ld-powerpc/powerpc.exp: Run them. --- diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index b4fa4aed7b6..7223c497d07 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -4779,6 +4779,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, { unsigned long r_symndx; struct elf_link_hash_entry *h; + Elf_Internal_Sym *isym; enum elf_ppc64_reloc_type r_type; int tls_type; struct _ppc64_elf_section_data *ppc64_sec; @@ -4786,9 +4787,15 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, r_symndx = ELF64_R_SYM (rel->r_info); if (r_symndx < symtab_hdr->sh_info) - h = NULL; + { + h = NULL; + isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd, r_symndx); + if (isym == NULL) + return false; + } else { + isym = NULL; h = sym_hashes[r_symndx - symtab_hdr->sh_info]; h = elf_follow_link (h); @@ -4859,11 +4866,6 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, } else { - Elf_Internal_Sym *isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, - abfd, r_symndx); - if (isym == NULL) - return false; - if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC) { ifunc = update_local_sym_info (abfd, symtab_hdr, r_symndx, @@ -5127,16 +5129,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, dest = h->root.u.def.section; } else - { - Elf_Internal_Sym *isym; - - isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, - abfd, r_symndx); - if (isym == NULL) - return false; - - dest = bfd_section_from_elf_index (abfd, isym->st_shndx); - } + dest = bfd_section_from_elf_index (abfd, isym->st_shndx); if (dest != sec) ppc64_elf_section_data (sec)->has_14bit_branch = 1; @@ -5352,11 +5345,13 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, dodyn: if ((h != NULL && (h->root.type == bfd_link_hash_defweak - || !h->def_regular)) + || (!h->def_regular && !h->root.ldscript_def))) || (h != NULL - && !bfd_link_executable (info) - && !SYMBOLIC_BIND (info, h)) + && !SYMBOL_REFERENCES_LOCAL (info, h)) || (bfd_link_pic (info) + && (h != NULL + ? !bfd_is_abs_symbol (&h->root) + : isym->st_shndx != SHN_ABS) && must_be_dyn_reloc (info, r_type)) || (!bfd_link_pic (info) && ifunc != NULL)) @@ -5404,20 +5399,12 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, } else { - /* Track dynamic relocs needed for local syms too. - We really need local syms available to do this - easily. Oh well. */ + /* Track dynamic relocs needed for local syms too. */ struct ppc_local_dyn_relocs *p; struct ppc_local_dyn_relocs **head; bool is_ifunc; asection *s; void *vpp; - Elf_Internal_Sym *isym; - - isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, - abfd, r_symndx); - if (isym == NULL) - return false; s = bfd_section_from_elf_index (abfd, isym->st_shndx); if (s == NULL) @@ -7256,11 +7243,13 @@ dec_dynrel_count (const Elf_Internal_Rela *rel, if ((h != NULL && (h->root.type == bfd_link_hash_defweak - || !h->def_regular)) + || (!h->def_regular && !h->root.ldscript_def))) || (h != NULL - && !bfd_link_executable (info) - && !SYMBOLIC_BIND (info, h)) + && !SYMBOL_REFERENCES_LOCAL (info, h)) || (bfd_link_pic (info) + && (h != NULL + ? !bfd_is_abs_symbol (&h->root) + : sym_sec != bfd_abs_section_ptr) && must_be_dyn_reloc (info, r_type)) || (!bfd_link_pic (info) && (h != NULL @@ -9065,7 +9054,9 @@ ppc64_elf_edit_toc (struct bfd_link_info *info) || discarded_section (sym_sec)) continue; - if (!SYMBOL_REFERENCES_LOCAL (info, h)) + if (!SYMBOL_REFERENCES_LOCAL (info, h) + || (bfd_link_pic (info) + && sym_sec == bfd_abs_section_ptr)) continue; if (h != NULL) @@ -9647,7 +9638,9 @@ ppc64_elf_edit_toc (struct bfd_link_info *info) if ((h ? h->type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC) continue; - if (!SYMBOL_REFERENCES_LOCAL (info, h)) + if (!SYMBOL_REFERENCES_LOCAL (info, h) + || (bfd_link_pic (info) + && sym_sec == bfd_abs_section_ptr)) continue; if (h != NULL) @@ -9781,7 +9774,8 @@ allocate_got (struct elf_link_hash_entry *h, && (gent->tls_type == 0 ? !info->enable_dt_relr : !(bfd_link_executable (info) - && SYMBOL_REFERENCES_LOCAL (info, h)))) + && SYMBOL_REFERENCES_LOCAL (info, h))) + && !bfd_is_abs_symbol (&h->root)) || (htab->elf.dynamic_sections_created && h->dynindx != -1 && !SYMBOL_REFERENCES_LOCAL (info, h))) @@ -10246,6 +10240,8 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd, unsigned char *lgot_masks; bfd_size_type locsymcount; Elf_Internal_Shdr *symtab_hdr; + Elf_Internal_Sym *local_syms; + Elf_Internal_Sym *isym; if (!is_ppc64_elf (ibfd)) continue; @@ -10296,8 +10292,22 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd, local_plt = (struct plt_entry **) end_lgot_ents; end_local_plt = local_plt + locsymcount; lgot_masks = (unsigned char *) end_local_plt; + local_syms = NULL; + if (bfd_link_pic (info)) + { + local_syms = (Elf_Internal_Sym *) symtab_hdr->contents; + if (local_syms == NULL && locsymcount != 0) + { + local_syms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, locsymcount, + 0, NULL, NULL, NULL); + if (local_syms == NULL) + return false; + } + } s = ppc64_elf_tdata (ibfd)->got; - for (; lgot_ents < end_lgot_ents; ++lgot_ents, ++lgot_masks) + for (isym = local_syms; + lgot_ents < end_lgot_ents; + ++lgot_ents, ++lgot_masks, isym != NULL && isym++) { struct got_entry **pent, *ent; @@ -10330,7 +10340,8 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd, else if (bfd_link_pic (info) && (ent->tls_type == 0 ? !info->enable_dt_relr - : !bfd_link_executable (info))) + : !bfd_link_executable (info)) + && isym->st_shndx != SHN_ABS) { asection *srel = ppc64_elf_tdata (ibfd)->relgot; srel->size += rel_size; @@ -10341,6 +10352,14 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd, else *pent = ent->next; } + if (local_syms != NULL + && symtab_hdr->contents != (unsigned char *) local_syms) + { + if (!info->keep_memory) + free (local_syms); + else + symtab_hdr->contents = (unsigned char *) local_syms; + } /* Allocate space for plt calls to local syms. */ lgot_masks = (unsigned char *) end_local_plt; @@ -12793,6 +12812,8 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info) bfd_size_type locsymcount; Elf_Internal_Shdr *symtab_hdr; asection *s; + Elf_Internal_Sym *local_syms; + Elf_Internal_Sym *isym; if (!is_ppc64_elf (ibfd)) continue; @@ -12807,8 +12828,22 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info) local_plt = (struct plt_entry **) end_lgot_ents; end_local_plt = local_plt + locsymcount; lgot_masks = (unsigned char *) end_local_plt; + local_syms = NULL; + if (bfd_link_pic (info)) + { + local_syms = (Elf_Internal_Sym *) symtab_hdr->contents; + if (local_syms == NULL && locsymcount != 0) + { + local_syms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, locsymcount, + 0, NULL, NULL, NULL); + if (local_syms == NULL) + return false; + } + } s = ppc64_elf_tdata (ibfd)->got; - for (; lgot_ents < end_lgot_ents; ++lgot_ents, ++lgot_masks) + for (isym = local_syms; + lgot_ents < end_lgot_ents; + ++lgot_ents, ++lgot_masks, isym != NULL && isym++) { struct got_entry *ent; @@ -12832,7 +12867,8 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info) else if (bfd_link_pic (info) && (ent->tls_type == 0 ? !info->enable_dt_relr - : !bfd_link_executable (info))) + : !bfd_link_executable (info)) + && isym->st_shndx != SHN_ABS) { asection *srel = ppc64_elf_tdata (ibfd)->relgot; srel->size += rel_size; @@ -13422,7 +13458,8 @@ got_and_plt_relr_for_local_syms (struct bfd_link_info *info) struct plt_entry **local_plt, **lplt, **end_local_plt; Elf_Internal_Shdr *symtab_hdr; bfd_size_type locsymcount; - Elf_Internal_Sym *local_syms = NULL; + Elf_Internal_Sym *local_syms; + Elf_Internal_Sym *isym; struct plt_entry *pent; struct got_entry *gent; @@ -13435,14 +13472,25 @@ got_and_plt_relr_for_local_syms (struct bfd_link_info *info) symtab_hdr = &elf_symtab_hdr (ibfd); locsymcount = symtab_hdr->sh_info; + local_syms = (Elf_Internal_Sym *) symtab_hdr->contents; + if (local_syms == NULL && locsymcount != 0) + { + local_syms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, locsymcount, + 0, NULL, NULL, NULL); + if (local_syms == NULL) + return false; + } end_lgot_ents = lgot_ents + locsymcount; local_plt = (struct plt_entry **) end_lgot_ents; end_local_plt = local_plt + locsymcount; - for (lgot = lgot_ents; lgot < end_lgot_ents; ++lgot) + for (lgot = lgot_ents, isym = local_syms; + lgot < end_lgot_ents; + ++lgot, ++isym) for (gent = *lgot; gent != NULL; gent = gent->next) if (!gent->is_indirect && gent->tls_type == 0 - && gent->got.offset != (bfd_vma) -1) + && gent->got.offset != (bfd_vma) -1 + && isym->st_shndx != SHN_ABS) { asection *got = ppc64_elf_tdata (gent->owner)->got; bfd_vma r_offset = (got->output_section->vma @@ -13456,29 +13504,22 @@ got_and_plt_relr_for_local_syms (struct bfd_link_info *info) } if (!htab->opd_abi) - for (lplt = local_plt; lplt < end_local_plt; ++lplt) + for (lplt = local_plt, isym = local_syms; + lplt < end_local_plt; + ++lplt, ++isym) for (pent = *lplt; pent != NULL; pent = pent->next) - if (pent->plt.offset != (bfd_vma) -1) + if (pent->plt.offset != (bfd_vma) -1 + && ELF_ST_TYPE (isym->st_info) != STT_GNU_IFUNC) { - Elf_Internal_Sym *sym; - - if (!get_sym_h (NULL, &sym, NULL, NULL, &local_syms, - lplt - local_plt, ibfd)) + bfd_vma r_offset = (pent->plt.offset + + htab->pltlocal->output_offset + + htab->pltlocal->output_section->vma); + if (!append_relr_off (htab, r_offset)) { - err_exit: if (symtab_hdr->contents != (unsigned char *) local_syms) free (local_syms); return false; } - - if (ELF_ST_TYPE (sym->st_info) != STT_GNU_IFUNC) - { - bfd_vma r_offset = (pent->plt.offset - + htab->pltlocal->output_offset - + htab->pltlocal->output_section->vma); - if (!append_relr_off (htab, r_offset)) - goto err_exit; - } } if (local_syms != NULL @@ -13514,9 +13555,10 @@ got_and_plt_relr (struct elf_link_hash_entry *h, void *inf) && (h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak)) { - if (!htab->elf.dynamic_sections_created - || h->dynindx == -1 - || SYMBOL_REFERENCES_LOCAL (info, h)) + if ((!htab->elf.dynamic_sections_created + || h->dynindx == -1 + || SYMBOL_REFERENCES_LOCAL (info, h)) + && !bfd_is_abs_symbol (&h->root)) for (gent = h->got.glist; gent != NULL; gent = gent->next) if (!gent->is_indirect && gent->tls_type == 0 @@ -13805,6 +13847,10 @@ ppc64_elf_size_stubs (struct bfd_link_info *info) ? h->type == STT_GNU_IFUNC : ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC) continue; + if (h != NULL + ? bfd_is_abs_symbol (&h->root) + : sym->st_shndx == SHN_ABS) + continue; if (h != NULL && !SYMBOL_REFERENCES_LOCAL (info, h)) continue; @@ -16553,6 +16599,8 @@ ppc64_elf_relocate_section (bfd *output_bfd, case R_PPC64_GOT16_DS: if ((h ? h->elf.type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC + || (bfd_link_pic (info) + && sec == bfd_abs_section_ptr) || !htab->do_toc_opt) break; from = TOCstart + htab->sec_info[input_section->id].toc_off; @@ -16577,6 +16625,8 @@ ppc64_elf_relocate_section (bfd *output_bfd, case R_PPC64_GOT16_LO_DS: case R_PPC64_GOT16_HA: if ((h ? h->elf.type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC + || (bfd_link_pic (info) + && sec == bfd_abs_section_ptr) || !htab->do_toc_opt) break; from = TOCstart + htab->sec_info[input_section->id].toc_off; @@ -16607,6 +16657,8 @@ ppc64_elf_relocate_section (bfd *output_bfd, case R_PPC64_GOT_PCREL34: if ((h ? h->elf.type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC + || (bfd_link_pic (info) + && sec == bfd_abs_section_ptr) || !htab->do_toc_opt) break; from = (rel->r_offset @@ -16846,7 +16898,11 @@ ppc64_elf_relocate_section (bfd *output_bfd, && bfd_link_executable (info) && (h == NULL || SYMBOL_REFERENCES_LOCAL (info, - &h->elf))))) + &h->elf))) + && (h != NULL + ? !bfd_is_abs_symbol (&h->elf.root) + : sym->st_shndx != SHN_ABS))) + relgot = ppc64_elf_tdata (ent->owner)->relgot; if (relgot != NULL) { @@ -17555,7 +17611,11 @@ ppc64_elf_relocate_section (bfd *output_bfd, case R_PPC64_GOT16_HA: case R_PPC64_TOC16_HA: if (htab->do_toc_opt && relocation + addend + 0x8000 < 0x10000 - && !ppc64_elf_tdata (input_bfd)->unexpected_toc_insn) + && !ppc64_elf_tdata (input_bfd)->unexpected_toc_insn + && !(bfd_link_pic (info) + && (h != NULL + ? bfd_is_abs_symbol (&h->elf.root) + : sec == bfd_abs_section_ptr))) { bfd_byte *p; nop_it: @@ -17586,6 +17646,10 @@ ppc64_elf_relocate_section (bfd *output_bfd, case R_PPC64_TOC16_LO_DS: if (htab->do_toc_opt && relocation + addend + 0x8000 < 0x10000 && !ppc64_elf_tdata (input_bfd)->unexpected_toc_insn + && !(bfd_link_pic (info) + && (h != NULL + ? bfd_is_abs_symbol (&h->elf.root) + : sec == bfd_abs_section_ptr)) && offset_in_range (input_section, rel->r_offset & ~3, 4)) { bfd_byte *p = contents + (rel->r_offset & ~3); diff --git a/ld/testsuite/ld-powerpc/abs-pie-relr.d b/ld/testsuite/ld-powerpc/abs-pie-relr.d new file mode 100644 index 00000000000..edf0b430c78 --- /dev/null +++ b/ld/testsuite/ld-powerpc/abs-pie-relr.d @@ -0,0 +1,34 @@ +#source: abs-reloc.s +#as: -a64 +#ld: -melf64ppc -pie --hash-style=sysv -z pack-relative-relocs --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0 +#objdump: -sdr + +#... +Contents of section .got: +.* (00000000 00018300|00830100 00000000) (00000000 00000001|01000000 00000000) .* +.* (00000000 00000002|02000000 00000000) (12345678 9abcdef0|f0debc9a 78563412) .* +.* (00000000 00000002|02000000 00000000) (12345678 9abcdef0|f0debc9a 78563412) .* +.* (00000000 00000001|01000000 00000000) .* +Contents of section \.data: +.* (00000000 00010338|38030100 00000000) (00000000 00000001|01000000 00000000) .* +.* (00000000 00000002|02000000 00000000) (12345678 9abcdef0|f0debc9a 78563412) .* +#... +.* <_start>: +.*: (3c 4c 00 02|02 00 4c 3c) addis r2,r12,2 +.*: (38 42 81 58|58 81 42 38) addi r2,r2,-32424 +.*: (60 00 00 00|00 00 00 60) nop +.*: (38 62 80 38|38 80 62 38) addi r3,r2,-32712 +.*: (60 00 00 00|00 00 00 60) nop +.*: (e8 82 80 08|08 80 82 e8) ld r4,-32760\(r2\) +.*: (60 00 00 00|00 00 00 60) nop +.*: (e8 a2 80 10|10 80 a2 e8) ld r5,-32752\(r2\) +.*: (60 00 00 00|00 00 00 60) nop +.*: (e8 c2 80 18|18 80 c2 e8) ld r6,-32744\(r2\) +.*: (60 00 00 00|00 00 00 60) nop +.*: (38 e2 80 38|38 80 e2 38) addi r7,r2,-32712 +.*: (3d 02 00 00|00 00 02 3d) addis r8,r2,0 +.*: (e9 08 80 30|30 80 08 e9) ld r8,-32720\(r8\) +.*: (3d 22 00 00|00 00 22 3d) addis r9,r2,0 +.*: (e9 29 80 20|20 80 29 e9) ld r9,-32736\(r9\) +.*: (3d 42 00 00|00 00 42 3d) addis r10,r2,0 +.*: (e9 4a 80 28|28 80 4a e9) ld r10,-32728\(r10\) diff --git a/ld/testsuite/ld-powerpc/abs-pie-relr.r b/ld/testsuite/ld-powerpc/abs-pie-relr.r new file mode 100644 index 00000000000..22effe89541 --- /dev/null +++ b/ld/testsuite/ld-powerpc/abs-pie-relr.r @@ -0,0 +1,8 @@ +#source: abs-reloc.s +#as: -a64 +#ld: -melf64ppc -pie --hash-style=sysv -z pack-relative-relocs --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0 +#readelf: -rW + +Relocation section '\.relr\.dyn' at offset .* contains 1 entry: + 1 offset +0+10338 diff --git a/ld/testsuite/ld-powerpc/abs-pie.d b/ld/testsuite/ld-powerpc/abs-pie.d new file mode 100644 index 00000000000..b0930b6269f --- /dev/null +++ b/ld/testsuite/ld-powerpc/abs-pie.d @@ -0,0 +1,34 @@ +#source: abs-reloc.s +#as: -a64 +#ld: -melf64ppc -pie --hash-style=sysv --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0 +#objdump: -sdr + +#... +Contents of section \.got: +.* (00000000 00018400|00840100 00000000) (00000000 00000001|01000000 00000000) .* +.* (00000000 00000002|02000000 00000000) (12345678 9abcdef0|f0debc9a 78563412) .* +.* (00000000 00000002|02000000 00000000) (12345678 9abcdef0|f0debc9a 78563412) .* +.* (00000000 00000001|01000000 00000000) .* +Contents of section \.data: +.* (00000000 00010438|38040100 00000000) (00000000 00000001|01000000 00000000) .* +.* (00000000 00000002|02000000 00000000) (12345678 9abcdef0|f0debc9a 78563412) .* +#... +.* <_start>: +.*: (3c 4c 00 02|02 00 4c 3c) addis r2,r12,2 +.*: (38 42 82 10|10 82 42 38) addi r2,r2,-32240 +.*: (60 00 00 00|00 00 00 60) nop +.*: (38 62 80 38|38 80 62 38) addi r3,r2,-32712 +.*: (60 00 00 00|00 00 00 60) nop +.*: (e8 82 80 08|08 80 82 e8) ld r4,-32760\(r2\) +.*: (60 00 00 00|00 00 00 60) nop +.*: (e8 a2 80 10|10 80 a2 e8) ld r5,-32752\(r2\) +.*: (60 00 00 00|00 00 00 60) nop +.*: (e8 c2 80 18|18 80 c2 e8) ld r6,-32744\(r2\) +.*: (60 00 00 00|00 00 00 60) nop +.*: (38 e2 80 38|38 80 e2 38) addi r7,r2,-32712 +.*: (3d 02 00 00|00 00 02 3d) addis r8,r2,0 +.*: (e9 08 80 30|30 80 08 e9) ld r8,-32720\(r8\) +.*: (3d 22 00 00|00 00 22 3d) addis r9,r2,0 +.*: (e9 29 80 20|20 80 29 e9) ld r9,-32736\(r9\) +.*: (3d 42 00 00|00 00 42 3d) addis r10,r2,0 +.*: (e9 4a 80 28|28 80 4a e9) ld r10,-32728\(r10\) diff --git a/ld/testsuite/ld-powerpc/abs-pie.r b/ld/testsuite/ld-powerpc/abs-pie.r new file mode 100644 index 00000000000..2ae4d0e96a2 --- /dev/null +++ b/ld/testsuite/ld-powerpc/abs-pie.r @@ -0,0 +1,8 @@ +#source: abs-reloc.s +#as: -a64 +#ld: -melf64ppc -pie --hash-style=sysv --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0 +#readelf: -rW + +Relocation section '\.rela\.dyn' at offset .* contains 1 entry: + +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend +0+10438 +0+16 R_PPC64_RELATIVE +10438 diff --git a/ld/testsuite/ld-powerpc/abs-reloc.s b/ld/testsuite/ld-powerpc/abs-reloc.s new file mode 100644 index 00000000000..a5898e1dcb1 --- /dev/null +++ b/ld/testsuite/ld-powerpc/abs-reloc.s @@ -0,0 +1,49 @@ + .globl x + .hidden x + + .section .toc,"aw" + .p2align 3 +.Lx: + .quad x +.La: + .quad a +.Lb: + .quad b +.Lc: + .quad c + + .data + .p2align 3 +x: + .quad x + .quad a + .quad b + .quad c + + .text + .p2align 2 + .globl _start + .type _start,@function +_start: +0: + addis 2,12,.TOC.-0b@ha + addi 2,2,.TOC.-0b@l + .localentry _start,.-_start + addis 3,2,.Lx@toc@ha + ld 3,.Lx@toc@l(3) + addis 4,2,.La@toc@ha + ld 4,.La@toc@l(4) + addis 5,2,.Lb@toc@ha + ld 5,.Lb@toc@l(5) + addis 6,2,.Lc@toc@ha + ld 6,.Lc@toc@l(6) + + addis 7,2,x@got@ha + ld 7,x@got@l(7) + addis 8,2,a@got@ha + ld 8,a@got@l(8) + addis 9,2,b@got@ha + ld 9,b@got@l(9) + addis 10,2,c@got@ha + ld 10,c@got@l(10) + .size _start,.-_start diff --git a/ld/testsuite/ld-powerpc/abs-shared-relr.d b/ld/testsuite/ld-powerpc/abs-shared-relr.d new file mode 100644 index 00000000000..1460809bf0b --- /dev/null +++ b/ld/testsuite/ld-powerpc/abs-shared-relr.d @@ -0,0 +1,34 @@ +#source: abs-reloc.s +#as: -a64 +#ld: -melf64ppc -shared --hash-style=sysv -z pack-relative-relocs --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0 +#objdump: -sdr + +#... +Contents of section \.got: +.* (00000000 00018400|00840100 00000000) 00000000 00000000 .* +.* (00000000 00000002|02000000 00000000) 00000000 00000000 .* +.* (00000000 00000002|02000000 00000000) 00000000 00000000 .* +.* 00000000 00000000 .* +Contents of section \.data: +.* (00000000 00010438|38040100 00000000) 00000000 00000000 .* +.* (00000000 00000002|02000000 00000000) 00000000 00000000 .* +#... +.* <_start>: +.*: (3c 4c 00 02|02 00 4c 3c) addis r2,r12,2 +.*: (38 42 81 b0|b0 81 42 38) addi r2,r2,-32336 +.*: (60 00 00 00|00 00 00 60) nop +.*: (38 62 80 38|38 80 62 38) addi r3,r2,-32712 +.*: (60 00 00 00|00 00 00 60) nop +.*: (e8 82 80 08|08 80 82 e8) ld r4,-32760\(r2\) +.*: (60 00 00 00|00 00 00 60) nop +.*: (e8 a2 80 10|10 80 a2 e8) ld r5,-32752\(r2\) +.*: (60 00 00 00|00 00 00 60) nop +.*: (e8 c2 80 18|18 80 c2 e8) ld r6,-32744\(r2\) +.*: (60 00 00 00|00 00 00 60) nop +.*: (38 e2 80 38|38 80 e2 38) addi r7,r2,-32712 +.*: (3d 02 00 00|00 00 02 3d) addis r8,r2,0 +.*: (e9 08 80 30|30 80 08 e9) ld r8,-32720\(r8\) +.*: (3d 22 00 00|00 00 22 3d) addis r9,r2,0 +.*: (e9 29 80 20|20 80 29 e9) ld r9,-32736\(r9\) +.*: (3d 42 00 00|00 00 42 3d) addis r10,r2,0 +.*: (e9 4a 80 28|28 80 4a e9) ld r10,-32728\(r10\) diff --git a/ld/testsuite/ld-powerpc/abs-shared-relr.r b/ld/testsuite/ld-powerpc/abs-shared-relr.r new file mode 100644 index 00000000000..978c43a38e9 --- /dev/null +++ b/ld/testsuite/ld-powerpc/abs-shared-relr.r @@ -0,0 +1,17 @@ +#source: abs-reloc.s +#as: -a64 +#ld: -melf64ppc -pie --hash-style=sysv -z pack-relative-relocs --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0 +#readelf: -rW + +Relocation section '\.rela\.dyn' at offset .* contains 6 entries: + +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend +0+10408 0+500000026 R_PPC64_ADDR64 0+1 a \+ 0 +0+10430 0+500000014 R_PPC64_GLOB_DAT 0+1 a \+ 0 +0+10440 0+500000026 R_PPC64_ADDR64 0+1 a \+ 0 +0+10418 0+400000026 R_PPC64_ADDR64 123456789abcdef0 c \+ 0 +0+10428 0+400000014 R_PPC64_GLOB_DAT 123456789abcdef0 c \+ 0 +0+10450 0+400000026 R_PPC64_ADDR64 123456789abcdef0 c \+ 0 + +Relocation section '\.relr\.dyn' at offset .* contains 1 entry: + 1 offset +0+10438 diff --git a/ld/testsuite/ld-powerpc/abs-shared.d b/ld/testsuite/ld-powerpc/abs-shared.d new file mode 100644 index 00000000000..b66a4b0b863 --- /dev/null +++ b/ld/testsuite/ld-powerpc/abs-shared.d @@ -0,0 +1,34 @@ +#source: abs-reloc.s +#as: -a64 +#ld: -melf64ppc -shared --hash-style=sysv --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0 +#objdump: -sdr + +#... +Contents of section \.got: +.* (00000000 00018400|00840100 00000000) 00000000 00000000 .* +.* (00000000 00000002|02000000 00000000) 00000000 00000000 .* +.* (00000000 00000002|02000000 00000000) 00000000 00000000 .* +.* 00000000 00000000 .* +Contents of section \.data: +.* (00000000 00010438|38040100 00000000) 00000000 00000000 .* +.* (00000000 00000002|02000000 00000000) 00000000 00000000 .* +#... +.* <_start>: +.*: (3c 4c 00 02|02 00 4c 3c) addis r2,r12,2 +.*: (38 42 81 a0|a0 81 42 38) addi r2,r2,-32352 +.*: (60 00 00 00|00 00 00 60) nop +.*: (38 62 80 38|38 80 62 38) addi r3,r2,-32712 +.*: (60 00 00 00|00 00 00 60) nop +.*: (e8 82 80 08|08 80 82 e8) ld r4,-32760\(r2\) +.*: (60 00 00 00|00 00 00 60) nop +.*: (e8 a2 80 10|10 80 a2 e8) ld r5,-32752\(r2\) +.*: (60 00 00 00|00 00 00 60) nop +.*: (e8 c2 80 18|18 80 c2 e8) ld r6,-32744\(r2\) +.*: (60 00 00 00|00 00 00 60) nop +.*: (38 e2 80 38|38 80 e2 38) addi r7,r2,-32712 +.*: (3d 02 00 00|00 00 02 3d) addis r8,r2,0 +.*: (e9 08 80 30|30 80 08 e9) ld r8,-32720\(r8\) +.*: (3d 22 00 00|00 00 22 3d) addis r9,r2,0 +.*: (e9 29 80 20|20 80 29 e9) ld r9,-32736\(r9\) +.*: (3d 42 00 00|00 00 42 3d) addis r10,r2,0 +.*: (e9 4a 80 28|28 80 4a e9) ld r10,-32728\(r10\) diff --git a/ld/testsuite/ld-powerpc/abs-shared.r b/ld/testsuite/ld-powerpc/abs-shared.r new file mode 100644 index 00000000000..70fb78139ba --- /dev/null +++ b/ld/testsuite/ld-powerpc/abs-shared.r @@ -0,0 +1,14 @@ +#source: abs-reloc.s +#as: -a64 +#ld: -melf64ppc -shared --hash-style=sysv --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0 +#readelf: -rW + +Relocation section '\.rela\.dyn' at offset .* contains 7 entries: + +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend +0+10438 0+000000016 R_PPC64_RELATIVE +10438 +0+10408 0+500000026 R_PPC64_ADDR64 0+1 a \+ 0 +0+10430 0+500000014 R_PPC64_GLOB_DAT 0+1 a \+ 0 +0+10440 0+500000026 R_PPC64_ADDR64 0+1 a \+ 0 +0+10418 0+400000026 R_PPC64_ADDR64 123456789abcdef0 c \+ 0 +0+10428 0+400000014 R_PPC64_GLOB_DAT 123456789abcdef0 c \+ 0 +0+10450 0+400000026 R_PPC64_ADDR64 123456789abcdef0 c \+ 0 diff --git a/ld/testsuite/ld-powerpc/abs-static.d b/ld/testsuite/ld-powerpc/abs-static.d new file mode 100644 index 00000000000..fafb1a6e944 --- /dev/null +++ b/ld/testsuite/ld-powerpc/abs-static.d @@ -0,0 +1,32 @@ +#source: abs-reloc.s +#as: -a64 +#ld: -melf64ppc -static --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0 +#objdump: -sdr + +#... +Contents of section \.got: +.* (00000000 10018100|00810110 00000000) (12345678 9abcdef0|f0debc9a 78563412) .* +.* (12345678 9abcdef0|f0debc9a 78563412) .* +Contents of section \.data: +.* (00000000 10010118|18010110 00000000) (00000000 00000001|01000000 00000000) .* +.* (00000000 00000002|02000000 00000000) (12345678 9abcdef0|f0debc9a 78563412) .* +#... +.* <_start>: +.*: (3c 40 10 02|02 10 40 3c) lis r2,4098 +.*: (38 42 81 00|00 81 42 38) addi r2,r2,-32512 +.*: (60 00 00 00|00 00 00 60) nop +.*: (38 62 80 18|18 80 62 38) addi r3,r2,-32744 +.*: (3c 82 ef fe|fe ef 82 3c) addis r4,r2,-4098 +.*: (38 84 7f 01|01 7f 84 38) addi r4,r4,32513 +.*: (3c a2 ef fe|fe ef a2 3c) addis r5,r2,-4098 +.*: (38 a5 7f 02|02 7f a5 38) addi r5,r5,32514 +.*: (60 00 00 00|00 00 00 60) nop +.*: (e8 c2 80 08|08 80 c2 e8) ld r6,-32760\(r2\) +.*: (60 00 00 00|00 00 00 60) nop +.*: (38 e2 80 18|18 80 e2 38) addi r7,r2,-32744 +.*: (3d 02 ef fe|fe ef 02 3d) addis r8,r2,-4098 +.*: (39 08 7f 01|01 7f 08 39) addi r8,r8,32513 +.*: (3d 22 ef fe|fe ef 22 3d) addis r9,r2,-4098 +.*: (39 29 7f 02|02 7f 29 39) addi r9,r9,32514 +.*: (60 00 00 00|00 00 00 60) nop +.*: (e9 42 80 10|10 80 42 e9) ld r10,-32752\(r2\) diff --git a/ld/testsuite/ld-powerpc/abs-static.r b/ld/testsuite/ld-powerpc/abs-static.r new file mode 100644 index 00000000000..4b5886cb021 --- /dev/null +++ b/ld/testsuite/ld-powerpc/abs-static.r @@ -0,0 +1,6 @@ +#source: abs-reloc.s +#as: -a64 +#ld: -melf64ppc -static --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0 +#readelf: -rW + +There are no relocations in this file. diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp index 3d738f5f93c..318bf92c85f 100644 --- a/ld/testsuite/ld-powerpc/powerpc.exp +++ b/ld/testsuite/ld-powerpc/powerpc.exp @@ -354,6 +354,26 @@ set ppc64elftests { {"startstop" "-shared -melf64ppc --hash-style=sysv --gc-sections -z start-stop-gc" "" "-a64 -mpower10" {startstop.s} {{objdump -d startstop.d} {readelf {-rW} startstop.r}} "startstop.so"} + {"abs-static" "-melf64ppc -static --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0" "" + "-a64" {abs-reloc.s} + {{objdump {-sdr} abs-static.d} + {readelf {-rW} abs-static.r}} "abs-static"} + {"abs-pie" "-melf64ppc -pie --hash-style=sysv --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0" "" + "-a64" {abs-reloc.s} + {{objdump {-sdr} abs-pie.d} + {readelf {-rW} abs-pie.r}} "abs-pie"} + {"abs-shared" "-melf64ppc -shared --hash-style=sysv --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0" "" + "-a64" {abs-reloc.s} + {{objdump {-sdr} abs-shared.d} + {readelf {-rW} abs-shared.r}} "abs-shared"} + {"abs-pie-relr" "-melf64ppc -pie --hash-style=sysv -z pack-relative-relocs --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0" "" + "-a64" {abs-reloc.s} + {{objdump {-sdr} abs-pie-relr.d} + {readelf {-rW} abs-pie-relr.r}} "abs-pie-relr"} + {"abs-shared-relr" "-melf64ppc -shared --hash-style=sysv -z pack-relative-relocs --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0" "" + "-a64" {abs-reloc.s} + {{objdump {-sdr} abs-shared-relr.d} + {readelf {-rW} abs-shared-relr.r}} "abs-shared-relr"} } set ppceabitests {