diff options
-rw-r--r-- | bfd/ChangeLog | 17 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 3 | ||||
-rw-r--r-- | bfd/elf-eh-frame.c | 219 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | ld/testsuite/ld-mips-elf/eh-frame1-n32.d | 263 | ||||
-rw-r--r-- | ld/testsuite/ld-mips-elf/eh-frame1-n64.d | 425 | ||||
-rw-r--r-- | ld/testsuite/ld-mips-elf/eh-frame1.ld | 18 | ||||
-rw-r--r-- | ld/testsuite/ld-mips-elf/eh-frame1.s | 148 | ||||
-rw-r--r-- | ld/testsuite/ld-mips-elf/mips-elf.exp | 4 |
9 files changed, 1048 insertions, 55 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index cfebb8c..1295b03 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -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 diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 541ad25..5367ad6 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -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; }; diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c index 7468eef..0c0b32c 100644 --- a/bfd/elf-eh-frame.c +++ b/bfd/elf-eh-frame.c @@ -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); diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 2851668..094fe60 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -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. diff --git a/ld/testsuite/ld-mips-elf/eh-frame1-n32.d b/ld/testsuite/ld-mips-elf/eh-frame1-n32.d new file mode 100644 index 0000000..4e33219 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/eh-frame1-n32.d @@ -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 + diff --git a/ld/testsuite/ld-mips-elf/eh-frame1-n64.d b/ld/testsuite/ld-mips-elf/eh-frame1-n64.d new file mode 100644 index 0000000..2b175e0 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/eh-frame1-n64.d @@ -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 + diff --git a/ld/testsuite/ld-mips-elf/eh-frame1.ld b/ld/testsuite/ld-mips-elf/eh-frame1.ld new file mode 100644 index 0000000..910a84e --- /dev/null +++ b/ld/testsuite/ld-mips-elf/eh-frame1.ld @@ -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/ : { *(*) } +} diff --git a/ld/testsuite/ld-mips-elf/eh-frame1.s b/ld/testsuite/ld-mips-elf/eh-frame1.s new file mode 100644 index 0000000..c8413db --- /dev/null +++ b/ld/testsuite/ld-mips-elf/eh-frame1.s @@ -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 diff --git a/ld/testsuite/ld-mips-elf/mips-elf.exp b/ld/testsuite/ld-mips-elf/mips-elf.exp index f0c2b84..c3417bc 100644 --- a/ld/testsuite/ld-mips-elf/mips-elf.exp +++ b/ld/testsuite/ld-mips-elf/mips-elf.exp @@ -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" +} |