binutils/

2004-04-26  H.J. Lu  <hongjiu.lu@intel.com>

	* readelf.c (do_section_groups): New.
	(options): Add --section-groups/-g.
	(usage): Mention --section-groups/-g.
	(parse_args): Support --section-groups/-g.
	(get_group_flags): New.
	(process_section_groups): New.
	(process_object): Call process_section_groups.

gas/

2004-04-26  H.J. Lu  <hongjiu.lu@intel.com>

	* config/obj-elf.c (obj_elf_change_section): Check if the old
	group name is NULL before comparison.

gas/testsuite/

2004-04-26  H.J. Lu  <hongjiu.lu@intel.com>

	* gas/elf/elf.exp: Add group0a, group0b and group1 for section
	group.

	* gas/elf/group0.s: New file.
	* gas/elf/group0a.d: Likewise.
	* gas/elf/group0b.d: Likewise.
	* gas/elf/group1.e: Likewise.
	* gas/elf/group1.s: Likewise.
This commit is contained in:
H.J. Lu
2004-04-27 03:59:09 +00:00
parent 1829f4b2af
commit f5842774f4
11 changed files with 193 additions and 3 deletions

View File

@@ -140,6 +140,7 @@ int do_dynamic;
int do_syms;
int do_reloc;
int do_sections;
int do_section_groups;
int do_segments;
int do_unwind;
int do_using_dynamic;
@@ -2393,6 +2394,7 @@ struct option options[] =
{"segments", no_argument, 0, 'l'},
{"sections", no_argument, 0, 'S'},
{"section-headers", no_argument, 0, 'S'},
{"section-groups", no_argument, 0, 'g'},
{"symbols", no_argument, 0, 's'},
{"syms", no_argument, 0, 's'},
{"relocs", no_argument, 0, 'r'},
@@ -2426,6 +2428,7 @@ usage (void)
--segments An alias for --program-headers\n\
-S --section-headers Display the sections' header\n\
--sections An alias for --section-headers\n\
-g --section-groups Display the section groups\n\
-e --headers Equivalent to: -h -l -S\n\
-s --syms Display the symbol table\n\
--symbols An alias for --syms\n\
@@ -2493,7 +2496,7 @@ parse_args (int argc, char **argv)
usage ();
while ((c = getopt_long
(argc, argv, "ersuahnldSDAIw::x:i:vVWH", options, NULL)) != EOF)
(argc, argv, "ersuahnldSDAIgw::x:i:vVWH", options, NULL)) != EOF)
{
char *cp;
int section;
@@ -2514,12 +2517,16 @@ parse_args (int argc, char **argv)
do_dynamic++;
do_header++;
do_sections++;
do_section_groups++;
do_segments++;
do_version++;
do_histogram++;
do_arch++;
do_notes++;
break;
case 'g':
do_section_groups++;
break;
case 'e':
do_header++;
do_sections++;
@@ -2746,7 +2753,8 @@ parse_args (int argc, char **argv)
if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
&& !do_segments && !do_header && !do_dump && !do_version
&& !do_histogram && !do_debugging && !do_arch && !do_notes)
&& !do_histogram && !do_debugging && !do_arch && !do_notes
&& !do_section_groups)
usage ();
else if (argc < 3)
{
@@ -3703,6 +3711,124 @@ process_section_headers (FILE *file)
return 1;
}
static const char *
get_group_flags (unsigned int flags)
{
static char buff[32];
switch (flags)
{
case GRP_COMDAT:
return "COMDAT";
default:
sprintf (buff, _("[<unknown>: 0x%x]"), flags);
break;
}
return buff;
}
static int
process_section_groups (FILE *file)
{
Elf_Internal_Shdr *section;
unsigned int i;
if (!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"));
return 1;
}
if (section_headers == NULL)
{
error (_("Section headers are not available!\n"));
abort ();
}
/* Scan the sections for the group section. */
for (i = 0, section = section_headers;
i < elf_header.e_shnum;
i++, section++)
{
if (section->sh_type == SHT_GROUP)
{
char *name = SECTION_NAME (section);
char *group_name, *strtab, *start, *indices;
unsigned int entry, j, size;
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)
{
error (_("Bad sh_link in group section `%s'\n"), name);
continue;
}
symtab = GET_ELF_SYMBOLS (file, symtab_sec);
sym = symtab + section->sh_info;
if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
{
bfd_vma sec_index = SECTION_HEADER_INDEX (sym->st_shndx);
if (sec_index == 0)
{
error (_("Bad sh_info in group section `%s'\n"), name);
continue;
}
group_name = SECTION_NAME (section_headers + sec_index);
strtab = NULL;
}
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"));
group_name = strtab + sym->st_name;
}
start = get_data (NULL, file, section->sh_offset,
section->sh_size, _("section data"));
indices = start;
size = (section->sh_size / section->sh_entsize) - 1;
entry = byte_get (indices, 4);
indices += 4;
printf ("\n%s group section `%s' [%s] contains %u sections:\n",
get_group_flags (entry), name, group_name, size);
printf (_(" [Index] Name\n"));
for (j = 0; j < size; j++)
{
entry = byte_get (indices, 4);
indices += 4;
sec = SECTION_HEADER (entry);
printf (" [%5u] %s\n",
entry, SECTION_NAME (sec));
}
if (strtab)
free (strtab);
if (start)
free (start);
}
}
return 1;
}
struct
{
const char *name;
@@ -10331,6 +10457,8 @@ process_object (char *file_name, FILE *file)
process_section_contents (file);
process_section_groups (file);
process_corefile_contents (file);
process_gnu_liblist (file);