From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21540 invoked by alias); 17 Mar 2005 19:51:00 -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 21421 invoked from network); 17 Mar 2005 19:50:52 -0000 Received: from unknown (HELO sccrmhc11.comcast.net) (204.127.202.59) by sourceware.org with SMTP; 17 Mar 2005 19:50:52 -0000 Received: from lucon.org ([24.6.212.230]) by comcast.net (sccrmhc14) with ESMTP id <20050317195052014004kbbqe>; Thu, 17 Mar 2005 19:50:52 +0000 Received: by lucon.org (Postfix, from userid 1000) id C5A4263F8C; Thu, 17 Mar 2005 11:50:51 -0800 (PST) Date: Thu, 17 Mar 2005 22:03:00 -0000 From: "H. J. Lu" To: binutils@sources.redhat.com Subject: RFC: Store ELF section index for input file Message-ID: <20050317195051.GA9484@lucon.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.1i X-SW-Source: 2005-03/txt/msg00490.txt.bz2 When there are many sections in input file, _bfd_elf_make_section_from_shdr can be very slow. Can we store ELF section index in bfd section for input file? With this patch, the link time of my testcase went from 966.01s user 0.81s system 99% cpu 16:06.87 total to 49.03s user 0.76s system 99% cpu 49.816 total H.J. --- bfd/elf-bfd.h.fast 2005-03-03 13:35:31.000000000 -0800 +++ bfd/elf-bfd.h 2005-03-17 11:14:18.656521092 -0800 @@ -629,7 +629,7 @@ struct elf_backend_data /* A function to handle unusual section types when creating BFD sections from ELF sections. */ bfd_boolean (*elf_backend_section_from_shdr) - (bfd *, Elf_Internal_Shdr *, const char *); + (bfd *, Elf_Internal_Shdr *, const char *, int); /* A function to convert machine dependent section header flags to BFD internal section header flags. */ @@ -1060,7 +1060,8 @@ struct bfd_elf_section_data unsigned int rel_count2; /* The ELF section number of this section. Only used for an output - file. */ + file. Also used for an input file as the index into the ELF + section array, elf_elfsections. */ int this_idx; /* The ELF section number of the reloc section indicated by @@ -1416,7 +1417,7 @@ extern bfd_boolean bfd_elf_mkcorefile extern Elf_Internal_Shdr *bfd_elf_find_section (bfd *, char *); extern bfd_boolean _bfd_elf_make_section_from_shdr - (bfd *, Elf_Internal_Shdr *, const char *); + (bfd *, Elf_Internal_Shdr *, const char *, int); extern bfd_boolean _bfd_elf_make_section_from_phdr (bfd *, Elf_Internal_Phdr *, int, const char *); extern struct bfd_hash_entry *_bfd_elf_link_hash_newfunc --- bfd/elf.c.fast 2005-03-16 15:14:41.000000000 -0800 +++ bfd/elf.c 2005-03-17 11:19:25.464861663 -0800 @@ -673,7 +673,8 @@ bfd_elf_is_group_section (bfd *abfd ATTR bfd_boolean _bfd_elf_make_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr, - const char *name) + const char *name, + int shindex) { asection *newsect; flagword flags; @@ -692,6 +693,7 @@ _bfd_elf_make_section_from_shdr (bfd *ab hdr->bfd_section = newsect; elf_section_data (newsect)->this_hdr = *hdr; + elf_section_data (newsect)->this_idx = shindex; /* Always use the real type/flags. */ elf_section_type (newsect) = hdr->sh_type; @@ -1730,10 +1732,10 @@ bfd_section_from_shdr (bfd *abfd, unsign case SHT_FINI_ARRAY: /* .fini_array section. */ case SHT_PREINIT_ARRAY: /* .preinit_array section. */ case SHT_GNU_LIBLIST: /* .gnu.liblist section. */ - return _bfd_elf_make_section_from_shdr (abfd, hdr, name); + return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); case SHT_DYNAMIC: /* Dynamic linking information. */ - if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) + if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) return FALSE; if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB) { @@ -1784,7 +1786,8 @@ bfd_section_from_shdr (bfd *abfd, unsign linker. */ if ((hdr->sh_flags & SHF_ALLOC) != 0 && (abfd->flags & DYNAMIC) != 0 - && ! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) + && ! _bfd_elf_make_section_from_shdr (abfd, hdr, name, + shindex)) return FALSE; /* Go looking for SHT_SYMTAB_SHNDX too, since if there is one we @@ -1828,7 +1831,7 @@ bfd_section_from_shdr (bfd *abfd, unsign /* Besides being a symbol table, we also treat this as a regular section, so that objcopy can handle it. */ - return _bfd_elf_make_section_from_shdr (abfd, hdr, name); + return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); case SHT_SYMTAB_SHNDX: /* Symbol section indices when >64k sections */ if (elf_symtab_shndx (abfd) == shindex) @@ -1864,7 +1867,8 @@ bfd_section_from_shdr (bfd *abfd, unsign elf_elfsections (abfd)[shindex] = hdr; /* We also treat this as a regular section, so that objcopy can handle it. */ - return _bfd_elf_make_section_from_shdr (abfd, hdr, name); + return _bfd_elf_make_section_from_shdr (abfd, hdr, name, + shindex); } /* If the string table isn't one of the above, then treat it as a @@ -1889,7 +1893,7 @@ bfd_section_from_shdr (bfd *abfd, unsign } } } - return _bfd_elf_make_section_from_shdr (abfd, hdr, name); + return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); case SHT_REL: case SHT_RELA: @@ -1906,7 +1910,8 @@ bfd_section_from_shdr (bfd *abfd, unsign ((*_bfd_error_handler) (_("%B: invalid link %lu for reloc section %s (index %u)"), abfd, hdr->sh_link, name, shindex)); - return _bfd_elf_make_section_from_shdr (abfd, hdr, name); + return _bfd_elf_make_section_from_shdr (abfd, hdr, name, + shindex); } /* For some incomprehensible reason Oracle distributes @@ -1953,7 +1958,8 @@ bfd_section_from_shdr (bfd *abfd, unsign can't use it as a reloc section if it points to the null section. */ if (hdr->sh_link != elf_onesymtab (abfd) || hdr->sh_info == SHN_UNDEF) - return _bfd_elf_make_section_from_shdr (abfd, hdr, name); + return _bfd_elf_make_section_from_shdr (abfd, hdr, name, + shindex); if (! bfd_section_from_shdr (abfd, hdr->sh_info)) return FALSE; @@ -1990,19 +1996,19 @@ bfd_section_from_shdr (bfd *abfd, unsign case SHT_GNU_verdef: elf_dynverdef (abfd) = shindex; elf_tdata (abfd)->dynverdef_hdr = *hdr; - return _bfd_elf_make_section_from_shdr (abfd, hdr, name); + return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); break; case SHT_GNU_versym: elf_dynversym (abfd) = shindex; elf_tdata (abfd)->dynversym_hdr = *hdr; - return _bfd_elf_make_section_from_shdr (abfd, hdr, name); + return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); break; case SHT_GNU_verneed: elf_dynverref (abfd) = shindex; elf_tdata (abfd)->dynverref_hdr = *hdr; - return _bfd_elf_make_section_from_shdr (abfd, hdr, name); + return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); break; case SHT_SHLIB: @@ -2015,7 +2021,7 @@ bfd_section_from_shdr (bfd *abfd, unsign name = group_signature (abfd, hdr); if (name == NULL) return FALSE; - if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name)) + if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) return FALSE; if (hdr->contents != NULL) { @@ -2041,7 +2047,8 @@ bfd_section_from_shdr (bfd *abfd, unsign default: /* Check for any processor-specific section types. */ - return bed->elf_backend_section_from_shdr (abfd, hdr, name); + return bed->elf_backend_section_from_shdr (abfd, hdr, name, + shindex); } return TRUE; --- bfd/elfxx-ia64.c.fast 2005-03-16 15:14:41.000000000 -0800 +++ bfd/elfxx-ia64.c 2005-03-17 11:23:28.057503044 -0800 @@ -193,8 +193,6 @@ static void elfNN_ia64_relax_ldxmov PARAMS((bfd_byte *contents, bfd_vma off)); static bfd_boolean is_unwind_section_name PARAMS ((bfd *abfd, const char *)); -static bfd_boolean elfNN_ia64_section_from_shdr - PARAMS ((bfd *, Elf_Internal_Shdr *, const char *)); static bfd_boolean elfNN_ia64_section_flags PARAMS ((flagword *, const Elf_Internal_Shdr *)); static bfd_boolean elfNN_ia64_fake_sections @@ -1271,13 +1269,14 @@ is_unwind_section_name (abfd, name) } /* Handle an IA-64 specific section when reading an object file. This - is called when elfcode.h finds a section with an unknown type. */ + is called when bfd_section_from_shdr finds a section with an unknown + type. */ static bfd_boolean -elfNN_ia64_section_from_shdr (abfd, hdr, name) - bfd *abfd; - Elf_Internal_Shdr *hdr; - const char *name; +elfNN_ia64_section_from_shdr (bfd *abfd, + Elf_Internal_Shdr *hdr, + const char *name, + int shindex) { asection *newsect; @@ -1301,7 +1300,7 @@ elfNN_ia64_section_from_shdr (abfd, hdr, return FALSE; } - if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) + if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) return FALSE; newsect = hdr->bfd_section;