S/390: Improve partial relro support for 64 bit
Currently on S/390 the .got.plt always comes first which prevents the GNU_RELRO segment from being extended across the non-plt GOT entries. Just swapping both unfortunately is not that simple since our ABI requires the _GLOBAL_OFFSET_TABLE_ symbol to point to the very beginning of the entire GOT. Of the 3 magic GOT entries the first is accessed via got pointer while second and third are being accessed via DT_PLTGOT. In order to keep them together we make DT_PLTGOT to point to the .got instead of .got.plt. However, this violates an assumption in the dynamic linker prelink undo code about the GOTPLT entries starting at DT_PLTGOT + 3. We got rid of this requirement with a Glibc patch already in version 2.24: https://sourceware.org/ml/libc-alpha/2016-06/msg01302.html So the S/390 relro GOT layout will look like this with this patch: +----------------------------------+ |got[0]: DYNAMIC | <--- _GLOBAL_OFFSET_TABLE_ == DT_PLTGOT .got |got[1]: link_map parm | |got[2]: &_dl_runtime_resolve | +----------------------------------+ | | non-plt GOT entries | | | | +----------------------------------+ | | <--- .gotplt, PLT GOT entries | | | | | | +----------------------------------+ The patch detects the current layout in size_dynamic_section in order to deal also with linker scripts not generated by this ld version. With partial relro enabled we pick a linker script where .got and .got.plt are swapped which then triggers the rest of the logic. ld/ChangeLog: 2018-07-18 Andreas Krebbel <krebbel@linux.ibm.com> * emulparams/elf64_s390.sh: Define GENERATE_RELRO_SCRIPT and SEPARATE_GOTPLT. * testsuite/ld-s390/gotreloc_64-relro-1.dd: New test. * testsuite/ld-s390/gotreloc_64-norelro-1.dd: Renamed from ... * testsuite/ld-s390/gotreloc_64-1.dd: ... this. * testsuite/ld-s390/s390.exp: Split the GOT testcase into two. bfd/ChangeLog: 2018-07-18 Andreas Krebbel <krebbel@linux.ibm.com> * elf-s390-common.c (s390_gotplt_after_got_p): New function. (s390_got_pointer): New function. (s390_got_offset): New function. (s390_gotplt_offset): New function. * elf64-s390.c (allocate_dynrelocs): Adjust comment. (elf_s390_size_dynamic_sections): Move space for magic GOT entries from .got.plt to .got if necessary and pick the right location for _GLOBAL_OFFSET_TABLE_. (elf_s390_relocate_section): Use the wrapper functions from elf-s390-common.c to deal with both possible layouts (either .got or .got.plt first). (elf_s390_finish_dynamic_sections): Likewise. (elf_s390_finish_dynamic_symbol): Make the location of the GOT magic entries conditional.
This commit is contained in:
parent
a38137289e
commit
afca762f59
|
@ -30,6 +30,87 @@ s390_is_ifunc_symbol_p (struct elf_link_hash_entry *h)
|
|||
return h->type == STT_GNU_IFUNC || eh->ifunc_resolver_address != 0;
|
||||
}
|
||||
|
||||
/* Return true if .got.plt is supposed to be emitted after .got. */
|
||||
|
||||
static inline bfd_boolean
|
||||
s390_gotplt_after_got_p (struct bfd_link_info *info)
|
||||
{
|
||||
struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info);
|
||||
|
||||
if (!htab->elf.sgot || !htab->elf.sgotplt)
|
||||
return TRUE;
|
||||
|
||||
if (htab->elf.sgot->output_section == htab->elf.sgotplt->output_section)
|
||||
{
|
||||
if (htab->elf.sgot->output_offset < htab->elf.sgotplt->output_offset)
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (htab->elf.sgot->output_section->vma
|
||||
<= htab->elf.sgotplt->output_section->vma)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Return the value of the _GLOBAL_OFFSET_TABLE_ symbol. */
|
||||
|
||||
static inline bfd_vma
|
||||
s390_got_pointer (struct bfd_link_info *info)
|
||||
{
|
||||
struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info);
|
||||
bfd_vma got_pointer;
|
||||
|
||||
BFD_ASSERT (htab && htab->elf.hgot);
|
||||
|
||||
got_pointer = (htab->elf.hgot->root.u.def.section->output_section->vma
|
||||
+ htab->elf.hgot->root.u.def.section->output_offset);
|
||||
/* Our ABI requires the GOT pointer to point at the very beginning
|
||||
of the global offset table. */
|
||||
BFD_ASSERT (got_pointer
|
||||
<= (htab->elf.sgot->output_section->vma
|
||||
+ htab->elf.sgot->output_offset));
|
||||
BFD_ASSERT (got_pointer
|
||||
<= (htab->elf.sgotplt->output_section->vma
|
||||
+ htab->elf.sgotplt->output_offset));
|
||||
|
||||
return got_pointer;
|
||||
}
|
||||
|
||||
|
||||
/* Return the offset of the .got versus _GLOBAL_OFFSET_TABLE_. */
|
||||
|
||||
static inline bfd_vma
|
||||
s390_got_offset (struct bfd_link_info *info)
|
||||
{
|
||||
struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info);
|
||||
|
||||
/* The absolute address of the .got in the target image. */
|
||||
bfd_vma got_address = (htab->elf.sgot->output_section->vma
|
||||
+ htab->elf.sgot->output_offset);
|
||||
|
||||
/* GOT offset must not be negative. */
|
||||
BFD_ASSERT (s390_got_pointer (info) <= got_address);
|
||||
return got_address - s390_got_pointer (info);
|
||||
}
|
||||
|
||||
/* Return the offset of the .got.plt versus _GLOBAL_OFFSET_TABLE_. */
|
||||
|
||||
static inline bfd_vma
|
||||
s390_gotplt_offset (struct bfd_link_info *info)
|
||||
{
|
||||
struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info);
|
||||
|
||||
/* The absolute address of the .got.plt in the target image. */
|
||||
bfd_vma gotplt_address = (htab->elf.sgotplt->output_section->vma
|
||||
+ htab->elf.sgotplt->output_offset);
|
||||
|
||||
/* GOT offset must not be negative. */
|
||||
BFD_ASSERT (s390_got_pointer (info) <= gotplt_address);
|
||||
return gotplt_address - s390_got_pointer (info);
|
||||
}
|
||||
|
||||
/* Create sections needed by STT_GNU_IFUNC symbol. */
|
||||
|
||||
static bfd_boolean
|
||||
|
|
141
bfd/elf64-s390.c
141
bfd/elf64-s390.c
|
@ -481,7 +481,7 @@ elf_s390_is_local_label_name (bfd *abfd, const char *name)
|
|||
|
||||
#define RELA_ENTRY_SIZE sizeof (Elf64_External_Rela)
|
||||
|
||||
/* The first three entries in a procedure linkage table are reserved,
|
||||
/* The first three entries in a global offset table are reserved,
|
||||
and the initial contents are unimportant (we zero them out).
|
||||
Subsequent entries look like this. See the SVR4 ABI 386
|
||||
supplement to see how this works. */
|
||||
|
@ -511,8 +511,8 @@ elf_s390_is_local_label_name (bfd *abfd, const char *name)
|
|||
LG 1,0(1) # 6 bytes Load address from GOT in r1
|
||||
BCR 15,1 # 2 bytes Jump to address
|
||||
RET1: BASR 1,0 # 2 bytes Return from GOT 1st time
|
||||
LGF 1,12(1) # 6 bytes Load offset in symbl table in r1
|
||||
BRCL 15,-x # 6 bytes Jump to start of PLT
|
||||
LGF 1,12(1) # 6 bytes Load rela.plt offset into r1
|
||||
BRCL 15,-x # 6 bytes Jump to first PLT entry
|
||||
.long ? # 4 bytes offset into .rela.plt
|
||||
|
||||
Total = 32 bytes per PLT entry
|
||||
|
@ -1605,8 +1605,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h,
|
|||
/* Make room for this entry. */
|
||||
s->size += PLT_ENTRY_SIZE;
|
||||
|
||||
/* We also need to make an entry in the .got.plt section, which
|
||||
will be placed in the .got section by the linker script. */
|
||||
/* We also need to make an entry in the .got.plt section. */
|
||||
htab->elf.sgotplt->size += GOT_ENTRY_SIZE;
|
||||
|
||||
/* We also need to make an entry in the .rela.plt section. */
|
||||
|
@ -1831,6 +1830,20 @@ elf_s390_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|||
}
|
||||
}
|
||||
|
||||
if (htab->elf.sgot && s390_gotplt_after_got_p (info))
|
||||
{
|
||||
/* _bfd_elf_create_got_section adds the got header size always
|
||||
to .got.plt but we need it in .got if this section comes
|
||||
first. */
|
||||
htab->elf.sgot->size += 3 * GOT_ENTRY_SIZE;
|
||||
htab->elf.sgotplt->size -= 3 * GOT_ENTRY_SIZE;
|
||||
|
||||
/* Make the _GLOBAL_OFFSET_TABLE_ symbol point to the .got
|
||||
instead of .got.plt. */
|
||||
htab->elf.hgot->root.u.def.section = htab->elf.sgot;
|
||||
htab->elf.hgot->root.u.def.value = 0;
|
||||
}
|
||||
|
||||
/* Set up .got offsets for local syms, and space for local dynamic
|
||||
relocs. */
|
||||
for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
|
||||
|
@ -2131,7 +2144,6 @@ elf_s390_relocate_section (bfd *output_bfd,
|
|||
bfd_boolean unresolved_reloc;
|
||||
bfd_reloc_status_type r;
|
||||
int tls_type;
|
||||
asection *base_got = htab->elf.sgot;
|
||||
bfd_boolean resolved_to_zero;
|
||||
|
||||
r_type = ELF64_R_TYPE (rel->r_info);
|
||||
|
@ -2172,7 +2184,7 @@ elf_s390_relocate_section (bfd *output_bfd,
|
|||
case R_390_PLTOFF16:
|
||||
case R_390_PLTOFF32:
|
||||
case R_390_PLTOFF64:
|
||||
relocation -= htab->elf.sgot->output_section->vma;
|
||||
relocation -= s390_got_pointer (info);
|
||||
break;
|
||||
case R_390_GOTPLT12:
|
||||
case R_390_GOTPLT16:
|
||||
|
@ -2192,10 +2204,10 @@ elf_s390_relocate_section (bfd *output_bfd,
|
|||
htab->elf.sgot->contents +
|
||||
local_got_offsets[r_symndx]);
|
||||
relocation = (local_got_offsets[r_symndx] +
|
||||
htab->elf.sgot->output_offset);
|
||||
s390_got_offset (info));
|
||||
|
||||
if (r_type == R_390_GOTENT || r_type == R_390_GOTPLTENT)
|
||||
relocation += htab->elf.sgot->output_section->vma;
|
||||
relocation += s390_got_pointer (info);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -2254,25 +2266,23 @@ elf_s390_relocate_section (bfd *output_bfd,
|
|||
|
||||
if (s390_is_ifunc_symbol_p (h))
|
||||
{
|
||||
/* Entry indices of .iplt and .igot.plt match
|
||||
1:1. No magic PLT first entry here. */
|
||||
plt_index = h->plt.offset / PLT_ENTRY_SIZE;
|
||||
relocation = (plt_index * GOT_ENTRY_SIZE +
|
||||
htab->elf.igotplt->output_offset);
|
||||
if (r_type == R_390_GOTPLTENT)
|
||||
relocation += htab->elf.igotplt->output_section->vma;
|
||||
relocation = (plt_index * GOT_ENTRY_SIZE
|
||||
+ s390_gotplt_offset (info)
|
||||
+ htab->elf.igotplt->output_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Calc. index no.
|
||||
Current offset - size first entry / entry size. */
|
||||
plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) /
|
||||
PLT_ENTRY_SIZE;
|
||||
plt_index = ((h->plt.offset - PLT_FIRST_ENTRY_SIZE)
|
||||
/ PLT_ENTRY_SIZE);
|
||||
|
||||
/* Offset in GOT is PLT index plus GOT headers(3)
|
||||
times 8, addr & GOT addr. */
|
||||
relocation = (plt_index + 3) * GOT_ENTRY_SIZE;
|
||||
if (r_type == R_390_GOTPLTENT)
|
||||
relocation += htab->elf.sgot->output_section->vma;
|
||||
relocation = (plt_index * GOT_ENTRY_SIZE
|
||||
+ s390_gotplt_offset (info));
|
||||
}
|
||||
if (r_type == R_390_GOTPLTENT)
|
||||
relocation += s390_got_pointer (info);
|
||||
unresolved_reloc = FALSE;
|
||||
break;
|
||||
}
|
||||
|
@ -2286,7 +2296,7 @@ elf_s390_relocate_section (bfd *output_bfd,
|
|||
case R_390_GOTENT:
|
||||
/* Relocation is to the entry for this symbol in the global
|
||||
offset table. */
|
||||
if (base_got == NULL)
|
||||
if (htab->elf.sgot == NULL)
|
||||
abort ();
|
||||
|
||||
if (h != NULL)
|
||||
|
@ -2303,8 +2313,19 @@ elf_s390_relocate_section (bfd *output_bfd,
|
|||
{
|
||||
/* No explicit GOT usage so redirect to the
|
||||
got.iplt slot. */
|
||||
base_got = htab->elf.igotplt;
|
||||
off = h->plt.offset / PLT_ENTRY_SIZE * GOT_ENTRY_SIZE;
|
||||
relocation = (s390_gotplt_offset (info)
|
||||
+ htab->elf.igotplt->output_offset
|
||||
+ (h->plt.offset / PLT_ENTRY_SIZE
|
||||
* GOT_ENTRY_SIZE));
|
||||
|
||||
/* For @GOTENT the relocation is against the offset between
|
||||
the instruction and the symbols entry in the GOT and not
|
||||
between the start of the GOT and the symbols entry. We
|
||||
add the vma of the GOT to get the correct value. */
|
||||
if (r_type == R_390_GOTENT || r_type == R_390_GOTPLTENT)
|
||||
relocation += s390_got_pointer (info);
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2337,7 +2358,7 @@ elf_s390_relocate_section (bfd *output_bfd,
|
|||
else
|
||||
{
|
||||
bfd_put_64 (output_bfd, relocation,
|
||||
base_got->contents + off);
|
||||
htab->elf.sgot->contents + off);
|
||||
h->got.offset |= 1;
|
||||
}
|
||||
|
||||
|
@ -2419,7 +2440,7 @@ elf_s390_relocate_section (bfd *output_bfd,
|
|||
if (off >= (bfd_vma) -2)
|
||||
abort ();
|
||||
|
||||
relocation = base_got->output_offset + off;
|
||||
relocation = s390_got_offset (info) + off;
|
||||
|
||||
/* For @GOTENT the relocation is against the offset between
|
||||
the instruction and the symbols entry in the GOT and not
|
||||
|
@ -2427,7 +2448,7 @@ elf_s390_relocate_section (bfd *output_bfd,
|
|||
add the vma of the GOT to get the correct value. */
|
||||
if ( r_type == R_390_GOTENT
|
||||
|| r_type == R_390_GOTPLTENT)
|
||||
relocation += base_got->output_section->vma;
|
||||
relocation += s390_got_pointer (info);
|
||||
|
||||
break;
|
||||
|
||||
|
@ -2445,22 +2466,17 @@ elf_s390_relocate_section (bfd *output_bfd,
|
|||
relocation = (htab->elf.iplt->output_section->vma
|
||||
+ htab->elf.iplt->output_offset
|
||||
+ h->plt.offset
|
||||
- htab->elf.sgot->output_section->vma);
|
||||
- s390_got_pointer (info));
|
||||
goto do_relocation;
|
||||
}
|
||||
|
||||
/* Note that sgot->output_offset is not involved in this
|
||||
calculation. We always want the start of .got. If we
|
||||
defined _GLOBAL_OFFSET_TABLE in a different way, as is
|
||||
permitted by the ABI, we might have to change this
|
||||
calculation. */
|
||||
relocation -= htab->elf.sgot->output_section->vma;
|
||||
relocation -= s390_got_pointer (info);
|
||||
break;
|
||||
|
||||
case R_390_GOTPC:
|
||||
case R_390_GOTPCDBL:
|
||||
/* Use global offset table as symbol value. */
|
||||
relocation = htab->elf.sgot->output_section->vma;
|
||||
relocation = s390_got_pointer (info);
|
||||
unresolved_reloc = FALSE;
|
||||
break;
|
||||
|
||||
|
@ -2509,7 +2525,7 @@ elf_s390_relocate_section (bfd *output_bfd,
|
|||
|| h->plt.offset == (bfd_vma) -1
|
||||
|| (htab->elf.splt == NULL && !s390_is_ifunc_symbol_p (h)))
|
||||
{
|
||||
relocation -= htab->elf.sgot->output_section->vma;
|
||||
relocation -= s390_got_pointer (info);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2517,12 +2533,12 @@ elf_s390_relocate_section (bfd *output_bfd,
|
|||
relocation = (htab->elf.iplt->output_section->vma
|
||||
+ htab->elf.iplt->output_offset
|
||||
+ h->plt.offset
|
||||
- htab->elf.sgot->output_section->vma);
|
||||
- s390_got_pointer (info));
|
||||
else
|
||||
relocation = (htab->elf.splt->output_section->vma
|
||||
+ htab->elf.splt->output_offset
|
||||
+ h->plt.offset
|
||||
- htab->elf.sgot->output_section->vma);
|
||||
- s390_got_pointer (info));
|
||||
unresolved_reloc = FALSE;
|
||||
break;
|
||||
|
||||
|
@ -3296,7 +3312,7 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
|
|||
if (h->plt.offset != (bfd_vma) -1)
|
||||
{
|
||||
bfd_vma plt_index;
|
||||
bfd_vma got_offset;
|
||||
bfd_vma gotplt_offset;
|
||||
Elf_Internal_Rela rela;
|
||||
bfd_byte *loc;
|
||||
|
||||
|
@ -3325,18 +3341,25 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
|
|||
Current offset - size first entry / entry size. */
|
||||
plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) / PLT_ENTRY_SIZE;
|
||||
|
||||
/* Offset in GOT is PLT index plus GOT headers(3) times 8,
|
||||
addr & GOT addr. */
|
||||
got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
|
||||
/* The slots in the .got.plt correspond to the PLT slots in
|
||||
the same order. */
|
||||
gotplt_offset = plt_index * GOT_ENTRY_SIZE;
|
||||
|
||||
/* If .got.plt comes first it needs to contain the 3 header
|
||||
entries. */
|
||||
if (!s390_gotplt_after_got_p (info))
|
||||
gotplt_offset += 3 * GOT_ENTRY_SIZE;
|
||||
|
||||
/* Fill in the blueprint of a PLT. */
|
||||
memcpy (htab->elf.splt->contents + h->plt.offset, elf_s390x_plt_entry,
|
||||
PLT_ENTRY_SIZE);
|
||||
|
||||
/* Fixup the relative address to the GOT entry */
|
||||
/* The first instruction in the PLT entry is a LARL loading
|
||||
the address of the GOT slot. We write the 4 byte
|
||||
immediate operand of the LARL instruction here. */
|
||||
bfd_put_32 (output_bfd,
|
||||
(htab->elf.sgotplt->output_section->vma +
|
||||
htab->elf.sgotplt->output_offset + got_offset
|
||||
htab->elf.sgotplt->output_offset + gotplt_offset
|
||||
- (htab->elf.splt->output_section->vma +
|
||||
htab->elf.splt->output_offset +
|
||||
h->plt.offset))/2,
|
||||
|
@ -3356,12 +3379,12 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
|
|||
+ htab->elf.splt->output_offset
|
||||
+ h->plt.offset
|
||||
+ 14),
|
||||
htab->elf.sgotplt->contents + got_offset);
|
||||
htab->elf.sgotplt->contents + gotplt_offset);
|
||||
|
||||
/* Fill in the entry in the .rela.plt section. */
|
||||
rela.r_offset = (htab->elf.sgotplt->output_section->vma
|
||||
+ htab->elf.sgotplt->output_offset
|
||||
+ got_offset);
|
||||
+ gotplt_offset);
|
||||
rela.r_info = ELF64_R_INFO (h->dynindx, R_390_JMP_SLOT);
|
||||
rela.r_addend = 0;
|
||||
loc = htab->elf.srelplt->contents + plt_index *
|
||||
|
@ -3568,8 +3591,8 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
|
|||
continue;
|
||||
|
||||
case DT_PLTGOT:
|
||||
s = htab->elf.sgotplt;
|
||||
dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
|
||||
/* DT_PLTGOT matches _GLOBAL_OFFSET_TABLE_ */
|
||||
dyn.d_un.d_ptr = s390_got_pointer (info);
|
||||
break;
|
||||
|
||||
case DT_JMPREL:
|
||||
|
@ -3606,10 +3629,11 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
|
|||
/* fill in blueprint for plt 0 entry */
|
||||
memcpy (htab->elf.splt->contents, elf_s390x_first_plt_entry,
|
||||
PLT_FIRST_ENTRY_SIZE);
|
||||
/* Fixup relative address to start of GOT */
|
||||
/* The second instruction in the first PLT entry is a LARL
|
||||
loading the GOT pointer. Fill in the LARL immediate
|
||||
address. */
|
||||
bfd_put_32 (output_bfd,
|
||||
(htab->elf.sgotplt->output_section->vma
|
||||
+ htab->elf.sgotplt->output_offset
|
||||
(s390_got_pointer (info)
|
||||
- htab->elf.splt->output_section->vma
|
||||
- htab->elf.splt->output_offset - 6)/2,
|
||||
htab->elf.splt->contents + 8);
|
||||
|
@ -3619,21 +3643,22 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
|
|||
= PLT_ENTRY_SIZE;
|
||||
}
|
||||
|
||||
if (htab->elf.sgotplt)
|
||||
if (htab->elf.hgot && htab->elf.hgot->root.u.def.section)
|
||||
{
|
||||
/* Fill in the first three entries in the global offset table. */
|
||||
if (htab->elf.sgotplt->size > 0)
|
||||
if (htab->elf.hgot->root.u.def.section->size > 0)
|
||||
{
|
||||
bfd_put_64 (output_bfd,
|
||||
(sdyn == NULL ? (bfd_vma) 0
|
||||
: sdyn->output_section->vma + sdyn->output_offset),
|
||||
htab->elf.sgotplt->contents);
|
||||
htab->elf.hgot->root.u.def.section->contents);
|
||||
/* One entry for shared object struct ptr. */
|
||||
bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + 8);
|
||||
bfd_put_64 (output_bfd, (bfd_vma) 0,
|
||||
htab->elf.hgot->root.u.def.section->contents + 8);
|
||||
/* One entry for _dl_runtime_resolve. */
|
||||
bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + 16);
|
||||
bfd_put_64 (output_bfd, (bfd_vma) 0,
|
||||
htab->elf.hgot->root.u.def.section->contents + 16);
|
||||
}
|
||||
|
||||
elf_section_data (htab->elf.sgot->output_section)
|
||||
->this_hdr.sh_entsize = 8;
|
||||
}
|
||||
|
|
|
@ -11,9 +11,12 @@ NOP=0x07070707
|
|||
TEMPLATE_NAME=elf32
|
||||
GENERATE_SHLIB_SCRIPT=yes
|
||||
GENERATE_PIE_SCRIPT=yes
|
||||
GENERATE_RELRO_SCRIPT=yes
|
||||
NO_SMALL_DATA=yes
|
||||
EXTRA_EM_FILE=s390
|
||||
IREL_IN_PLT=
|
||||
SEPARATE_GOTPLT=0
|
||||
test -z "$RELRO" && unset SEPARATE_GOTPLT
|
||||
|
||||
# Treat a host that matches the target with the possible exception of "x"
|
||||
# in the name as if it were native.
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
tmpdir/gotreloc_64-1: file format elf64-s390
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
.* <foo>:
|
||||
.*: c0 10 00 00 00 0e [ ]*larl %r1,.* <bar>
|
||||
.*: c0 10 00 00 00 0b [ ]*larl %r1,.* <bar>
|
||||
.*: c4 1d 00 00 0f 1a [ ]*lrl %r1,.* <_GLOBAL_OFFSET_TABLE_\+0x18>
|
||||
.*: 58 10 c0 18 [ ]*l %r1,24\(%r12\)
|
||||
.*: e3 10 c0 18 00 58 [ ]*ly %r1,24\(%r12\)
|
||||
.* <bar>:
|
||||
.*: 00 00 01 23 .long 0x00000123
|
|
@ -70,10 +70,15 @@ set s390xtests {
|
|||
{{readelf -WSsrl tlsbin_64.rd} {objdump -dzrj.text tlsbin_64.dd}
|
||||
{objdump -sj.got tlsbin_64.sd} {objdump -sj.tdata tlsbin_64.td}}
|
||||
"tlsbin_64"}
|
||||
{"GOT: symbol address load from got to larl"
|
||||
"-shared -melf64_s390 --hash-style=sysv --version-script=gotreloc-1.ver" ""
|
||||
{"GOT: norelro symbol address load from got to larl"
|
||||
"-shared -melf64_s390 -z norelro --hash-style=sysv --version-script=gotreloc-1.ver" ""
|
||||
"-m64" {gotreloc-1.s}
|
||||
{{objdump -dzrj.text gotreloc_64-1.dd}}
|
||||
{{objdump -dzrj.text gotreloc_64-norelro-1.dd}}
|
||||
"gotreloc_64-1"}
|
||||
{"GOT: relro symbol address load from got to larl"
|
||||
"-shared -melf64_s390 -z relro --hash-style=sysv --version-script=gotreloc-1.ver" ""
|
||||
"-m64" {gotreloc-1.s}
|
||||
{{objdump -dzrj.text gotreloc_64-relro-1.dd}}
|
||||
"gotreloc_64-1"}
|
||||
{"PLT: offset test"
|
||||
"-shared -m elf64_s390 -dT pltoffset-1.ld" ""
|
||||
|
|
Loading…
Reference in New Issue