This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
RFC: Store ELF section index for input file
- From: "H. J. Lu" <hjl at lucon dot org>
- To: binutils at sources dot redhat dot com
- Date: Thu, 17 Mar 2005 11:50:51 -0800
- Subject: RFC: Store ELF section index for input file
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;