From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15448 invoked by alias); 2 Dec 2007 20:35:02 -0000 Received: (qmail 15384 invoked by uid 22791); 2 Dec 2007 20:35:01 -0000 X-Spam-Check-By: sourceware.org Received: from smtp.nildram.co.uk (HELO smtp.nildram.co.uk) (195.112.4.54) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sun, 02 Dec 2007 20:34:53 +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 7068D2B5A8E for ; Sun, 2 Dec 2007 20:34:46 +0000 (GMT) Received: from richard by firetop.home with local (Exim 4.63) (envelope-from ) id 1IyvWb-0007hK-N4 for binutils@sourceware.org; Sun, 02 Dec 2007 20:34:49 +0000 From: Richard Sandiford To: binutils@sourceware.org Mail-Followup-To: binutils@sourceware.org, rsandifo@nildram.co.uk Subject: [PATCH 5/7] Fix --gc-sections for C++ MIPS ELF References: <87r6i4svjg.fsf@firetop.home> Date: Sun, 02 Dec 2007 20:35:00 -0000 In-Reply-To: <87r6i4svjg.fsf@firetop.home> (Richard Sandiford's message of "Sun\, 02 Dec 2007 20\:15\:15 +0000") Message-ID: <8763zgsumu.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/msg00005.txt.bz2 This patch and the next one reorganise eh_cie_fde so that the CIE-specific flags are in the new u.cie structure. I've split them up because this first one is more involved, and it's quite likely I'm missing something. (It's also a prerequisite for removing offsets_adjusted, because I'm getting rid of one of the checks here.) We currently have two flags: make_lsda_relative, which says that we can make LSDA relocations relative if want to, and need_lsda_relative, which says that we've decided to do that. We need two fields in case the LSDA is not a pointer: http://sourceware.org/ml/binutils/2004-09/msg00313.html We set need_lsda_relative based on make_lsda_relative in _bfd_elf_eh_frame_section_offset, but could we do it when parsing the section instead? The original patch linked above used a make/need_* pair for make_relative as well as make_lsda_relative, whereas we've now dropped need_relative. This is now the only case where _bfd_elf_eh_frame_section_offset changes the CIE and FDE information. Richard bfd/ * elf-bfd.h (eh_cie_fde): Remove need_lsda_relative. Move make_lsda_relative to u.cie. * elf-eh-frame.c (cie): Rename make_lsda_relative to can_make_lsda_relative. (_bfd_elf_parse_eh_frame): Don't set the old eh_cie_fde make_lsda_relative field. Update after cie renaming. Set u.cie.make_lsda_relative if can_make_lsda_relative and if we find a relocation against the LSDA. (_bfd_elf_discard_section_eh_frame): Copy make_lsda_relative when changing a CIE's group representative. (_bfd_elf_eh_frame_section_offset): Don't set need_ldsa_relative here. (_bfd_elf_write_section_eh_frame): Check u.cie.make_lsda_relative rather than need_lsda_relative. Index: bfd/elf-bfd.h =================================================================== --- bfd/elf-bfd.h 2007-12-02 17:22:22.000000000 +0000 +++ bfd/elf-bfd.h 2007-12-02 17:40:41.000000000 +0000 @@ -285,6 +285,11 @@ struct eh_cie_fde /* True if we have marked relocations associated with this CIE. */ unsigned int gc_mark : 1; + + /* True if we have decided to turn an absolute LSDA encoding into + a PC-relative one. It is the group representative's setting + that matters. */ + unsigned int make_lsda_relative : 1; } cie; } u; unsigned int reloc_index; @@ -299,8 +304,6 @@ struct eh_cie_fde 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; }; Index: bfd/elf-eh-frame.c =================================================================== --- bfd/elf-eh-frame.c 2007-12-02 17:26:13.000000000 +0000 +++ bfd/elf-eh-frame.c 2007-12-02 17:41:29.000000000 +0000 @@ -50,7 +50,7 @@ struct cie unsigned char fde_encoding; unsigned char initial_insn_length; unsigned char make_relative; - unsigned char make_lsda_relative; + unsigned char can_make_lsda_relative; unsigned char initial_instructions[50]; }; @@ -799,7 +799,7 @@ #define GET_RELOC(buf) \ ->elf_backend_can_make_lsda_relative_eh_frame (abfd, info, sec)) && (cie->lsda_encoding & 0xf0) == DW_EH_PE_absptr) - cie->make_lsda_relative = 1; + cie->can_make_lsda_relative = 1; /* If FDE encoding was not specified, it defaults to DW_EH_absptr. */ @@ -817,7 +817,6 @@ #define GET_RELOC(buf) \ ENSURE_NO_RELOCS (buf); this_inf->make_relative = cie->make_relative; - this_inf->make_lsda_relative = cie->make_lsda_relative; this_inf->per_encoding_relative = (cie->per_encoding & 0x70) == DW_EH_PE_pcrel; } @@ -862,6 +861,9 @@ #define GET_RELOC(buf) \ be adjusted if any future augmentations do the same thing. */ if (cie->lsda_encoding != DW_EH_PE_omit) { + SKIP_RELOCS (buf); + if (cie->can_make_lsda_relative && GET_RELOC (buf)) + cie->cie_inf->u.cie.make_lsda_relative = 1; this_inf->lsda_offset = buf - start; /* If there's no 'z' augmentation, we don't know where the CFA insns begin. Assume no padding. */ @@ -1097,6 +1099,8 @@ _bfd_elf_gc_mark_fdes (struct bfd_link_i /* Make the local CIE represent the merged group. */ merged->u.cie.merged = cie; cie->removed = 0; + cie->u.cie.make_lsda_relative + = merged->u.cie.make_lsda_relative; } } } @@ -1248,15 +1252,10 @@ _bfd_elf_eh_frame_section_offset (bfd *o /* 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].u.fde.cie_inf->make_lsda_relative - && (offset == (sec_info->entry[mid].offset + 8 - + sec_info->entry[mid].lsda_offset)) - && (sec_info->entry[mid].u.fde.cie_inf->need_lsda_relative - || !hdr_info->offsets_adjusted)) - { - sec_info->entry[mid].u.fde.cie_inf->need_lsda_relative = 1; - return (bfd_vma) -2; - } + && sec_info->entry[mid].u.fde.cie_inf->u.cie.make_lsda_relative + && offset == (sec_info->entry[mid].offset + 8 + + sec_info->entry[mid].lsda_offset)) + return (bfd_vma) -2; /* If converting to DW_EH_PE_pcrel, there will be no need for run-time relocation against DW_CFA_set_loc's arguments. */ @@ -1394,7 +1393,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab { /* CIE */ if (ent->make_relative - || ent->need_lsda_relative + || ent->u.cie.make_lsda_relative || ent->per_encoding_relative) { char *aug; @@ -1404,7 +1403,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab /* Need to find 'R' or 'L' augmentation's argument and modify DW_EH_PE_* value. */ action = ((ent->make_relative ? 1 : 0) - | (ent->need_lsda_relative ? 2 : 0) + | (ent->u.cie.make_lsda_relative ? 2 : 0) | (ent->per_encoding_relative ? 4 : 0)); extra_string = extra_augmentation_string_bytes (ent); extra_data = extra_augmentation_data_bytes (ent); @@ -1548,7 +1547,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab } if ((ent->lsda_encoding & 0xf0) == DW_EH_PE_pcrel - || cie->need_lsda_relative) + || cie->u.cie.make_lsda_relative) { buf += ent->lsda_offset; width = get_DW_EH_PE_width (ent->lsda_encoding, ptr_size); @@ -1558,7 +1557,7 @@ _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 (cie->need_lsda_relative) + else if (cie->u.cie.make_lsda_relative) value -= (sec->output_section->vma + ent->new_offset + 8 + ent->lsda_offset); write_value (abfd, buf, value, width);