aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2005-02-11 15:48:11 +0000
committerH.J. Lu <hjl.tools@gmail.com>2005-02-11 15:48:11 +0000
commitd1f5c6e34f0dd06ad9a3f82988663268f854c6eb (patch)
tree8d3afca07eddf6f0afc719b1a1f6a508e9dbbf5f
parentd9391a1764c97a7fc4dde5ee4bb81c6c2d5b0ac0 (diff)
downloadgdb-d1f5c6e34f0dd06ad9a3f82988663268f854c6eb.zip
gdb-d1f5c6e34f0dd06ad9a3f82988663268f854c6eb.tar.gz
gdb-d1f5c6e34f0dd06ad9a3f82988663268f854c6eb.tar.bz2
2005-02-10 H.J. Lu <hongjiu.lu@intel.com>
* readelf.c (group_count): Don't initialize it. (process_section_groups): Reurn 1 if we won't do unwind nor section groups. Set group_count to 0 before counting group sections and return 1 if there are no group sections. Reread SHT_SYMTAB/SHT_STRTAB sections only when needed. Don't skip section 0. (process_object): Only set do_unwind to 0 if process_section_groups return 0.
-rw-r--r--binutils/ChangeLog11
-rw-r--r--binutils/readelf.c101
2 files changed, 88 insertions, 24 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 252da84..a5edcbf 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,14 @@
+2005-02-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ * readelf.c (group_count): Don't initialize it.
+ (process_section_groups): Reurn 1 if we won't do unwind nor
+ section groups. Set group_count to 0 before counting group
+ sections and return 1 if there are no group sections. Reread
+ SHT_SYMTAB/SHT_STRTAB sections only when needed. Don't skip
+ section 0.
+ (process_object): Only set do_unwind to 0 if
+ process_section_groups return 0.
+
2005-02-10 Ian Lance Taylor <ian@airs.com>
* MAINTAINERS: Update my e-mail address.
diff --git a/binutils/readelf.c b/binutils/readelf.c
index a4650b4..24dbacf 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -185,7 +185,7 @@ struct group
};
struct group *section_groups;
-size_t group_count = 0;
+size_t group_count;
struct group **section_headers_groups;
@@ -3956,11 +3956,18 @@ process_section_groups (FILE *file)
Elf_Internal_Shdr *section;
unsigned int i;
struct group *group;
+ Elf_Internal_Shdr *symtab_sec, *strtab_sec;
+ Elf_Internal_Sym *symtab;
+ char *strtab;
+
+ /* Don't process section groups unless needed. */
+ if (!do_unwind && !do_section_groups)
+ return 1;
if (elf_header.e_shnum == 0)
{
if (do_section_groups)
- printf (_("\nThere are no section groups in this file.\n"));
+ printf (_("\nThere are no sections in this file.\n"));
return 1;
}
@@ -3981,12 +3988,21 @@ process_section_groups (FILE *file)
}
/* Scan the sections for the group section. */
+ group_count = 0;
for (i = 0, section = section_headers;
i < elf_header.e_shnum;
i++, section++)
if (section->sh_type == SHT_GROUP)
group_count++;
+ if (group_count == 0)
+ {
+ if (do_section_groups)
+ printf (_("\nThere are no section groups in this file.\n"));
+
+ return 1;
+ }
+
section_groups = calloc (group_count, sizeof (struct group));
if (section_groups == NULL)
@@ -3995,6 +4011,10 @@ process_section_groups (FILE *file)
return 0;
}
+ symtab_sec = NULL;
+ strtab_sec = NULL;
+ symtab = NULL;
+ strtab = NULL;
for (i = 0, section = section_headers, group = section_groups;
i < elf_header.e_shnum;
i++, section++)
@@ -4002,20 +4022,26 @@ process_section_groups (FILE *file)
if (section->sh_type == SHT_GROUP)
{
char *name = SECTION_NAME (section);
- char *group_name, *strtab, *start, *indices;
+ char *group_name, *start, *indices;
unsigned int entry, j, size;
+ Elf_Internal_Shdr *sec;
Elf_Internal_Sym *sym;
- Elf_Internal_Shdr *symtab_sec, *strtab_sec, *sec;
- Elf_Internal_Sym *symtab;
/* Get the symbol table. */
- symtab_sec = SECTION_HEADER (section->sh_link);
- if (symtab_sec->sh_type != SHT_SYMTAB)
+ sec = SECTION_HEADER (section->sh_link);
+ if (sec->sh_type != SHT_SYMTAB)
{
error (_("Bad sh_link in group section `%s'\n"), name);
continue;
}
- symtab = GET_ELF_SYMBOLS (file, symtab_sec);
+
+ if (symtab_sec != sec)
+ {
+ symtab_sec = sec;
+ if (symtab)
+ free (symtab);
+ symtab = GET_ELF_SYMBOLS (file, symtab_sec);
+ }
sym = symtab + section->sh_info;
@@ -4034,11 +4060,16 @@ process_section_groups (FILE *file)
else
{
/* Get the string table. */
- strtab_sec = SECTION_HEADER (symtab_sec->sh_link);
- strtab = get_data (NULL, file, strtab_sec->sh_offset,
- strtab_sec->sh_size,
- _("string table"));
-
+ sec = SECTION_HEADER (symtab_sec->sh_link);
+ if (strtab_sec != sec)
+ {
+ strtab_sec = sec;
+ if (strtab)
+ free (strtab);
+ strtab = get_data (NULL, file, strtab_sec->sh_offset,
+ strtab_sec->sh_size,
+ _("string table"));
+ }
group_name = strtab + sym->st_name;
}
@@ -4070,9 +4101,26 @@ process_section_groups (FILE *file)
if (section_headers_groups [SECTION_HEADER_INDEX (entry)]
!= NULL)
{
- error (_("section [%5u] already in group section [%5u]\n"),
- entry, section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index);
- continue;
+ if (entry)
+ {
+ error (_("section [%5u] already in group section [%5u]\n"),
+ entry,
+ section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index);
+ continue;
+ }
+ else
+ {
+ /* Intel C/C++ compiler may put section 0 in a
+ section group. We just warn it the first time
+ and ignore it afterwards. */
+ static int warned = 0;
+ if (!warned)
+ {
+ error (_("section 0 in group section [%5u]\n"),
+ section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index);
+ warned++;
+ }
+ }
}
section_headers_groups [SECTION_HEADER_INDEX (entry)]
@@ -4091,10 +4139,6 @@ process_section_groups (FILE *file)
group->root = g;
}
- if (symtab)
- free (symtab);
- if (strtab)
- free (strtab);
if (start)
free (start);
@@ -4102,6 +4146,10 @@ process_section_groups (FILE *file)
}
}
+ if (symtab)
+ free (symtab);
+ if (strtab)
+ free (strtab);
return 1;
}
@@ -11660,17 +11708,22 @@ process_object (char *file_name, FILE *file)
if (! process_file_header ())
return 1;
- if (! process_section_headers (file)
- || ! process_section_groups (file))
+ if (! process_section_headers (file))
{
- /* Without loaded section headers and section groups we
- cannot process lots of things. */
+ /* Without loaded section headers we cannot process lots of
+ things. */
do_unwind = do_version = do_dump = do_arch = 0;
if (! do_using_dynamic)
do_syms = do_reloc = 0;
}
+ if (! process_section_groups (file))
+ {
+ /* Without loaded section groups we cannot process unwind. */
+ do_unwind = 0;
+ }
+
if (process_program_headers (file))
process_dynamic_section (file);