From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7573 invoked by alias); 2 Dec 2007 20:19:25 -0000 Received: (qmail 7561 invoked by uid 22791); 2 Dec 2007 20:19:24 -0000 X-Spam-Check-By: sourceware.org Received: from smtp.nildram.co.uk (HELO smtp.nildram.co.uk) (195.149.33.74) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sun, 02 Dec 2007 20:19:18 +0000 Received: from firetop.home (85-211-136-23.dyn.gotadsl.co.uk [85.211.136.23]) by smtp.nildram.co.uk (Postfix) with ESMTP id 052B54C05C for ; Sun, 2 Dec 2007 20:19:12 +0000 (GMT) Received: from richard by firetop.home with local (Exim 4.63) (envelope-from ) id 1IyvHW-0007Qd-Pv for binutils@sourceware.org; Sun, 02 Dec 2007 20:19:14 +0000 From: Richard Sandiford To: binutils@sourceware.org Mail-Followup-To: binutils@sourceware.org, rsandifo@nildram.co.uk Subject: [PATCH 2/7] Fix --gc-sections for C++ MIPS ELF References: <87r6i4svjg.fsf@firetop.home> Date: Sun, 02 Dec 2007 20:19:00 -0000 In-Reply-To: <87r6i4svjg.fsf@firetop.home> (Richard Sandiford's message of "Sun\, 02 Dec 2007 20\:15\:15 +0000") Message-ID: <87ir3gsvct.fsf@firetop.home> User-Agent: Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org X-SW-Source: 2007-12/txt/msg00002.txt.bz2 Later patches want to know the index of the first relocation against a particular FDE or CIE, so this patch adds a reloc_index field to eh_cie_fde. We currently have: struct eh_cie_fde *cie_inf; unsigned int size; unsigned int offset; unsigned int new_offset; unsigned char fde_encoding; unsigned char lsda_encoding; 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_lsda_relative : 1; unsigned int per_encoding_relative : 1; unsigned int *set_loc; i.e. 3 unsigned chars and 8 bits in an unsigned int, so we can avoid growing the structure by turning the "unsigned char"s into "unsigned int : 8"s. Also, later patches want to add some CIE-specific information, so this patch puts the FDE-specific cie_inf in a union. Richard bfd/ * elf-bfd.h (eh_cie_fde): Put cie_inf in a union. Add a reloc_index field. Use bitfields for fde_encoding, lsda_encoding and lsda_offset. * elf-eh-frame.c (extra_augmentation_data_bytes): Adjust cie_inf accesses after the above change. (_bfd_elf_eh_frame_section_offset): Likewise. (_bfd_elf_write_section_eh_frame): Likewise. (_bfd_elf_discard_section_eh_frame): Likewise. Set up reloc_index. Index: bfd/elf-bfd.h =================================================================== --- bfd/elf-bfd.h 2007-12-02 16:59:46.000000000 +0000 +++ bfd/elf-bfd.h 2007-12-02 17:01:08.000000000 +0000 @@ -264,14 +264,19 @@ struct elf_link_loaded_list /* Structures used by the eh_frame optimization code. */ struct eh_cie_fde { - /* For FDEs, this points to the CIE used. */ - struct eh_cie_fde *cie_inf; + union { + struct { + /* The CIE that we have chosen to use for this FDE. */ + struct eh_cie_fde *cie_inf; + } fde; + } u; + unsigned int reloc_index; unsigned int size; unsigned int offset; unsigned int new_offset; - unsigned char fde_encoding; - unsigned char lsda_encoding; - unsigned char lsda_offset; + unsigned int fde_encoding : 8; + unsigned int lsda_encoding : 8; + unsigned int lsda_offset : 8; unsigned int cie : 1; unsigned int removed : 1; unsigned int add_augmentation_size : 1; Index: bfd/elf-eh-frame.c =================================================================== --- bfd/elf-eh-frame.c 2007-12-02 16:59:44.000000000 +0000 +++ bfd/elf-eh-frame.c 2007-12-02 17:01:08.000000000 +0000 @@ -304,7 +304,7 @@ extra_augmentation_data_bytes (struct eh } else { - if (entry->cie_inf->add_augmentation_size) + if (entry->u.fde.cie_inf->add_augmentation_size) size++; } return size; @@ -572,6 +572,7 @@ #define GET_RELOC(buf) \ this_inf->offset = last_fde - ehbuf; this_inf->size = 4 + hdr_length; + this_inf->reloc_index = cookie->rel - cookie->rels; if (hdr_length == 0) { @@ -826,7 +827,7 @@ #define GET_RELOC(buf) \ } ecie->usage_count++; hdr_info->fde_count++; - this_inf->cie_inf = (void *) (ecie - ecies); + this_inf->u.fde.cie_inf = (void *) (ecie - ecies); } /* Skip the initial location and address range. */ @@ -954,8 +955,8 @@ #define GET_RELOC(buf) \ { if (!ent->cie) { - ecie = ecies + (bfd_hostptr_t) ent->cie_inf; - ent->cie_inf = ecie->cie.cie_inf; + ecie = ecies + (bfd_hostptr_t) ent->u.fde.cie_inf; + ent->u.fde.cie_inf = ecie->cie.cie_inf; } ent->new_offset = offset; offset += size_of_output_cie_fde (ent, ptr_size); @@ -1116,20 +1117,20 @@ _bfd_elf_eh_frame_section_offset (bfd *o /* If converting to DW_EH_PE_pcrel, there will be no need for run-time relocation against FDE's initial_location field. */ if (!sec_info->entry[mid].cie - && sec_info->entry[mid].cie_inf->make_relative + && sec_info->entry[mid].u.fde.cie_inf->make_relative && 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. */ if (!sec_info->entry[mid].cie - && sec_info->entry[mid].cie_inf->make_lsda_relative + && sec_info->entry[mid].u.fde.cie_inf->make_lsda_relative && (offset == (sec_info->entry[mid].offset + 8 + sec_info->entry[mid].lsda_offset)) - && (sec_info->entry[mid].cie_inf->need_lsda_relative + && (sec_info->entry[mid].u.fde.cie_inf->need_lsda_relative || !hdr_info->offsets_adjusted)) { - sec_info->entry[mid].cie_inf->need_lsda_relative = 1; + sec_info->entry[mid].u.fde.cie_inf->need_lsda_relative = 1; return (bfd_vma) -2; } @@ -1138,7 +1139,7 @@ _bfd_elf_eh_frame_section_offset (bfd *o if (sec_info->entry[mid].set_loc && (sec_info->entry[mid].cie ? sec_info->entry[mid].make_relative - : sec_info->entry[mid].cie_inf->make_relative) + : sec_info->entry[mid].u.fde.cie_inf->make_relative) && (offset >= sec_info->entry[mid].offset + 8 + sec_info->entry[mid].set_loc[1])) { @@ -1375,10 +1376,12 @@ _bfd_elf_write_section_eh_frame (bfd *ab bfd_vma value, address; unsigned int width; bfd_byte *start; + struct eh_cie_fde *cie; /* Skip length. */ + cie = ent->u.fde.cie_inf; buf += 4; - value = ent->new_offset + 4 - ent->cie_inf->new_offset; + value = ent->new_offset + 4 - cie->new_offset; bfd_put_32 (abfd, value, buf); buf += 4; width = get_DW_EH_PE_width (ent->fde_encoding, ptr_size); @@ -1406,7 +1409,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab address += sec->output_section->vma + ent->offset + 8; break; } - if (ent->cie_inf->make_relative) + if (cie->make_relative) value -= sec->output_section->vma + ent->new_offset + 8; write_value (abfd, buf, value, width); } @@ -1421,7 +1424,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab } if ((ent->lsda_encoding & 0xf0) == DW_EH_PE_pcrel - || ent->cie_inf->need_lsda_relative) + || cie->need_lsda_relative) { buf += ent->lsda_offset; width = get_DW_EH_PE_width (ent->lsda_encoding, ptr_size); @@ -1431,13 +1434,13 @@ _bfd_elf_write_section_eh_frame (bfd *ab { if ((ent->lsda_encoding & 0xf0) == DW_EH_PE_pcrel) value += ent->offset - ent->new_offset; - else if (ent->cie_inf->need_lsda_relative) + else if (cie->need_lsda_relative) value -= (sec->output_section->vma + ent->new_offset + 8 + ent->lsda_offset); write_value (abfd, buf, value, width); } } - else if (ent->cie_inf->add_augmentation_size) + else if (cie->add_augmentation_size) { /* Skip the PC and length and insert a zero byte for the augmentation size. */ @@ -1469,7 +1472,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab if ((ent->fde_encoding & 0xf0) == DW_EH_PE_pcrel) value += ent->offset + 8 - new_offset; - if (ent->cie_inf->make_relative) + if (cie->make_relative) value -= sec->output_section->vma + new_offset + ent->set_loc[cnt]; write_value (abfd, buf, value, width);