aboutsummaryrefslogtreecommitdiff
path: root/binutils/readelf.c
diff options
context:
space:
mode:
Diffstat (limited to 'binutils/readelf.c')
-rw-r--r--binutils/readelf.c189
1 files changed, 141 insertions, 48 deletions
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 0c9d0d3..c3c98e5 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -147,7 +147,7 @@ static int do_syms;
static int do_reloc;
static int do_sections;
static int do_section_groups;
-static int do_full_section_name;
+static int do_section_details;
static int do_segments;
static int do_unwind;
static int do_using_dynamic;
@@ -2716,6 +2716,7 @@ static struct option options[] =
{"sections", no_argument, 0, 'S'},
{"section-headers", no_argument, 0, 'S'},
{"section-groups", no_argument, 0, 'g'},
+ {"section-details", no_argument, 0, 't'},
{"full-section-name",no_argument, 0, 'N'},
{"symbols", no_argument, 0, 's'},
{"syms", no_argument, 0, 's'},
@@ -2751,8 +2752,7 @@ usage (void)
-S --section-headers Display the sections' header\n\
--sections An alias for --section-headers\n\
-g --section-groups Display the section groups\n\
- -N --full-section-name\n\
- Display the full section name\n\
+ -t --section-details Display the section details\n\
-e --headers Equivalent to: -h -l -S\n\
-s --syms Display the symbol table\n\
--symbols An alias for --syms\n\
@@ -2825,7 +2825,7 @@ parse_args (int argc, char **argv)
usage ();
while ((c = getopt_long
- (argc, argv, "ersuahnldSDAINgw::x:i:vVWH", options, NULL)) != EOF)
+ (argc, argv, "ersuahnldSDAINtgw::x:i:vVWH", options, NULL)) != EOF)
{
char *cp;
int section;
@@ -2856,8 +2856,10 @@ parse_args (int argc, char **argv)
case 'g':
do_section_groups++;
break;
+ case 't':
case 'N':
- do_full_section_name++;
+ do_sections++;
+ do_section_details++;
break;
case 'e':
do_header++;
@@ -3788,8 +3790,33 @@ get_64bit_elf_symbols (FILE *file, Elf_Internal_Shdr *section)
static const char *
get_elf_section_flags (bfd_vma sh_flags)
{
- static char buff[33];
+ static char buff[1024];
char *p = buff;
+ int index, size = sizeof (buff) - (8 + 4 + 1);
+ const struct
+ {
+ const char *str;
+ int len;
+ }
+ flags [] =
+ {
+ { "WRITE", 5 },
+ { "ALLOC", 5 },
+ { "EXEC", 4 },
+ { "MERGE", 5 },
+ { "STRINGS", 7 },
+ { "INFO LINK", 9 },
+ { "LINK ORDER", 10 },
+ { "OS NONCONF", 10 },
+ { "GROUP", 5 },
+ { "TLS", 3 }
+ };
+
+ if (do_section_details)
+ {
+ sprintf (buff, "[%8.8lx]: ", (unsigned long) sh_flags);
+ p += 8 + 4;
+ }
while (sh_flags)
{
@@ -3798,38 +3825,94 @@ get_elf_section_flags (bfd_vma sh_flags)
flag = sh_flags & - sh_flags;
sh_flags &= ~ flag;
- switch (flag)
+ if (do_section_details)
{
- case SHF_WRITE: *p = 'W'; break;
- case SHF_ALLOC: *p = 'A'; break;
- case SHF_EXECINSTR: *p = 'X'; break;
- case SHF_MERGE: *p = 'M'; break;
- case SHF_STRINGS: *p = 'S'; break;
- case SHF_INFO_LINK: *p = 'I'; break;
- case SHF_LINK_ORDER: *p = 'L'; break;
- case SHF_OS_NONCONFORMING: *p = 'O'; break;
- case SHF_GROUP: *p = 'G'; break;
- case SHF_TLS: *p = 'T'; break;
+ switch (flag)
+ {
+ case SHF_WRITE: index = 0; break;
+ case SHF_ALLOC: index = 1; break;
+ case SHF_EXECINSTR: index = 2; break;
+ case SHF_MERGE: index = 3; break;
+ case SHF_STRINGS: index = 4; break;
+ case SHF_INFO_LINK: index = 5; break;
+ case SHF_LINK_ORDER: index = 6; break;
+ case SHF_OS_NONCONFORMING: index = 7; break;
+ case SHF_GROUP: index = 8; break;
+ case SHF_TLS: index = 9; break;
- default:
- if (elf_header.e_machine == EM_X86_64
- && flag == SHF_X86_64_LARGE)
- *p = 'l';
+ default:
+ index = -1;
+ break;
+ }
+
+ if (p != buff + 8 + 4)
+ {
+ if (size < 10 + 2)
+ abort ();
+ size -= 2;
+ *p++ = ',';
+ *p++ = ' ';
+ }
+
+ if (index != -1)
+ {
+ size -= flags [index].len;
+ p = stpcpy (p, flags [index].str);
+ }
else if (flag & SHF_MASKOS)
{
- *p = 'o';
- sh_flags &= ~ SHF_MASKOS;
+ size -= 5 + 8;
+ sprintf (p, "OS (%8.8lx)", (unsigned long) flag);
+ p += 5 + 8;
}
else if (flag & SHF_MASKPROC)
{
- *p = 'p';
- sh_flags &= ~ SHF_MASKPROC;
+ size -= 7 + 8;
+ sprintf (p, "PROC (%8.8lx)", (unsigned long) flag);
+ p += 7 + 8;
}
else
- *p = 'x';
- break;
+ {
+ size -= 10 + 8;
+ sprintf (p, "UNKNOWN (%8.8lx)", (unsigned long) flag);
+ p += 10 + 8;
+ }
+ }
+ else
+ {
+ switch (flag)
+ {
+ case SHF_WRITE: *p = 'W'; break;
+ case SHF_ALLOC: *p = 'A'; break;
+ case SHF_EXECINSTR: *p = 'X'; break;
+ case SHF_MERGE: *p = 'M'; break;
+ case SHF_STRINGS: *p = 'S'; break;
+ case SHF_INFO_LINK: *p = 'I'; break;
+ case SHF_LINK_ORDER: *p = 'L'; break;
+ case SHF_OS_NONCONFORMING: *p = 'O'; break;
+ case SHF_GROUP: *p = 'G'; break;
+ case SHF_TLS: *p = 'T'; break;
+
+ default:
+ if (elf_header.e_machine == EM_X86_64
+ && flag == SHF_X86_64_LARGE)
+ *p = 'l';
+ else if (flag & SHF_MASKOS)
+ {
+ *p = 'o';
+ sh_flags &= ~ SHF_MASKOS;
+ }
+ else if (flag & SHF_MASKPROC)
+ {
+ *p = 'p';
+ sh_flags &= ~ SHF_MASKPROC;
+ }
+ else
+ *p = 'x';
+ break;
+ }
+ p++;
}
- p++;
}
*p = '\0';
@@ -4009,10 +4092,10 @@ process_section_headers (FILE *file)
if (is_32bit_elf)
{
- if (do_full_section_name)
+ if (do_section_details)
{
printf (_(" [Nr] Name\n"));
- printf (_(" Type Addr Off Size ES Flg Lk Inf Al\n"));
+ printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
}
else
printf
@@ -4020,10 +4103,10 @@ process_section_headers (FILE *file)
}
else if (do_wide)
{
- if (do_full_section_name)
+ if (do_section_details)
{
printf (_(" [Nr] Name\n"));
- printf (_(" Type Address Off Size ES Flg Lk Inf Al\n"));
+ printf (_(" Type Address Off Size ES Lk Inf Al\n"));
}
else
printf
@@ -4031,11 +4114,11 @@ process_section_headers (FILE *file)
}
else
{
- if (do_full_section_name)
+ if (do_section_details)
{
printf (_(" [Nr] Name\n"));
- printf (_(" Flags Type Address Offset\n"));
- printf (_(" Size EntSize Link Info Align\n"));
+ printf (_(" Type Address Offset Link\n"));
+ printf (_(" Size EntSize Info Align\n"));
}
else
{
@@ -4044,11 +4127,14 @@ process_section_headers (FILE *file)
}
}
+ if (do_section_details)
+ printf (_(" Flags\n"));
+
for (i = 0, section = section_headers;
i < elf_header.e_shnum;
i++, section++)
{
- if (do_full_section_name)
+ if (do_section_details)
{
printf (" [%2u] %s\n",
SECTION_HEADER_NUM (i),
@@ -4072,7 +4158,10 @@ process_section_headers (FILE *file)
(unsigned long) section->sh_size,
(unsigned long) section->sh_entsize);
- printf (" %3s ", get_elf_section_flags (section->sh_flags));
+ if (do_section_details)
+ fputs (" ", stdout);
+ else
+ printf (" %3s ", get_elf_section_flags (section->sh_flags));
printf ("%2ld %3lu %2ld\n",
(unsigned long) section->sh_link,
@@ -4107,7 +4196,10 @@ process_section_headers (FILE *file)
print_vma (section->sh_entsize, LONG_HEX);
}
- printf (" %3s ", get_elf_section_flags (section->sh_flags));
+ if (do_section_details)
+ fputs (" ", stdout);
+ else
+ printf (" %3s ", get_elf_section_flags (section->sh_flags));
printf ("%2ld %3lu ",
(unsigned long) section->sh_link,
@@ -4121,27 +4213,24 @@ process_section_headers (FILE *file)
putchar ('\n');
}
}
- else if (do_full_section_name)
+ else if (do_section_details)
{
- printf (" %-15.15s %-15.15s ",
- get_elf_section_flags (section->sh_flags),
+ printf (" %-15.15s ",
get_section_type_name (section->sh_type));
- putchar (' ');
print_vma (section->sh_addr, LONG_HEX);
if ((long) section->sh_offset == section->sh_offset)
- printf (" %8.8lx", (unsigned long) section->sh_offset);
+ printf (" %16.16lx", (unsigned long) section->sh_offset);
else
{
printf (" ");
print_vma (section->sh_offset, LONG_HEX);
}
- printf ("\n ");
+ printf (" %ld\n ", (unsigned long) section->sh_link);
print_vma (section->sh_size, LONG_HEX);
- printf (" ");
+ putchar (' ');
print_vma (section->sh_entsize, LONG_HEX);
- printf (" %2ld %3lu %ld\n",
- (unsigned long) section->sh_link,
+ printf (" %-16lu %ld\n",
(unsigned long) section->sh_info,
(unsigned long) section->sh_addralign);
}
@@ -4168,9 +4257,13 @@ process_section_headers (FILE *file)
(unsigned long) section->sh_info,
(unsigned long) section->sh_addralign);
}
+
+ if (do_section_details)
+ printf (" %s\n", get_elf_section_flags (section->sh_flags));
}
- printf (_("Key to Flags:\n\
+ if (!do_section_details)
+ printf (_("Key to Flags:\n\
W (write), A (alloc), X (execute), M (merge), S (strings)\n\
I (info), L (link order), G (group), x (unknown)\n\
O (extra OS processing required) o (OS specific), p (processor specific)\n"));