From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7163 invoked by alias); 13 Nov 2004 12:12:58 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 5689 invoked from network); 13 Nov 2004 12:12:27 -0000 Received: from unknown (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org with SMTP; 13 Nov 2004 12:12:27 -0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.11/8.12.11) with ESMTP id iADCCRue008164 for ; Sat, 13 Nov 2004 07:12:27 -0500 Received: from localhost (mail@vpn50-32.rdu.redhat.com [172.16.50.32]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id iADCCPr01290 for ; Sat, 13 Nov 2004 07:12:25 -0500 Received: from rsandifo by localhost with local (Exim 3.35 #1) id 1CSwlU-0001RB-00 for binutils@sources.redhat.com; Sat, 13 Nov 2004 12:12:24 +0000 To: binutils@sources.redhat.com Subject: RFA: Extensions to the .eh_frame linker code From: Richard Sandiford Date: Sat, 13 Nov 2004 12:12:00 -0000 Message-ID: <87654akkwn.fsf@redhat.com> User-Agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2004-11/txt/msg00209.txt.bz2 The patch below lets the linker convert from absolute to relative FDE encodings in cases where the original CIEs have no explicit 'R' augmentation. I've been meaning to do this for a while now, but finally got spurred into action after having a glibc change rejected. ;) This feature is useful on MIPS targets because every relocatable object uses the default DW_EH_PE_absptr FDE encoding. Although it would be nice if relocatable PIC objects could use DW_EH_PE_pcrel from the outset, the ABIs don't define a suitable relocation. The idea of the patch is pretty simple. First of all, we need to allow the final CIEs and FDEs to be bigger than the originals. The patch supports this by adding two new eh_cie_fde fields: "growth", the number of extra useful bytes, and "new_size", the properly-rounded size of the output CIE or FDE. Second, it must be possible for _bfd_elf_discard_section_eh_frame to decide once and for all whether the FDE encoding will change or not. At the moment, the function simply sets "make_relative" if the transformation would be useful and leaves the final decision to _bfd_elf_eh_frame_section_offset. The make_relative/need_relative distinction was a result of Alan's fix for ld/418. As I understand it, the important part of that change was really the make_lsda_relative/need_lsda_relative split (because we don't know for sure what the LSDA actually contains). It looks like the make_relative/need_relative part was done more for consistency than anything. Since the meaning of the "initial PC" field is fixed, I hope it's OK to go back to having just make_relative for the FDE encoding. With those two changes, we can extend the following code: 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; to include CIEs that have no 'R' augmentation (cie.fde_encoding == DW_EH_PE_omit at this point). We then need to reserve space for the new 'R' augmentation and FDE encoding byte. If the augmentation string was originally empty, we also need to add a 'z' augmentation and associated length. Adding a 'z' augmentation will affect the FDEs as well, of course. The patch records this information in two new eh_cie_fde fields: "add_augmentation_size", which says whether a new 'z' augmentation is needed, and "add_fde_encoding", which says whether a new 'R' augmentation is needed. Some other notes: (1) I've moved the block starting: if (cie.lsda_encoding != DW_EH_PE_omit) into the preceding else clause so that it only applies to FDEs that are not being removed. This is because the following code: else if (last_cie_inf->add_augmentation_size) this_inf->growth += 1; must not be run in that case. The patch gets a bit unreadable here, but it's really just reindentation followed by the new "else if" quoted above. (2) At the moment, _bfd_elf_write_section_eh_frame makes a single pass over the section data. This pass updates the contents of each entry and then moves it to its final offset. Since offsets can now grow as well as shrink, we need to move the entries in two passes, one forward, one backward. It's also easier to adjust the contents of growing entries if we know that everything already starts at its final offset. The patch therefore moves all the entries before doing any detailed updates. (3) The new "add_augmentation_size" field is logically separate from the "add_fde_encoding" field, and we might want to set it when adding other types of augmentation in future. Until that happens though, it seems more natural for _bfd_elf_write_section_eh_frame to handle the two together, as per the following block: if (ent->add_fde_encoding) { BFD_ASSERT (action & 1); if (ent->add_augmentation_size) ... else ... *aug++ = 'R'; *buf++ = DW_EH_PE_pcrel; action &= ~1; } I wasn't sure what structure the code would have if we ever tried to add several non-'z' augmentations and I didn't want to generalise things too far. (4) There's a missed optimisation opportunity: /* Round the size up the next alignment boundary and adjust the section size accordingly. ??? It would be better to trim any existing padding first. */ I hope to implement this soon, but I thought the patch was already getting to the difficult-to-review stage as it was. I've tried to bullet-proof the testcase against such an optimisation by padding each CIE and FDE with non-nops. The type of padding is parameterised, so once the optimisation is implemented, it should just be a case of attaching new .d files to the same .s file and setting "fill" to 0. Patch tested by bootstrapping & regression testing gcc on i686-pc-linux-gnu and mips64-linux-gnu. Also tested against the gas/ld/binutils testsuite for: sparc-linux-gnu sparc64-linux-gnu i386-linux-gnu x86_64-linux-gnu powerpc-linux-gnu powerpc64-linux-gnu sh-linux-gnu mips64-elf mipsisa64-elf mips64-linux-gnu OK to install? Richard bfd/ * elf-bfd.h (eh_cie_fde): Add new fields: growth, new_size, add_augmentation_size and add_fde_encoding. Remove need_relative. * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Allow the CIEs and FDEs to grow as well as shrink. Consider changing the FDE encoding in cases where the CIE has no explicit 'R' augmentation. (_bfd_elf_eh_frame_section_offset): Remove need_relative handling. Add the growth field to 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. ld/testsuite * 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. Index: bfd/elf-bfd.h =================================================================== RCS file: /cvs/src/src/bfd/elf-bfd.h,v retrieving revision 1.162 diff -u -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.162 elf-bfd.h --- bfd/elf-bfd.h 14 Oct 2004 23:38:08 -0000 1.162 +++ bfd/elf-bfd.h 13 Nov 2004 09:55:38 -0000 @@ -289,6 +289,8 @@ struct eh_cie_fde /* For FDEs, this points to the CIE used. */ struct eh_cie_fde *cie_inf; unsigned int size; + unsigned int growth; + unsigned int new_size; unsigned int offset; unsigned int new_offset; unsigned char fde_encoding; @@ -296,9 +298,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; }; Index: bfd/elf-eh-frame.c =================================================================== RCS file: /cvs/src/src/bfd/elf-eh-frame.c,v retrieving revision 1.35 diff -u -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.35 elf-eh-frame.c --- bfd/elf-eh-frame.c 14 Oct 2004 23:38:08 -0000 1.35 +++ bfd/elf-eh-frame.c 13 Nov 2004 09:55:38 -0000 @@ -380,7 +380,7 @@ #define GET_RELOC(buf) \ && cie_compare (&cie, &hdr_info->last_cie) == 0) || cie_usage_count == 0) { - new_size -= cie.hdr.length + 4; + new_size -= last_cie_inf->new_size; last_cie_inf->removed = 1; } else @@ -514,9 +514,33 @@ #define GET_RELOC(buf) \ 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) + { + cie.make_relative = 1; + + /* If the augmentation string is currently empty, record + that we want to add 'z' to it and a length byte to the + associated data. */ + if (*cie.augmentation == 0) + { + this_inf->add_augmentation_size = 1; + this_inf->growth += 2; + } + + /* Record that we need to add 'R' to the augmentation + string and an FDE encoding to the augmentation data. */ + this_inf->add_fde_encoding = 1; + this_inf->growth += 2; + } + } if (info->shared && (get_elf_backend_data (abfd) @@ -574,23 +598,36 @@ #define GET_RELOC(buf) \ } cie_usage_count++; hdr_info->fde_count++; - } - if (cie.lsda_encoding != DW_EH_PE_omit) - { - unsigned int dummy; + if (cie.lsda_encoding != DW_EH_PE_omit) + { + unsigned int dummy; - aug = buf; - buf += 2 * get_DW_EH_PE_width (cie.fde_encoding, ptr_size); - if (cie.augmentation[0] == 'z') - read_uleb128 (dummy, buf); - /* If some new augmentation data is added before LSDA - in FDE augmentation area, this need to be adjusted. */ - this_inf->lsda_offset = (buf - aug); + aug = buf; + buf += 2 * get_DW_EH_PE_width (cie.fde_encoding, ptr_size); + if (cie.augmentation[0] == 'z') + read_uleb128 (dummy, buf); + /* If some new augmentation data is added before LSDA + in FDE augmentation area, this need to be adjusted. */ + this_inf->lsda_offset = (buf - aug); + } + else if (last_cie_inf->add_augmentation_size) + this_inf->growth += 1; } buf = last_fde + 4 + hdr.length; SKIP_RELOCS (buf); } + this_inf->new_size = this_inf->size + this_inf->growth; + if (this_inf->growth > 0) + { + /* Round the size up the next alignment boundary and adjust + the section size accordingly. + + ??? It would be better to trim any existing padding first. */ + this_inf->new_size = (this_inf->new_size + ptr_size - 1) & -ptr_size; + new_size += this_inf->new_size - this_inf->size; + } + this_inf->fde_encoding = cie.fde_encoding; this_inf->lsda_encoding = cie.lsda_encoding; sec_info->count++; @@ -606,7 +643,7 @@ #define GET_RELOC(buf) \ if (!ent->removed) { ent->new_offset = offset; - offset += ent->size; + offset += ent->new_size; if (ent->cie) last_cie_inf = ent; else @@ -614,7 +651,7 @@ #define GET_RELOC(buf) \ } 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; if (sec->size == 0) @@ -759,13 +796,8 @@ _bfd_elf_eh_frame_section_offset (bfd *o 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. */ @@ -782,8 +814,11 @@ _bfd_elf_eh_frame_section_offset (bfd *o if (hdr_info->offsets_adjusted) offset -= sec->output_offset; + /* If the new entry is bigger than the original, all the new bytes + will be inserted before the first relocation. */ return (offset + sec_info->entry[mid].new_offset - - sec_info->entry[mid].offset); + - sec_info->entry[mid].offset + + sec_info->entry[mid].growth); } /* Write out .eh_frame section. This is called with the relocated @@ -798,7 +833,6 @@ _bfd_elf_write_section_eh_frame (bfd *ab 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; @@ -851,7 +885,21 @@ _bfd_elf_write_section_eh_frame (bfd *ab 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 the 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) { if (ent->removed) @@ -860,20 +908,27 @@ _bfd_elf_write_section_eh_frame (bfd *ab if (ent->cie) { /* CIE */ - if (ent->need_relative + if (ent->make_relative || ent->need_lsda_relative || ent->per_encoding_relative) { - unsigned char *aug; + unsigned char *buf, *aug, *end; unsigned int action; 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; + buf = contents + ent->new_offset - sec->output_offset; + end = buf + ent->size; + + /* Install the new size, filling the extra bytes with + DW_CFA_nops. */ + memset (end, 0, ent->new_size - ent->size); + bfd_put_32 (abfd, ent->new_size - 4, buf); + /* Skip length, id and version. */ buf += 9; aug = buf; @@ -883,10 +938,46 @@ _bfd_elf_write_section_eh_frame (bfd *ab read_uleb128 (dummy, buf); if (*aug == 'z') { + /* Bump the size if we're adding an FDE encoding byte. + The uleb128 will always be a single byte for the + kind of augmentation strings that we're prepared + to handle. */ + if (ent->add_fde_encoding) + *buf += 1; read_uleb128 (dummy, buf); aug++; } + if (ent->add_fde_encoding) + { + BFD_ASSERT (action & 1); + if (ent->add_augmentation_size) + { + /* We need to insert 'zR' into the augmentation + string and add two bytes to the augmentation data. + Shuffle everything appropriately and move BUF to + account for the new string length. */ + memmove (buf + 4, buf, end - buf); + memmove (aug + 2, aug, buf - aug); + buf += 2; + + *aug++ = 'z'; + *buf++ = 1; + } + else + { + /* As above, but we only need to insert 'R' into + the augmentation string and we only need to + add one byte to the data. */ + memmove (buf + 2, buf, end - buf); + memmove (aug + 1, aug, buf - aug); + buf++; + } + *aug++ = 'R'; + *buf++ = DW_EH_PE_pcrel; + action &= ~1; + } + while (action) switch (*aug++) { @@ -915,7 +1006,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab val = read_value (abfd, buf, per_width, get_DW_EH_PE_signed (per_encoding)); - val += ent->offset - ent->new_offset; + val += ent->offset - ent->new_offset - ent->growth; write_value (abfd, buf, val, per_width); action &= ~4; } @@ -938,10 +1029,18 @@ _bfd_elf_write_section_eh_frame (bfd *ab else if (ent->size > 4) { /* FDE */ + bfd_byte *buf, *end; bfd_vma value, address; unsigned int width; - buf = contents + ent->offset - sec->output_offset; + buf = contents + ent->new_offset - sec->output_offset; + end = buf + ent->size; + + /* Install the new size, filling the extra bytes with + DW_CFA_nops. */ + memset (end, 0, ent->new_size - ent->size); + bfd_put_32 (abfd, ent->new_size - 4, buf); + /* Skip length. */ buf += 4; value = ent->new_offset + 4 - ent->cie_inf->new_offset; @@ -972,7 +1071,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab 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); } @@ -1001,14 +1100,18 @@ _bfd_elf_write_section_eh_frame (bfd *ab 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; } { @@ -1021,6 +1124,8 @@ _bfd_elf_write_section_eh_frame (bfd *ab && ((sec->output_offset + sec->size + pad) <= sec->output_section->size)) { + bfd_byte *buf; + /* Find the last CIE/FDE. */ ent = sec_info->entry + sec_info->count; while (--ent != sec_info->entry) @@ -1035,20 +1140,17 @@ _bfd_elf_write_section_eh_frame (bfd *ab buf = contents + ent->new_offset - sec->output_offset; - /* Update length. */ - ent->size += pad; - bfd_put_32 (abfd, ent->size - 4, buf); - /* Pad it with DW_CFA_nop */ - memset (p, 0, pad); - p += pad; + memset (buf + ent->new_size, 0, pad); + + /* Update length. */ + ent->new_size += pad; + bfd_put_32 (abfd, ent->new_size - 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); Index: ld/testsuite/ld-mips-elf/mips-elf.exp =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-mips-elf/mips-elf.exp,v retrieving revision 1.18 diff -u -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.18 mips-elf.exp --- ld/testsuite/ld-mips-elf/mips-elf.exp 8 Jul 2004 15:43:00 -0000 1.18 +++ ld/testsuite/ld-mips-elf/mips-elf.exp 13 Nov 2004 09:55:38 -0000 @@ -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" +} diff -u /dev/null ld/testsuite/ld-mips-elf/eh-frame1-n32.d --- /dev/null Fri Apr 23 00:21:55 2004 +++ ld/testsuite/ld-mips-elf/eh-frame1-n32.d Sat Nov 13 09:43:09 2004 @@ -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' .*: +# 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 -u /dev/null ld/testsuite/ld-mips-elf/eh-frame1-n64.d --- /dev/null Fri Apr 23 00:21:55 2004 +++ ld/testsuite/ld-mips-elf/eh-frame1-n64.d Sat Nov 13 09:43:09 2004 @@ -0,0 +1,423 @@ +#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' .*: +# 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 -u /dev/null ld/testsuite/ld-mips-elf/eh-frame1.ld --- /dev/null Fri Apr 23 00:21:55 2004 +++ ld/testsuite/ld-mips-elf/eh-frame1.ld Sat Nov 13 09:43:09 2004 @@ -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 -u /dev/null ld/testsuite/ld-mips-elf/eh-frame1.s --- /dev/null Fri Apr 23 00:21:55 2004 +++ ld/testsuite/ld-mips-elf/eh-frame1.s Sat Nov 13 09:43:09 2004 @@ -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 (total 16 bytes). + .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