aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binutils/ChangeLog10
-rw-r--r--binutils/readelf.c132
-rw-r--r--gas/ChangeLog5
-rw-r--r--gas/config/obj-elf.c3
-rw-r--r--gas/testsuite/ChangeLog11
-rw-r--r--gas/testsuite/gas/elf/elf.exp3
-rw-r--r--gas/testsuite/gas/elf/group0.s4
-rw-r--r--gas/testsuite/gas/elf/group0a.d9
-rw-r--r--gas/testsuite/gas/elf/group0b.d10
-rw-r--r--gas/testsuite/gas/elf/group1.e7
-rw-r--r--gas/testsuite/gas/elf/group1.s2
11 files changed, 193 insertions, 3 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 55d9ec0..47c8d0b 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,13 @@
+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.
+
2004-04-24 Alan Modra <amodra@bigpond.net.au>
* objdump.c (disassemble_section): Don't disassemble sections
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 4db0a10..29e1c8b 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -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);
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 7a4f663..08a4750 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+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.
+
2004-04-23 Chris Demetriou <cgd@broadcom.com>
* config/tc-mips.h (mips_dwarf2_addr_size): Prototype.
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index 14d48f2..e5f3ce3 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -645,7 +645,8 @@ obj_elf_change_section (const char *name,
if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
as_warn (_("ignoring changed section entity size for %s"), name);
if ((attr & SHF_GROUP) != 0
- && strcmp (elf_group_name (old_sec), group_name) != 0)
+ && (elf_group_name (old_sec) == NULL
+ || strcmp (elf_group_name (old_sec), group_name) != 0))
as_warn (_("ignoring new section group for %s"), name);
}
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 31e854d..9ec1aff 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,14 @@
+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.
+
2004-04-23 Nick Clifton <nickc@redhat.com>
* gas/symver/symver1.d: Cope with extra symbols inserted by
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index f427482..e087fba 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -48,6 +48,9 @@ if { ([istarget "*-*-elf*"]
set target_machine -m32r
}
run_dump_test "ehopt0"
+ run_dump_test "group0a"
+ run_dump_test "group0b"
+ run_list_test "group1" "" "" ""
run_dump_test "section0"
run_dump_test "section1"
run_list_test "section2" "$target_machine" "-al" ""
diff --git a/gas/testsuite/gas/elf/group0.s b/gas/testsuite/gas/elf/group0.s
new file mode 100644
index 0000000..26bdda2
--- /dev/null
+++ b/gas/testsuite/gas/elf/group0.s
@@ -0,0 +1,4 @@
+ .section .foo,"axG",@progbits,.foo_group,comdat
+ .byte 1
+ .section .bar,"aG",@progbits,.foo_group,comdat
+ .byte 1
diff --git a/gas/testsuite/gas/elf/group0a.d b/gas/testsuite/gas/elf/group0a.d
new file mode 100644
index 0000000..9b2b967
--- /dev/null
+++ b/gas/testsuite/gas/elf/group0a.d
@@ -0,0 +1,9 @@
+#readelf: -SW
+#name: group section
+#source: group0.s
+
+#...
+[ ]*\[.*\][ ]+\.foo[ ]+PROGBITS.*[ ]+AXG[ ]+.*
+[ ]*\[.*\][ ]+\.bar[ ]+PROGBITS.*[ ]+AG[ ]+.*
+[ ]*\[.*\][ ]+\.foo_group[ ]+GROUP.*
+#pass
diff --git a/gas/testsuite/gas/elf/group0b.d b/gas/testsuite/gas/elf/group0b.d
new file mode 100644
index 0000000..847a86b
--- /dev/null
+++ b/gas/testsuite/gas/elf/group0b.d
@@ -0,0 +1,10 @@
+#readelf: -g
+#name: group section
+#source: group0.s
+
+#...
+COMDAT group section `.foo_group' \[.foo_group\] contains 2 sections:
+[ ]+\[Index\][ ]+Name
+[ ]+\[.*\][ ]+.foo
+[ ]+\[.*\][ ]+.bar
+#pass
diff --git a/gas/testsuite/gas/elf/group1.e b/gas/testsuite/gas/elf/group1.e
new file mode 100644
index 0000000..d4c4003
--- /dev/null
+++ b/gas/testsuite/gas/elf/group1.e
@@ -0,0 +1,7 @@
+
+Symbol table '.symtab' contains 4 entries:
+ Num: Value[ ]* Size Type Bind Vis Ndx Name
+ 0: 0+0 0 NOTYPE LOCAL DEFAULT UND
+ 1: 0+0 0 SECTION LOCAL DEFAULT 1
+ 2: 0+0 0 SECTION LOCAL DEFAULT 2
+ 3: 0+0 0 SECTION LOCAL DEFAULT 3
diff --git a/gas/testsuite/gas/elf/group1.s b/gas/testsuite/gas/elf/group1.s
new file mode 100644
index 0000000..1645f0b
--- /dev/null
+++ b/gas/testsuite/gas/elf/group1.s
@@ -0,0 +1,2 @@
+ .section .text,"axG",@progbits,.foo_group,comdat
+ .byte 1