PowerPC64 EH info for _notoc linkage stubs

This patch generates EH info for the new _notoc linkage stubs, to
support unwinding from asynchronous signal handlers.  Unwinding
through the __tls_get_addr_opt stub was already supported, but that
was just a single stub.  With multiple stubs the EH opcodes need to be
emitted and sized when iterating over stubs, so this is done when
emitting and sizing the stub code.  Emitting the CIEs and FDEs is done
when sizing the stubs, as we did before in order to have the linker
generated FDEs indexed in .eh_frame_hdr.  I moved the final tweaks to
FDEs from ppc64_elf_finish_dynamic_sections to ppc64_elf_build_stubs
simply because it's tidier to be done with them at that point.

bfd/
	* elf64-ppc.c (struct map_stub): Delete tls_get_addr_opt_bctrl.
	Add lr_restore, eh_size and eh_base.
	(eh_advance, eh_advance_size): New functions.
	(build_tls_get_addr_stub): Emit EH info for stub.
	(ppc_build_one_stub): Likewise for _notoc stubs.
	(ppc_size_one_stub): Size EH info for stub.
	(group_sections): Init new map_stub fields.
	(stub_eh_frame_size): Delete.
	(ppc64_elf_size_stubs): Size EH info for stubs.  Set up dummy EH
	program for stubs.
	(ppc64_elf_build_stubs): Reinit new map_stub fields.  Set FDE
	offset to stub section here..
	(ppc64_elf_finish_dynamic_sections): ..rather than here.
ld/
	* testsuite/ld-powerpc/notoc.s: Generate some cfi.
	* testsuite/ld-powerpc/notoc.d: Adjust.
	* testsuite/ld-powerpc/notoc.wf: New file.
	* testsuite/ld-powerpc/powerpc.exp: Run "ext" and "notoc" tests
	as run_ld_link_tests rather than run_dump_test.
This commit is contained in:
Alan Modra 2018-08-06 21:43:51 +09:30
parent e81b4c933c
commit df136d64fa
7 changed files with 316 additions and 148 deletions

View File

@ -1,3 +1,19 @@
2018-08-07 Alan Modra <amodra@gmail.com>
* elf64-ppc.c (struct map_stub): Delete tls_get_addr_opt_bctrl.
Add lr_restore, eh_size and eh_base.
(eh_advance, eh_advance_size): New functions.
(build_tls_get_addr_stub): Emit EH info for stub.
(ppc_build_one_stub): Likewise for _notoc stubs.
(ppc_size_one_stub): Size EH info for stub.
(group_sections): Init new map_stub fields.
(stub_eh_frame_size): Delete.
(ppc64_elf_size_stubs): Size EH info for stubs. Set up dummy EH
program for stubs.
(ppc64_elf_build_stubs): Reinit new map_stub fields. Set FDE
offset to stub section here..
(ppc64_elf_finish_dynamic_sections): ..rather than here.
2018-08-07 Alan Modra <amodra@gmail.com>
* elf64-ppc.c (ppc64_elf_relocate_section): Don't skip first

View File

@ -4113,9 +4113,15 @@ struct map_stub
/* Whether to emit a copy of register save/restore functions in this
group. */
int needs_save_res;
/* The offset of the __tls_get_addr_opt plt stub bctrl in this group,
or -1u if no such stub with bctrl exists. */
unsigned int tls_get_addr_opt_bctrl;
/* Current offset within stubs after the insn restoring lr in a
_notoc or _both stub using bcl for pc-relative addressing, or
after the insn restoring lr in a __tls_get_addr_opt plt stub. */
unsigned int lr_restore;
/* Accumulated size of EH info emitted to describe return address
if stubs modify lr. Does not include 17 byte FDE header. */
unsigned int eh_size;
/* Offset in glink_eh_frame to the start of EH info for this group. */
unsigned int eh_base;
};
struct ppc_stub_hash_entry {
@ -10965,6 +10971,52 @@ size_offset (bfd_vma off)
return size;
}
/* Emit .eh_frame opcode to advance pc by DELTA. */
static bfd_byte *
eh_advance (bfd *abfd, bfd_byte *eh, unsigned int delta)
{
delta /= 4;
if (delta < 64)
*eh++ = DW_CFA_advance_loc + delta;
else if (delta < 256)
{
*eh++ = DW_CFA_advance_loc1;
*eh++ = delta;
}
else if (delta < 65536)
{
*eh++ = DW_CFA_advance_loc2;
bfd_put_16 (abfd, delta, eh);
eh += 2;
}
else
{
*eh++ = DW_CFA_advance_loc4;
bfd_put_32 (abfd, delta, eh);
eh += 4;
}
return eh;
}
/* Size of required .eh_frame opcode to advance pc by DELTA. */
static unsigned int
eh_advance_size (unsigned int delta)
{
if (delta < 64 * 4)
/* DW_CFA_advance_loc+[1..63]. */
return 1;
if (delta < 256 * 4)
/* DW_CFA_advance_loc1, byte. */
return 2;
if (delta < 65536 * 4)
/* DW_CFA_advance_loc2, 2 bytes. */
return 3;
/* DW_CFA_advance_loc4, 4 bytes. */
return 5;
}
/* With power7 weakly ordered memory model, it is possible for ld.so
to update a plt entry in one thread and have another thread see a
stale zero toc entry. To avoid this we need some sort of acquire
@ -11262,6 +11314,7 @@ build_tls_get_addr_stub (struct ppc_link_hash_table *htab,
bfd_byte *p, bfd_vma offset, Elf_Internal_Rela *r)
{
bfd *obfd = htab->params->stub_bfd;
bfd_byte *loc = p;
bfd_put_32 (obfd, LD_R11_0R3 + 0, p), p += 4;
bfd_put_32 (obfd, LD_R12_0R3 + 8, p), p += 4;
@ -11288,6 +11341,26 @@ build_tls_get_addr_stub (struct ppc_link_hash_table *htab,
bfd_put_32 (obfd, MTLR_R11, p), p += 4;
bfd_put_32 (obfd, BLR, p), p += 4;
if (htab->glink_eh_frame != NULL
&& htab->glink_eh_frame->size != 0)
{
bfd_byte *base, *eh;
unsigned int lr_used, delta;
base = htab->glink_eh_frame->contents + stub_entry->group->eh_base + 17;
eh = base + stub_entry->group->eh_size;
lr_used = stub_entry->stub_offset + (p - 20 - loc);
delta = lr_used - stub_entry->group->lr_restore;
stub_entry->group->lr_restore = lr_used + 16;
eh = eh_advance (htab->elf.dynobj, eh, delta);
*eh++ = DW_CFA_offset_extended_sf;
*eh++ = 65;
*eh++ = -(STK_LINKER (htab) / 8) & 0x7f;
*eh++ = DW_CFA_advance_loc + 4;
*eh++ = DW_CFA_restore_extended;
*eh++ = 65;
stub_entry->group->eh_size = eh - base;
}
return p;
}
@ -11707,6 +11780,32 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
bfd_put_32 (htab->params->stub_bfd, BCTR, p);
}
p += 4;
if (htab->glink_eh_frame != NULL
&& htab->glink_eh_frame->size != 0)
{
bfd_byte *base, *eh;
unsigned int lr_used, delta;
base = (htab->glink_eh_frame->contents
+ stub_entry->group->eh_base + 17);
eh = base + stub_entry->group->eh_size;
lr_used = stub_entry->stub_offset + 8;
if (stub_entry->stub_type == ppc_stub_long_branch_both
|| stub_entry->stub_type == ppc_stub_plt_branch_both
|| stub_entry->stub_type == ppc_stub_plt_call_both)
lr_used += 4;
delta = lr_used - stub_entry->group->lr_restore;
stub_entry->group->lr_restore = lr_used + 8;
eh = eh_advance (htab->elf.dynobj, eh, delta);
*eh++ = DW_CFA_register;
*eh++ = 65;
*eh++ = 12;
*eh++ = DW_CFA_advance_loc + 2;
*eh++ = DW_CFA_restore_extended;
*eh++ = 65;
stub_entry->group->eh_size = eh - base;
}
break;
case ppc_stub_plt_call:
@ -11920,15 +12019,45 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
off = targ - off;
size = plt_stub_size (htab, stub_entry, off);
if (stub_entry->stub_type < ppc_stub_plt_call_notoc)
if (stub_entry->stub_type >= ppc_stub_plt_call_notoc)
{
/* After the bcl, lr has been modified so we need to emit
.eh_frame info saying the return address is in r12. */
unsigned int lr_used = stub_entry->stub_offset + 8;
unsigned int delta;
if (stub_entry->stub_type > ppc_stub_plt_call_notoc)
lr_used += 4;
/* The eh_frame info will consist of a DW_CFA_advance_loc or
variant, DW_CFA_register, 65, 12, DW_CFA_advance_loc+2,
DW_CFA_restore_extended 65. */
delta = lr_used - stub_entry->group->lr_restore;
stub_entry->group->eh_size += eh_advance_size (delta) + 6;
stub_entry->group->lr_restore = lr_used + 8;
}
else
{
if (stub_entry->h != NULL
&& (stub_entry->h == htab->tls_get_addr_fd
|| stub_entry->h == htab->tls_get_addr)
&& htab->params->tls_get_addr_opt
&& stub_entry->stub_type == ppc_stub_plt_call_r2save)
stub_entry->group->tls_get_addr_opt_bctrl
= stub_entry->stub_offset + size - 5 * 4;
{
/* After the bctrl, lr has been modified so we need to
emit .eh_frame info saying the return address is
on the stack. In fact we put the EH info specifying
that the return address is on the stack *at* the
call rather than after it, because the EH info for a
call needs to be specified by that point.
See libgcc/unwind-dw2.c execute_cfa_program. */
unsigned int lr_used = stub_entry->stub_offset + size - 20;
unsigned int delta;
/* The eh_frame info will consist of a DW_CFA_advance_loc
or variant, DW_CFA_offset_externed_sf, 65, -stackoff,
DW_CFA_advance_loc+4, DW_CFA_restore_extended, 65. */
delta = lr_used - stub_entry->group->lr_restore;
stub_entry->group->eh_size += eh_advance_size (delta) + 6;
stub_entry->group->lr_restore = size - 4;
}
if (info->emitrelocations)
{
@ -11988,6 +12117,19 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
if (stub_entry->stub_type >= ppc_stub_long_branch_notoc)
{
/* After the bcl, lr has been modified so we need to emit
.eh_frame info saying the return address is in r12. */
unsigned int lr_used = stub_entry->stub_offset + 8;
unsigned int delta;
if (stub_entry->stub_type > ppc_stub_long_branch_notoc)
lr_used += 4;
/* The eh_frame info will consist of a DW_CFA_advance_loc or
variant, DW_CFA_register, 65, 12, DW_CFA_advance_loc+2,
DW_CFA_restore_extended 65. */
delta = lr_used - stub_entry->group->lr_restore;
stub_entry->group->eh_size += eh_advance_size (delta) + 6;
stub_entry->group->lr_restore = lr_used + 8;
if (off + (1 << 25) >= (bfd_vma) (1 << 26))
{
stub_entry->stub_type += (ppc_stub_plt_branch_notoc
@ -12821,7 +12963,9 @@ group_sections (struct bfd_link_info *info,
group->link_sec = curr;
group->stub_sec = NULL;
group->needs_save_res = 0;
group->tls_get_addr_opt_bctrl = -1u;
group->lr_restore = 0;
group->eh_size = 0;
group->eh_base = 0;
group->next = htab->group;
htab->group = group;
do
@ -12872,27 +13016,6 @@ static const unsigned char glink_eh_frame_cie[] =
DW_CFA_def_cfa, 1, 0 /* def_cfa: r1 offset 0. */
};
static size_t
stub_eh_frame_size (struct map_stub *group, size_t align)
{
size_t this_size = 17;
if (group->tls_get_addr_opt_bctrl != -1u)
{
unsigned int to_bctrl = group->tls_get_addr_opt_bctrl / 4;
if (to_bctrl < 64)
this_size += 1;
else if (to_bctrl < 256)
this_size += 2;
else if (to_bctrl < 65536)
this_size += 3;
else
this_size += 5;
this_size += 6;
}
this_size = (this_size + align - 1) & -align;
return this_size;
}
/* Stripping output sections is normally done before dynamic section
symbols have been allocated. This function is called later, and
handles cases like htab->brlt which is mapped to its own output
@ -13394,18 +13517,22 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
/* We may have added some stubs. Find out the new size of the
stub sections. */
for (group = htab->group; group != NULL; group = group->next)
if (group->stub_sec != NULL)
{
asection *stub_sec = group->stub_sec;
{
group->lr_restore = 0;
group->eh_size = 0;
if (group->stub_sec != NULL)
{
asection *stub_sec = group->stub_sec;
if (htab->stub_iteration <= STUB_SHRINK_ITER
|| stub_sec->rawsize < stub_sec->size)
/* Past STUB_SHRINK_ITER, rawsize is the max size seen. */
stub_sec->rawsize = stub_sec->size;
stub_sec->size = 0;
stub_sec->reloc_count = 0;
stub_sec->flags &= ~SEC_RELOC;
}
if (htab->stub_iteration <= STUB_SHRINK_ITER
|| stub_sec->rawsize < stub_sec->size)
/* Past STUB_SHRINK_ITER, rawsize is the max size seen. */
stub_sec->rawsize = stub_sec->size;
stub_sec->size = 0;
stub_sec->reloc_count = 0;
stub_sec->flags &= ~SEC_RELOC;
}
}
if (htab->stub_iteration <= STUB_SHRINK_ITER
|| htab->brlt->rawsize < htab->brlt->size)
@ -13436,8 +13563,8 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
size_t size = 0, align = 4;
for (group = htab->group; group != NULL; group = group->next)
if (group->stub_sec != NULL)
size += stub_eh_frame_size (group, align);
if (group->eh_size != 0)
size += (group->eh_size + 17 + align - 1) & -align;
if (htab->glink != NULL && htab->glink->size != 0)
size += (24 + align - 1) & -align;
if (size != 0)
@ -13484,6 +13611,10 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
size_t last_fde_len, size, align, pad;
struct map_stub *group;
/* It is necessary to at least have a rough outline of the
linker generated CIEs and FDEs written before
bfd_elf_discard_info is run, in order for these FDEs to be
indexed in .eh_frame_hdr. */
p = bfd_zalloc (htab->glink_eh_frame->owner, htab->glink_eh_frame->size);
if (p == NULL)
return FALSE;
@ -13498,10 +13629,11 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
p += last_fde_len + 4;
for (group = htab->group; group != NULL; group = group->next)
if (group->stub_sec != NULL)
if (group->eh_size != 0)
{
group->eh_base = p - htab->glink_eh_frame->contents;
last_fde = p;
last_fde_len = stub_eh_frame_size (group, align) - 4;
last_fde_len = ((group->eh_size + 17 + align - 1) & -align) - 4;
/* FDE length. */
bfd_put_32 (htab->elf.dynobj, last_fde_len, p);
p += 4;
@ -13516,39 +13648,9 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
p += 4;
/* Augmentation. */
p += 1;
if (group->tls_get_addr_opt_bctrl != -1u)
{
unsigned int to_bctrl = group->tls_get_addr_opt_bctrl / 4;
/* This FDE needs more than just the default.
Describe __tls_get_addr_opt stub LR. */
if (to_bctrl < 64)
*p++ = DW_CFA_advance_loc + to_bctrl;
else if (to_bctrl < 256)
{
*p++ = DW_CFA_advance_loc1;
*p++ = to_bctrl;
}
else if (to_bctrl < 65536)
{
*p++ = DW_CFA_advance_loc2;
bfd_put_16 (htab->elf.dynobj, to_bctrl, p);
p += 2;
}
else
{
*p++ = DW_CFA_advance_loc4;
bfd_put_32 (htab->elf.dynobj, to_bctrl, p);
p += 4;
}
*p++ = DW_CFA_offset_extended_sf;
*p++ = 65;
*p++ = -(STK_LINKER (htab) / 8) & 0x7f;
*p++ = DW_CFA_advance_loc + 4;
*p++ = DW_CFA_restore_extended;
*p++ = 65;
}
/* Pad. */
/* Make sure we don't have all nops. This is enough for
elf-eh-frame.c to detect the last non-nop opcode. */
p[group->eh_size - 1] = DW_CFA_advance_loc + 1;
p = last_fde + last_fde_len + 4;
}
if (htab->glink != NULL && htab->glink->size != 0)
@ -14023,14 +14125,19 @@ ppc64_elf_build_stubs (struct bfd_link_info *info,
/* Allocate memory to hold the linker stubs. */
for (group = htab->group; group != NULL; group = group->next)
if ((stub_sec = group->stub_sec) != NULL
&& stub_sec->size != 0)
{
stub_sec->contents = bfd_zalloc (htab->params->stub_bfd, stub_sec->size);
if (stub_sec->contents == NULL)
return FALSE;
stub_sec->size = 0;
}
{
group->eh_size = 0;
group->lr_restore = 0;
if ((stub_sec = group->stub_sec) != NULL
&& stub_sec->size != 0)
{
stub_sec->contents = bfd_zalloc (htab->params->stub_bfd,
stub_sec->size);
if (stub_sec->contents == NULL)
return FALSE;
stub_sec->size = 0;
}
}
if (htab->glink != NULL && htab->glink->size != 0)
{
@ -14213,6 +14320,55 @@ ppc64_elf_build_stubs (struct bfd_link_info *info,
}
}
if (htab->glink_eh_frame != NULL
&& htab->glink_eh_frame->size != 0)
{
bfd_vma val;
size_t align = 4;
p = htab->glink_eh_frame->contents;
p += (sizeof (glink_eh_frame_cie) + align - 1) & -align;
for (group = htab->group; group != NULL; group = group->next)
if (group->eh_size != 0)
{
/* Offset to stub section. */
val = (group->stub_sec->output_section->vma
+ group->stub_sec->output_offset);
val -= (htab->glink_eh_frame->output_section->vma
+ htab->glink_eh_frame->output_offset
+ (p + 8 - htab->glink_eh_frame->contents));
if (val + 0x80000000 > 0xffffffff)
{
_bfd_error_handler
(_("%s offset too large for .eh_frame sdata4 encoding"),
group->stub_sec->name);
return FALSE;
}
bfd_put_32 (htab->elf.dynobj, val, p + 8);
p += (group->eh_size + 17 + 3) & -4;
}
if (htab->glink != NULL && htab->glink->size != 0)
{
/* Offset to .glink. */
val = (htab->glink->output_section->vma
+ htab->glink->output_offset
+ 8);
val -= (htab->glink_eh_frame->output_section->vma
+ htab->glink_eh_frame->output_offset
+ (p + 8 - htab->glink_eh_frame->contents));
if (val + 0x80000000 > 0xffffffff)
{
_bfd_error_handler
(_("%s offset too large for .eh_frame sdata4 encoding"),
htab->glink->name);
return FALSE;
}
bfd_put_32 (htab->elf.dynobj, val, p + 8);
p += (24 + align - 1) & -align;
}
}
for (group = htab->group; group != NULL; group = group->next)
if ((stub_sec = group->stub_sec) != NULL)
{
@ -16745,62 +16901,14 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
NULL))
return FALSE;
if (htab->glink_eh_frame != NULL
&& htab->glink_eh_frame->size != 0)
{
bfd_vma val;
bfd_byte *p;
struct map_stub *group;
size_t align = 4;
p = htab->glink_eh_frame->contents;
p += (sizeof (glink_eh_frame_cie) + align - 1) & -align;
for (group = htab->group; group != NULL; group = group->next)
if (group->stub_sec != NULL)
{
/* Offset to stub section. */
val = (group->stub_sec->output_section->vma
+ group->stub_sec->output_offset);
val -= (htab->glink_eh_frame->output_section->vma
+ htab->glink_eh_frame->output_offset
+ (p + 8 - htab->glink_eh_frame->contents));
if (val + 0x80000000 > 0xffffffff)
{
_bfd_error_handler
(_("%s offset too large for .eh_frame sdata4 encoding"),
group->stub_sec->name);
return FALSE;
}
bfd_put_32 (dynobj, val, p + 8);
p += stub_eh_frame_size (group, align);
}
if (htab->glink != NULL && htab->glink->size != 0)
{
/* Offset to .glink. */
val = (htab->glink->output_section->vma
+ htab->glink->output_offset
+ 8);
val -= (htab->glink_eh_frame->output_section->vma
+ htab->glink_eh_frame->output_offset
+ (p + 8 - htab->glink_eh_frame->contents));
if (val + 0x80000000 > 0xffffffff)
{
_bfd_error_handler
(_("%s offset too large for .eh_frame sdata4 encoding"),
htab->glink->name);
return FALSE;
}
bfd_put_32 (dynobj, val, p + 8);
p += (24 + align - 1) & -align;
}
if (htab->glink_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME
&& !_bfd_elf_write_section_eh_frame (output_bfd, info,
htab->glink_eh_frame,
htab->glink_eh_frame->contents))
return FALSE;
}
&& htab->glink_eh_frame->size != 0
&& htab->glink_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME
&& !_bfd_elf_write_section_eh_frame (output_bfd, info,
htab->glink_eh_frame,
htab->glink_eh_frame->contents))
return FALSE;
/* We need to handle writing out multiple GOT sections ourselves,
since we didn't add them to DYNOBJ. We know dynobj is the first

View File

@ -1,3 +1,11 @@
2018-08-07 Alan Modra <amodra@gmail.com>
* testsuite/ld-powerpc/notoc.s: Generate some cfi.
* testsuite/ld-powerpc/notoc.d: Adjust.
* testsuite/ld-powerpc/notoc.wf: New file.
* testsuite/ld-powerpc/powerpc.exp: Run "ext" and "notoc" tests
as run_ld_link_tests rather than run_dump_test.
2018-08-07 Martin Storsjo <martin@martin.st>
* scripttempl/pe.sc: Improve the comment about overriding

View File

@ -1,7 +1,7 @@
#source: notoc.s
#as: -a64
#ld: --no-plt-localentry -T ext.lnk
#objdump: -dr
#objdump: -d
#target: powerpc64*-*-*
.*
@ -63,8 +63,8 @@ Disassembly of section \.text:
.*: (20 00 80 4e|4e 80 00 20) blr
.* <f2>:
.*: (02 10 40 3c|3c 40 10 02) lis r2,4098
.*: (00 90 42 38|38 42 90 00) addi r2,r2,-28672
.*: (01 10 40 3c|3c 40 10 01) lis r2,4097
.*: (00 80 42 38|38 42 80 00) addi r2,r2,-32768
.*: (4d ff ff 4b|4b ff ff 4d) bl .* <.*\.long_branch\.f1>
.*: (18 00 41 e8|e8 41 00 18) ld r2,24\(r1\)
.*: (f9 ff ff 4b|4b ff ff f9) bl .* <f2\+0x8>
@ -78,8 +78,8 @@ Disassembly of section \.text:
.*: (20 00 80 4e|4e 80 00 20) blr
.* <g2>:
.*: (02 10 40 3c|3c 40 10 02) lis r2,4098
.*: (00 90 42 38|38 42 90 00) addi r2,r2,-28672
.*: (01 10 40 3c|3c 40 10 01) lis r2,4097
.*: (00 80 42 38|38 42 80 00) addi r2,r2,-32768
.*: (cd ff ff 4b|4b ff ff cd) bl .* <f2\+0x8>
.*: (00 00 00 60|60 00 00 00) nop
.*: (11 ff ff 4b|4b ff ff 11) bl .* <.*\.long_branch\.f1>
@ -96,7 +96,7 @@ Disassembly of section \.text:
Disassembly of section \.text\.ext:
8000000000000000 <ext>:
8000000000000000: (02 10 40 3c|3c 40 10 02) lis r2,4098
8000000000000004: (00 90 42 38|38 42 90 00) addi r2,r2,-28672
8000000000000000: (01 10 40 3c|3c 40 10 01) lis r2,4097
8000000000000004: (00 80 42 38|38 42 80 00) addi r2,r2,-32768
8000000000000008: (00 00 00 60|60 00 00 00) nop
800000000000000c: (20 00 80 4e|4e 80 00 20) blr

View File

@ -53,4 +53,6 @@ g2:
blr
_start:
.cfi_startproc
b _start
.cfi_endproc

View File

@ -0,0 +1,33 @@
Contents of the \.eh_frame section:
00000000 0000000000000010 00000000 CIE
Version: 1
Augmentation: "zR"
Code alignment factor: 4
Data alignment factor: -8
Return address column: 65
Augmentation data: 1b
DW_CFA_def_cfa: r1 ofs 0
00000014 0000000000000024 00000018 FDE cie=00000000 pc=00000000100000c0\.\.0000000010000140
DW_CFA_advance_loc: 24 to 00000000100000d8
DW_CFA_register: r65 in r12
DW_CFA_advance_loc: 8 to 00000000100000e0
DW_CFA_restore_extended: r65
DW_CFA_advance_loc: 40 to 0000000010000108
DW_CFA_register: r65 in r12
DW_CFA_advance_loc: 8 to 0000000010000110
DW_CFA_restore_extended: r65
DW_CFA_advance_loc: 16 to 0000000010000120
DW_CFA_register: r65 in r12
DW_CFA_advance_loc: 8 to 0000000010000128
DW_CFA_restore_extended: r65
DW_CFA_nop
DW_CFA_nop
0000003c 0000000000000010 00000040 FDE cie=00000000 pc=00000000100001cc\.\.00000000100001d0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop

View File

@ -257,6 +257,9 @@ set ppc64elftests {
{{objdump -dr tocsave2a.d}} "tocsave2a"}
{"ambig shared v1" "-shared -melf64ppc" "" "-a64" {funv1.s} {} "funv1.so"}
{"ambig shared v2" "-shared -melf64ppc" "" "-a64" {funv2.s} {} "funv2.so"}
{"notoc ext" "" "" "-a64" {ext.s} {} ""}
{"notoc" "-melf64ppc --no-plt-localentry -T ext.lnk" "" "-a64" {notoc.s}
{{objdump -d notoc.d} {readelf {-wf -W} notoc.wf}} "notoc"}
}
set ppceabitests {
@ -331,8 +334,6 @@ if [ supports_ppc64 ] then {
run_dump_test "dotsym2"
run_dump_test "dotsym3"
run_dump_test "dotsym4"
run_dump_test "ext"
run_dump_test "notoc"
}
run_dump_test "tlsld32"