* elf-bfd.h (eh_cie_fde): Add new fields: add_augmentation_size and

add_fde_encoding.  Remove need_relative.
	* elf-eh-frame.c (extra_augmentation_string_bytes)
	(extra_augmentation_data_bytes, size_of_output_cie_fde): New functions.
	(_bfd_elf_discard_section_eh_frame): Consider changing the FDE encoding
	in cases where the CIE has no existing 'R' augmentation.  Use
	size_of_output_cie_fde when assigning offsets.  Use the final offset
	as the new section size.
	(_bfd_elf_eh_frame_section_offset): Remove need_relative handling.
	Account for any extra augmentation bytes in the returned offset.
	(_bfd_elf_write_section_eh_frame): Rework so that the entries are
	moved before being modified.  Pad growing entries with DW_CFA_nops.
	Add 'z' and 'R' augmentations as directed by add_augmentation_size
	and add_fde_encoding.
This commit is contained in:
Richard Sandiford 2004-11-16 10:16:30 +00:00
parent b32d3aa2a0
commit 353057a53c
9 changed files with 1048 additions and 55 deletions

View File

@ -1,3 +1,20 @@
2004-11-16 Richard Sandiford <rsandifo@redhat.com>
* elf-bfd.h (eh_cie_fde): Add new fields: add_augmentation_size and
add_fde_encoding. Remove need_relative.
* elf-eh-frame.c (extra_augmentation_string_bytes)
(extra_augmentation_data_bytes, size_of_output_cie_fde): New functions.
(_bfd_elf_discard_section_eh_frame): Consider changing the FDE encoding
in cases where the CIE has no existing 'R' augmentation. Use
size_of_output_cie_fde when assigning offsets. Use the final offset
as the new section size.
(_bfd_elf_eh_frame_section_offset): Remove need_relative handling.
Account for any extra augmentation bytes in the returned offset.
(_bfd_elf_write_section_eh_frame): Rework so that the entries are
moved before being modified. Pad growing entries with DW_CFA_nops.
Add 'z' and 'R' augmentations as directed by add_augmentation_size
and add_fde_encoding.
2004-11-15 Mark Mitchell <mark@codesourcery.com>
* elf32-arm.c (elf32_arm_relocate_section): Use

View File

@ -296,9 +296,10 @@ struct eh_cie_fde
unsigned char lsda_offset;
unsigned int cie : 1;
unsigned int removed : 1;
unsigned int add_augmentation_size : 1;
unsigned int add_fde_encoding : 1;
unsigned int make_relative : 1;
unsigned int make_lsda_relative : 1;
unsigned int need_relative : 1;
unsigned int need_lsda_relative : 1;
unsigned int per_encoding_relative : 1;
};

View File

@ -200,6 +200,60 @@ int cie_compare (struct cie *c1, struct cie *c2)
return 1;
}
/* Return the number of extra bytes that we'll be inserting into
ENTRY's augmentation string. */
static INLINE unsigned int
extra_augmentation_string_bytes (struct eh_cie_fde *entry)
{
unsigned int size = 0;
if (entry->cie)
{
if (entry->add_augmentation_size)
size++;
if (entry->add_fde_encoding)
size++;
}
return size;
}
/* Likewise ENTRY's augmentation data. */
static INLINE unsigned int
extra_augmentation_data_bytes (struct eh_cie_fde *entry)
{
unsigned int size = 0;
if (entry->cie)
{
if (entry->add_augmentation_size)
size++;
if (entry->add_fde_encoding)
size++;
}
else
{
if (entry->cie_inf->add_augmentation_size)
size++;
}
return size;
}
/* Return the size that ENTRY will have in the output. ALIGNMENT is the
required alignment of ENTRY in bytes. */
static unsigned int
size_of_output_cie_fde (struct eh_cie_fde *entry, unsigned int alignment)
{
if (entry->removed)
return 0;
if (entry->size == 4)
return 4;
return (entry->size
+ extra_augmentation_string_bytes (entry)
+ extra_augmentation_data_bytes (entry)
+ alignment - 1) & -alignment;
}
/* This function is called for each input file before the .eh_frame
section is relocated. It discards duplicate CIEs and FDEs for discarded
functions. The function returns TRUE iff any entries have been
@ -221,7 +275,6 @@ _bfd_elf_discard_section_eh_frame
struct eh_frame_sec_info *sec_info = NULL;
unsigned int leb128_tmp;
unsigned int cie_usage_count, offset;
bfd_size_type new_size;
unsigned int ptr_size;
if (sec->size == 0)
@ -267,7 +320,6 @@ _bfd_elf_discard_section_eh_frame
last_cie_inf = NULL;
memset (&cie, 0, sizeof (cie));
cie_usage_count = 0;
new_size = sec->size;
sec_info = bfd_zmalloc (sizeof (struct eh_frame_sec_info)
+ 99 * sizeof (struct eh_cie_fde));
if (sec_info == NULL)
@ -379,10 +431,7 @@ _bfd_elf_discard_section_eh_frame
== hdr_info->last_cie_sec->output_section)
&& cie_compare (&cie, &hdr_info->last_cie) == 0)
|| cie_usage_count == 0)
{
new_size -= cie.hdr.length + 4;
last_cie_inf->removed = 1;
}
last_cie_inf->removed = 1;
else
{
hdr_info->last_cie = cie;
@ -517,9 +566,22 @@ _bfd_elf_discard_section_eh_frame
if (info->shared
&& (get_elf_backend_data (abfd)
->elf_backend_can_make_relative_eh_frame
(abfd, info, sec))
&& (cie.fde_encoding & 0xf0) == DW_EH_PE_absptr)
cie.make_relative = 1;
(abfd, info, sec)))
{
if ((cie.fde_encoding & 0xf0) == DW_EH_PE_absptr)
cie.make_relative = 1;
/* If the CIE doesn't already have an 'R' entry, it's fairly
easy to add one, provided that there's no aligned data
after the augmentation string. */
else if (cie.fde_encoding == DW_EH_PE_omit
&& (cie.per_encoding & 0xf0) != DW_EH_PE_aligned)
{
if (*cie.augmentation == 0)
this_inf->add_augmentation_size = 1;
this_inf->add_fde_encoding = 1;
cie.make_relative = 1;
}
}
if (info->shared
&& (get_elf_backend_data (abfd)
@ -556,12 +618,9 @@ _bfd_elf_discard_section_eh_frame
goto free_no_table;
if ((*reloc_symbol_deleted_p) (buf - ehbuf, cookie))
{
/* This is a FDE against a discarded section. It should
be deleted. */
new_size -= hdr.length + 4;
this_inf->removed = 1;
}
/* This is a FDE against a discarded section. It should
be deleted. */
this_inf->removed = 1;
else
{
if (info->shared
@ -608,23 +667,23 @@ _bfd_elf_discard_section_eh_frame
for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
if (!ent->removed)
{
ent->new_offset = offset;
offset += ent->size;
if (ent->cie)
last_cie_inf = ent;
else
ent->cie_inf = last_cie_inf;
ent->new_offset = offset;
offset += size_of_output_cie_fde (ent, ptr_size);
}
hdr_info->last_cie_inf = last_cie_inf;
/* Shrink the sec as needed. */
/* Resize the sec as needed. */
sec->rawsize = sec->size;
sec->size = new_size;
sec->size = offset;
if (sec->size == 0)
sec->flags |= SEC_EXCLUDE;
free (ehbuf);
return new_size != sec->rawsize;
return offset != sec->rawsize;
free_no_table:
if (ehbuf)
@ -762,13 +821,8 @@ _bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED,
relocation against FDE's initial_location field. */
if (!sec_info->entry[mid].cie
&& sec_info->entry[mid].cie_inf->make_relative
&& offset == sec_info->entry[mid].offset + 8
&& (sec_info->entry[mid].cie_inf->need_relative
|| !hdr_info->offsets_adjusted))
{
sec_info->entry[mid].cie_inf->need_relative = 1;
return (bfd_vma) -2;
}
&& offset == sec_info->entry[mid].offset + 8)
return (bfd_vma) -2;
/* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
for run-time relocation against LSDA field. */
@ -785,8 +839,11 @@ _bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED,
if (hdr_info->offsets_adjusted)
offset -= sec->output_offset;
/* Any new augmentation bytes go before the first relocation. */
return (offset + sec_info->entry[mid].new_offset
- sec_info->entry[mid].offset);
- sec_info->entry[mid].offset
+ extra_augmentation_string_bytes (sec_info->entry + mid)
+ extra_augmentation_data_bytes (sec_info->entry + mid));
}
/* Write out .eh_frame section. This is called with the relocated
@ -801,7 +858,6 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
struct eh_frame_sec_info *sec_info;
struct elf_link_hash_table *htab;
struct eh_frame_hdr_info *hdr_info;
bfd_byte *p, *buf;
unsigned int leb128_tmp;
unsigned int ptr_size;
struct eh_cie_fde *ent;
@ -854,29 +910,66 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
if (hdr_info->array == NULL)
hdr_info = NULL;
p = contents;
/* The new offsets can be bigger or smaller than the original offsets.
We therefore need to make two passes over the section: one backward
pass to move entries up and one forward pass to move entries down.
The two passes won't interfere with each other because entries are
not reordered */
for (ent = sec_info->entry + sec_info->count; ent-- != sec_info->entry;)
if (!ent->removed && ent->new_offset > ent->offset)
memmove (contents + ent->new_offset - sec->output_offset,
contents + ent->offset - sec->output_offset, ent->size);
for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
if (!ent->removed && ent->new_offset < ent->offset)
memmove (contents + ent->new_offset - sec->output_offset,
contents + ent->offset - sec->output_offset, ent->size);
for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
{
unsigned char *buf, *end;
unsigned int new_size;
if (ent->removed)
continue;
if (ent->size == 4)
{
/* Any terminating FDE must be at the end of the section. */
BFD_ASSERT (ent == sec_info->entry + sec_info->count - 1);
continue;
}
buf = contents + ent->new_offset - sec->output_offset;
end = buf + ent->size;
new_size = size_of_output_cie_fde (ent, ptr_size);
/* Install the new size, filling the extra bytes with DW_CFA_nops. */
if (new_size != ent->size)
{
memset (end, 0, new_size - ent->size);
bfd_put_32 (abfd, new_size - 4, buf);
}
if (ent->cie)
{
/* CIE */
if (ent->need_relative
if (ent->make_relative
|| ent->need_lsda_relative
|| ent->per_encoding_relative)
{
unsigned char *aug;
unsigned int action;
unsigned int action, extra_string, extra_data;
unsigned int dummy, per_width, per_encoding;
/* Need to find 'R' or 'L' augmentation's argument and modify
DW_EH_PE_* value. */
action = ((ent->need_relative ? 1 : 0)
action = ((ent->make_relative ? 1 : 0)
| (ent->need_lsda_relative ? 2 : 0)
| (ent->per_encoding_relative ? 4 : 0));
buf = contents + ent->offset - sec->output_offset;
extra_string = extra_augmentation_string_bytes (ent);
extra_data = extra_augmentation_data_bytes (ent);
/* Skip length, id and version. */
buf += 9;
aug = buf;
@ -886,10 +979,30 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
read_uleb128 (dummy, buf);
if (*aug == 'z')
{
read_uleb128 (dummy, buf);
/* The uleb128 will always be a single byte for the kind
of augmentation strings that we're prepared to handle. */
*buf++ += extra_data;
aug++;
}
/* Make room for the new augmentation string and data bytes. */
memmove (buf + extra_string + extra_data, buf, end - buf);
memmove (aug + extra_string, aug, buf - aug);
buf += extra_string;
if (ent->add_augmentation_size)
{
*aug++ = 'z';
*buf++ = extra_data - 1;
}
if (ent->add_fde_encoding)
{
BFD_ASSERT (action & 1);
*aug++ = 'R';
*buf++ = DW_EH_PE_pcrel;
action &= ~1;
}
while (action)
switch (*aug++)
{
@ -919,6 +1032,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
val = read_value (abfd, buf, per_width,
get_DW_EH_PE_signed (per_encoding));
val += ent->offset - ent->new_offset;
val -= extra_string + extra_data;
write_value (abfd, buf, val, per_width);
action &= ~4;
}
@ -938,13 +1052,12 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
}
}
}
else if (ent->size > 4)
else
{
/* FDE */
bfd_vma value, address;
unsigned int width;
buf = contents + ent->offset - sec->output_offset;
/* Skip length. */
buf += 4;
value = ent->new_offset + 4 - ent->cie_inf->new_offset;
@ -975,7 +1088,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
address += sec->output_section->vma + ent->offset + 8;
break;
}
if (ent->cie_inf->need_relative)
if (ent->cie_inf->make_relative)
value -= sec->output_section->vma + ent->new_offset + 8;
write_value (abfd, buf, value, width);
}
@ -1004,14 +1117,15 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
write_value (abfd, buf, value, width);
}
}
else if (ent->cie_inf->add_augmentation_size)
{
/* Skip the PC and length and insert a zero byte for the
augmentation size. */
buf += width * 2;
memmove (buf + 1, buf, end - buf);
*buf = 0;
}
}
else
/* Terminating FDE must be at the end of .eh_frame section only. */
BFD_ASSERT (ent == sec_info->entry + sec_info->count - 1);
BFD_ASSERT (p == contents + ent->new_offset - sec->output_offset);
memmove (p, contents + ent->offset - sec->output_offset, ent->size);
p += ent->size;
}
{
@ -1024,6 +1138,9 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
&& ((sec->output_offset + sec->size + pad)
<= sec->output_section->size))
{
bfd_byte *buf;
unsigned int new_size;
/* Find the last CIE/FDE. */
ent = sec_info->entry + sec_info->count;
while (--ent != sec_info->entry)
@ -1035,23 +1152,17 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
abort ();
pad = alignment - pad;
buf = contents + ent->new_offset - sec->output_offset;
/* Update length. */
ent->size += pad;
bfd_put_32 (abfd, ent->size - 4, buf);
new_size = size_of_output_cie_fde (ent, ptr_size);
/* Pad it with DW_CFA_nop */
memset (p, 0, pad);
p += pad;
memset (buf + new_size, 0, pad);
bfd_put_32 (abfd, new_size + pad - 4, buf);
sec->size += pad;
}
}
BFD_ASSERT ((bfd_size_type) (p - contents) == sec->size);
return bfd_set_section_contents (abfd, sec->output_section,
contents, (file_ptr) sec->output_offset,
sec->size);

View File

@ -1,3 +1,9 @@
2004-11-16 Richard Sandiford <rsandifo@redhat.com>
* ld-mips-elf/eh-frame1.{s,ld},
* ld-mips-elf/eh-frame1-{n32,n64},d: New test.
* ld-mips-elf/mips-elf.exp: Run it.
2004-11-10 Alan Modra <amodra@bigpond.net.au>
* ld-d10v/reloc-003.d: Update for changed error message.

View File

@ -0,0 +1,263 @@
#name: MIPS eh-frame 1, n32
#source: eh-frame1.s
#source: eh-frame1.s
#as: -EB -n32 --defsym alignment=2 --defsym fill=0x40
#readelf: --relocs -wf
#ld: -shared -melf32btsmipn32 -Teh-frame1.ld
Relocation section '\.rel\.dyn' .*:
*Offset .*
00000000 00000000 R_MIPS_NONE *
# Initial PCs for the FDEs attached to CIE 0xbc
000300dc 00000003 R_MIPS_REL32 *
000300f0 00000003 R_MIPS_REL32 *
# Likewise CIE 0x220
00030240 00000003 R_MIPS_REL32 *
00030254 00000003 R_MIPS_REL32 *
0003008b 00000503 R_MIPS_REL32 00000000 foo
000300d0 00000503 R_MIPS_REL32 00000000 foo
0003010e 00000503 R_MIPS_REL32 00000000 foo
000301ef 00000503 R_MIPS_REL32 00000000 foo
00030234 00000503 R_MIPS_REL32 00000000 foo
00030272 00000503 R_MIPS_REL32 00000000 foo
#...
The section \.eh_frame contains:
00000000 00000010 00000000 CIE
Version: 1
Augmentation: "zR"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 10
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
00000014 00000010 00000018 FDE cie=00000000 pc=00020000..00020010
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000028 00000010 0000002c FDE cie=00000000 pc=00020010..00020030
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
# basic2 removed
0000003c 00000010 00000040 FDE cie=00000000 pc=00020030..00020060
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
# basic3 removed
00000050 00000010 00000054 FDE cie=00000000 pc=00020060..000200a0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
# basic4 removed
00000064 00000010 00000068 FDE cie=00000000 pc=000200a0..000200f0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000078 00000018 00000000 CIE
Version: 1
Augmentation: "zRP"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 10 00 00 00 00 00
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_nop
DW_CFA_nop
00000094 00000010 00000020 FDE cie=00000078 pc=000200f0..00020100
DW_CFA_advance_loc: 0 to 000200f0
DW_CFA_advance_loc: 0 to 000200f0
DW_CFA_advance_loc: 0 to 000200f0
000000a8 00000010 00000034 FDE cie=00000078 pc=00020100..00020120
DW_CFA_advance_loc: 0 to 00020100
DW_CFA_advance_loc: 0 to 00020100
DW_CFA_advance_loc: 0 to 00020100
000000bc 00000014 00000000 CIE
Version: 1
Augmentation: "zP"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 50 00 00 00 00 00 00 00
000000d4 00000010 0000001c FDE cie=000000bc pc=00020120..00020130
DW_CFA_advance_loc: 0 to 00020120
DW_CFA_advance_loc: 0 to 00020120
DW_CFA_advance_loc: 0 to 00020120
000000e8 00000010 00000030 FDE cie=000000bc pc=00020130..00020150
DW_CFA_advance_loc: 0 to 00020130
DW_CFA_advance_loc: 0 to 00020130
DW_CFA_advance_loc: 0 to 00020130
000000fc 00000014 00000000 CIE
Version: 1
Augmentation: "zPR"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 00 00 00 00 00 10
DW_CFA_advance_loc: 0 to 00000000
00000114 00000010 0000001c FDE cie=000000fc pc=00020150..00020160
DW_CFA_advance_loc: 0 to 00020150
DW_CFA_advance_loc: 0 to 00020150
DW_CFA_advance_loc: 0 to 00020150
# FDE for .discard removed
# zPR2 removed
00000128 00000010 00000030 FDE cie=000000fc pc=00020160..00020190
DW_CFA_advance_loc: 0 to 00020160
DW_CFA_advance_loc: 0 to 00020160
DW_CFA_advance_loc: 0 to 00020160
0000013c 00000010 00000044 FDE cie=000000fc pc=00020190..000201d0
DW_CFA_advance_loc: 0 to 00020190
DW_CFA_advance_loc: 0 to 00020190
DW_CFA_advance_loc: 0 to 00020190
00000150 00000010 00000000 CIE
Version: 1
Augmentation: "zR"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 10
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
00000164 00000010 00000018 FDE cie=00000150 pc=000201d0..000201e0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
# basic1 removed, followed by repeat of above
00000178 00000010 0000002c FDE cie=00000150 pc=000201e0..000201f0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
0000018c 00000010 00000040 FDE cie=00000150 pc=000201f0..00020210
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000001a0 00000010 00000054 FDE cie=00000150 pc=00020210..00020240
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000001b4 00000010 00000068 FDE cie=00000150 pc=00020240..00020280
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000001c8 00000010 0000007c FDE cie=00000150 pc=00020280..000202d0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000001dc 00000018 00000000 CIE
Version: 1
Augmentation: "zRP"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 10 00 00 00 00 00
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_nop
DW_CFA_nop
000001f8 00000010 00000020 FDE cie=000001dc pc=000202d0..000202e0
DW_CFA_advance_loc: 0 to 000202d0
DW_CFA_advance_loc: 0 to 000202d0
DW_CFA_advance_loc: 0 to 000202d0
0000020c 00000010 00000034 FDE cie=000001dc pc=000202e0..00020300
DW_CFA_advance_loc: 0 to 000202e0
DW_CFA_advance_loc: 0 to 000202e0
DW_CFA_advance_loc: 0 to 000202e0
00000220 00000014 00000000 CIE
Version: 1
Augmentation: "zP"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 50 00 00 00 00 00 00 00
00000238 00000010 0000001c FDE cie=00000220 pc=00020300..00020310
DW_CFA_advance_loc: 0 to 00020300
DW_CFA_advance_loc: 0 to 00020300
DW_CFA_advance_loc: 0 to 00020300
0000024c 00000010 00000030 FDE cie=00000220 pc=00020310..00020330
DW_CFA_advance_loc: 0 to 00020310
DW_CFA_advance_loc: 0 to 00020310
DW_CFA_advance_loc: 0 to 00020310
00000260 00000014 00000000 CIE
Version: 1
Augmentation: "zPR"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 00 00 00 00 00 10
DW_CFA_advance_loc: 0 to 00000000
00000278 00000010 0000001c FDE cie=00000260 pc=00020330..00020340
DW_CFA_advance_loc: 0 to 00020330
DW_CFA_advance_loc: 0 to 00020330
DW_CFA_advance_loc: 0 to 00020330
0000028c 00000010 00000030 FDE cie=00000260 pc=00020340..00020370
DW_CFA_advance_loc: 0 to 00020340
DW_CFA_advance_loc: 0 to 00020340
DW_CFA_advance_loc: 0 to 00020340
000002a0 00000010 00000044 FDE cie=00000260 pc=00020370..000203b0
DW_CFA_advance_loc: 0 to 00020370
DW_CFA_advance_loc: 0 to 00020370
DW_CFA_advance_loc: 0 to 00020370
000002b4 00000010 00000000 CIE
Version: 1
Augmentation: "zR"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 10
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
000002c8 00000010 00000018 FDE cie=000002b4 pc=000203b0..000203c0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop

View File

@ -0,0 +1,425 @@
#name: MIPS eh-frame 1, n64
#source: eh-frame1.s
#source: eh-frame1.s
#as: -EB -64 --defsym alignment=3 --defsym fill=0x40
#readelf: --relocs -wf
#ld: -shared -melf64btsmip -Teh-frame1.ld
Relocation section '\.rel\.dyn' .*:
*Offset .*
000000000000 000000000000 R_MIPS_NONE *
*Type2: R_MIPS_NONE *
*Type3: R_MIPS_NONE *
# Initial PCs for the FDEs attached to CIE 0x120
000000030148 000000001203 R_MIPS_REL32 *
*Type2: R_MIPS_64 *
*Type3: R_MIPS_NONE *
000000030168 000000001203 R_MIPS_REL32 *
*Type2: R_MIPS_64 *
*Type3: R_MIPS_NONE *
# Likewise CIE 0x340
000000030368 000000001203 R_MIPS_REL32 *
*Type2: R_MIPS_64 *
*Type3: R_MIPS_NONE *
000000030388 000000001203 R_MIPS_REL32 *
*Type2: R_MIPS_64 *
*Type3: R_MIPS_NONE *
0000000300cb 000500001203 R_MIPS_REL32 0000000000000000 foo
*Type2: R_MIPS_64 *
*Type3: R_MIPS_NONE *
000000030138 000500001203 R_MIPS_REL32 0000000000000000 foo
*Type2: R_MIPS_64 *
*Type3: R_MIPS_NONE *
000000030192 000500001203 R_MIPS_REL32 0000000000000000 foo
*Type2: R_MIPS_64 *
*Type3: R_MIPS_NONE *
0000000302eb 000500001203 R_MIPS_REL32 0000000000000000 foo
*Type2: R_MIPS_64 *
*Type3: R_MIPS_NONE *
000000030358 000500001203 R_MIPS_REL32 0000000000000000 foo
*Type2: R_MIPS_64 *
*Type3: R_MIPS_NONE *
0000000303b2 000500001203 R_MIPS_REL32 0000000000000000 foo
*Type2: R_MIPS_64 *
*Type3: R_MIPS_NONE *
#...
The section \.eh_frame contains:
00000000 00000014 00000000 CIE
Version: 1
Augmentation: "zR"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 10
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000018 0000001c 0000001c FDE cie=00000000 pc=00020000..00020010
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000038 0000001c 0000003c FDE cie=00000000 pc=00020010..00020030
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
# basic2 removed
00000058 0000001c 0000005c FDE cie=00000000 pc=00020030..00020060
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
# basic3 removed
00000078 0000001c 0000007c FDE cie=00000000 pc=00020060..000200a0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
# basic4 removed
00000098 0000001c 0000009c FDE cie=00000000 pc=000200a0..000200f0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000000b8 00000024 00000000 CIE
Version: 1
Augmentation: "zRP"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 10 00 00 00 00 00 00 00 00 00
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000000e0 0000001c 0000002c FDE cie=000000b8 pc=000200f0..00020100
DW_CFA_advance_loc: 0 to 000200f0
DW_CFA_advance_loc: 0 to 000200f0
DW_CFA_advance_loc: 0 to 000200f0
DW_CFA_advance_loc: 0 to 000200f0
DW_CFA_advance_loc: 0 to 000200f0
DW_CFA_advance_loc: 0 to 000200f0
DW_CFA_advance_loc: 0 to 000200f0
00000100 0000001c 0000004c FDE cie=000000b8 pc=00020100..00020120
DW_CFA_advance_loc: 0 to 00020100
DW_CFA_advance_loc: 0 to 00020100
DW_CFA_advance_loc: 0 to 00020100
DW_CFA_advance_loc: 0 to 00020100
DW_CFA_advance_loc: 0 to 00020100
DW_CFA_advance_loc: 0 to 00020100
DW_CFA_advance_loc: 0 to 00020100
00000120 0000001c 00000000 CIE
Version: 1
Augmentation: "zP"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000140 0000001c 00000024 FDE cie=00000120 pc=00020120..00020130
DW_CFA_advance_loc: 0 to 00020120
DW_CFA_advance_loc: 0 to 00020120
DW_CFA_advance_loc: 0 to 00020120
DW_CFA_advance_loc: 0 to 00020120
DW_CFA_advance_loc: 0 to 00020120
DW_CFA_advance_loc: 0 to 00020120
DW_CFA_advance_loc: 0 to 00020120
00000160 0000001c 00000044 FDE cie=00000120 pc=00020130..00020150
DW_CFA_advance_loc: 0 to 00020130
DW_CFA_advance_loc: 0 to 00020130
DW_CFA_advance_loc: 0 to 00020130
DW_CFA_advance_loc: 0 to 00020130
DW_CFA_advance_loc: 0 to 00020130
DW_CFA_advance_loc: 0 to 00020130
DW_CFA_advance_loc: 0 to 00020130
00000180 0000001c 00000000 CIE
Version: 1
Augmentation: "zPR"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 00 00 00 00 00 00 00 00 00 10
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
000001a0 0000001c 00000024 FDE cie=00000180 pc=00020150..00020160
DW_CFA_advance_loc: 0 to 00020150
DW_CFA_advance_loc: 0 to 00020150
DW_CFA_advance_loc: 0 to 00020150
DW_CFA_advance_loc: 0 to 00020150
DW_CFA_advance_loc: 0 to 00020150
DW_CFA_advance_loc: 0 to 00020150
DW_CFA_advance_loc: 0 to 00020150
# FDE for .discard removed
# zPR2 removed
000001c0 0000001c 00000044 FDE cie=00000180 pc=00020160..00020190
DW_CFA_advance_loc: 0 to 00020160
DW_CFA_advance_loc: 0 to 00020160
DW_CFA_advance_loc: 0 to 00020160
DW_CFA_advance_loc: 0 to 00020160
DW_CFA_advance_loc: 0 to 00020160
DW_CFA_advance_loc: 0 to 00020160
DW_CFA_advance_loc: 0 to 00020160
000001e0 0000001c 00000064 FDE cie=00000180 pc=00020190..000201d0
DW_CFA_advance_loc: 0 to 00020190
DW_CFA_advance_loc: 0 to 00020190
DW_CFA_advance_loc: 0 to 00020190
DW_CFA_advance_loc: 0 to 00020190
DW_CFA_advance_loc: 0 to 00020190
DW_CFA_advance_loc: 0 to 00020190
DW_CFA_advance_loc: 0 to 00020190
00000200 00000014 00000000 CIE
Version: 1
Augmentation: "zR"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 10
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000218 0000001c 0000001c FDE cie=00000200 pc=000201d0..000201e0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
# basic1 removed, followed by repeat of above
00000238 0000001c 0000003c FDE cie=00000200 pc=000201e0..000201f0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000258 0000001c 0000005c FDE cie=00000200 pc=000201f0..00020210
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000278 0000001c 0000007c FDE cie=00000200 pc=00020210..00020240
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000298 0000001c 0000009c FDE cie=00000200 pc=00020240..00020280
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000002b8 0000001c 000000bc FDE cie=00000200 pc=00020280..000202d0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000002d8 00000024 00000000 CIE
Version: 1
Augmentation: "zRP"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 10 00 00 00 00 00 00 00 00 00
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000300 0000001c 0000002c FDE cie=000002d8 pc=000202d0..000202e0
DW_CFA_advance_loc: 0 to 000202d0
DW_CFA_advance_loc: 0 to 000202d0
DW_CFA_advance_loc: 0 to 000202d0
DW_CFA_advance_loc: 0 to 000202d0
DW_CFA_advance_loc: 0 to 000202d0
DW_CFA_advance_loc: 0 to 000202d0
DW_CFA_advance_loc: 0 to 000202d0
00000320 0000001c 0000004c FDE cie=000002d8 pc=000202e0..00020300
DW_CFA_advance_loc: 0 to 000202e0
DW_CFA_advance_loc: 0 to 000202e0
DW_CFA_advance_loc: 0 to 000202e0
DW_CFA_advance_loc: 0 to 000202e0
DW_CFA_advance_loc: 0 to 000202e0
DW_CFA_advance_loc: 0 to 000202e0
DW_CFA_advance_loc: 0 to 000202e0
00000340 0000001c 00000000 CIE
Version: 1
Augmentation: "zP"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000360 0000001c 00000024 FDE cie=00000340 pc=00020300..00020310
DW_CFA_advance_loc: 0 to 00020300
DW_CFA_advance_loc: 0 to 00020300
DW_CFA_advance_loc: 0 to 00020300
DW_CFA_advance_loc: 0 to 00020300
DW_CFA_advance_loc: 0 to 00020300
DW_CFA_advance_loc: 0 to 00020300
DW_CFA_advance_loc: 0 to 00020300
00000380 0000001c 00000044 FDE cie=00000340 pc=00020310..00020330
DW_CFA_advance_loc: 0 to 00020310
DW_CFA_advance_loc: 0 to 00020310
DW_CFA_advance_loc: 0 to 00020310
DW_CFA_advance_loc: 0 to 00020310
DW_CFA_advance_loc: 0 to 00020310
DW_CFA_advance_loc: 0 to 00020310
DW_CFA_advance_loc: 0 to 00020310
000003a0 0000001c 00000000 CIE
Version: 1
Augmentation: "zPR"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 00 00 00 00 00 00 00 00 00 10
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
000003c0 0000001c 00000024 FDE cie=000003a0 pc=00020330..00020340
DW_CFA_advance_loc: 0 to 00020330
DW_CFA_advance_loc: 0 to 00020330
DW_CFA_advance_loc: 0 to 00020330
DW_CFA_advance_loc: 0 to 00020330
DW_CFA_advance_loc: 0 to 00020330
DW_CFA_advance_loc: 0 to 00020330
DW_CFA_advance_loc: 0 to 00020330
000003e0 0000001c 00000044 FDE cie=000003a0 pc=00020340..00020370
DW_CFA_advance_loc: 0 to 00020340
DW_CFA_advance_loc: 0 to 00020340
DW_CFA_advance_loc: 0 to 00020340
DW_CFA_advance_loc: 0 to 00020340
DW_CFA_advance_loc: 0 to 00020340
DW_CFA_advance_loc: 0 to 00020340
DW_CFA_advance_loc: 0 to 00020340
00000400 0000001c 00000064 FDE cie=000003a0 pc=00020370..000203b0
DW_CFA_advance_loc: 0 to 00020370
DW_CFA_advance_loc: 0 to 00020370
DW_CFA_advance_loc: 0 to 00020370
DW_CFA_advance_loc: 0 to 00020370
DW_CFA_advance_loc: 0 to 00020370
DW_CFA_advance_loc: 0 to 00020370
DW_CFA_advance_loc: 0 to 00020370
00000420 00000014 00000000 CIE
Version: 1
Augmentation: "zR"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 10
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_advance_loc: 0 to 00000000
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000438 0000001c 0000001c FDE cie=00000420 pc=000203b0..000203c0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop

View File

@ -0,0 +1,18 @@
SECTIONS
{
. = 0x10000;
.dynamic : { *(.dynamic) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.dyn : { *(.rel.dyn) }
. = 0x20000;
.text : { *(.text) }
. = 0x30000;
.eh_frame : { *(.eh_frame) }
.got : { *(.got) }
/DISCARD/ : { *(*) }
}

View File

@ -0,0 +1,148 @@
#----------------------------------------------------------------------------
# Macros
#----------------------------------------------------------------------------
mask = (1 << alignment) - 1
# Output VALUE as an unaligned pointer-sized quantity.
.macro pbyte value
.if alignment == 2
.4byte \value
.else
.8byte \value
.endif
.endm
# Start a new CIE, and emit everything up to the augmentation data.
# Use LABEL to mark the start of the entry and AUG as the augmentation
# string.
.macro start_cie label,aug
.section .eh_frame,"aw",@progbits
\label:
.word 2f-1f # Length
1:
.word 0 # Identifier
.byte 1 # Version
.string "\aug" # Augmentation
.byte 1 # Code alignment
.byte 4 # Data alignment
.byte 31 # Return address column
.endm
# Create a dummy function of SIZE bytes in SECTION and emit the
# first four entries of an FDE for it.
.macro start_fde cie,section,size
.section \section,"ax",@progbits
3:
.rept \size / 4
nop
.endr
4:
.section .eh_frame,"aw",@progbits
.word 2f-1f # Length
1:
.word .-\cie # CIE offset
pbyte 3b # Initial PC
pbyte 4b-3b # Size of code
.endm
# Finish a CIE or FDE entry.
.macro end_entry
.p2align alignment,fill
2:
.endm
# Start the augmentation data for a CIE that has a 'P' entry
# followed by EXTRA bytes. AUGLEN is the length of augmentation
# string (including zero terminator), ENCODING is the encoding to
# use for the personality routine and VALUE is the value it
# should have.
.macro persaug auglen,extra,encoding,value
.if (\encoding & 0xf0) == 0x50
.byte (-(9 + \auglen + 3 + 2) & mask) + 2 + mask + \extra
.byte \encoding
.fill -(9 + \auglen + 3 + 2) & mask,1,0
.else
.byte 2 + mask + \extra
.byte \encoding
.endif
pbyte \value
.endm
.macro cie_basic label
start_cie \label,""
end_entry
.endm
.macro fde_basic cie,section,size
start_fde \cie,\section,\size
end_entry
.endm
.macro cie_zP label,encoding,value
start_cie \label,"zP"
persaug 3,0,\encoding,\value
end_entry
.endm
.macro fde_zP cie,section,size
start_fde \cie,\section,\size
.byte 0 # Augmentation length
end_entry
.endm
.macro cie_zPR label,encoding,value
start_cie \label,"zPR"
persaug 4,1,\encoding,\value
.byte 0 # FDE enconding
end_entry
.endm
.macro fde_zPR cie,section,size
start_fde \cie,\section,\size
.byte 0 # Augmentation length
end_entry
.endm
#----------------------------------------------------------------------------
# Test code
#----------------------------------------------------------------------------
cie_basic basic1
fde_basic basic1,.text,0x10
fde_basic basic1,.text,0x20
cie_basic basic2
fde_basic basic2,.text,0x30
cie_basic basic3
fde_basic basic3,.text,0x40
cie_basic basic4
fde_basic basic4,.text,0x50
cie_zP zP_unalign1,0x00,foo
fde_zP zP_unalign1,.text,0x10
fde_zP zP_unalign1,.text,0x20
cie_zP zP_align1,0x50,foo
fde_zP zP_align1,.text,0x10
fde_zP zP_align1,.text,0x20
cie_zPR zPR1,0x00,foo
fde_zPR zPR1,.text,0x10
fde_zPR zPR1,.discard,0x20
cie_zPR zPR2,0x00,foo
fde_zPR zPR2,.text,0x30
fde_zPR zPR2,.text,0x40
cie_basic basic5
fde_basic basic5,.text,0x10

View File

@ -75,3 +75,7 @@ if $has_newabi {
}
run_dump_test "reloc-2"
run_dump_test "reloc-merge-lo16"
if {$has_newabi && $linux_gnu} {
run_dump_test "eh-frame1-n32"
run_dump_test "eh-frame1-n64"
}