summaryrefslogtreecommitdiff
path: root/elfutils/src/readelf.c
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@altlinux.org>2005-05-27 15:05:34 +0000
committerDmitry V. Levin <ldv@altlinux.org>2005-05-27 15:05:34 +0000
commitadf16cc80af8833e2516ed7345cc5fae50a20aa5 (patch)
tree4da6071004ace465a2219458f6dbb81457696551 /elfutils/src/readelf.c
parent6c721476c2e4977e4e59d676c01a40e584077c26 (diff)
downloadelfutils-bc717c9575ae8f759e4b79b6a7f0b1a673b18b28.tar.gz
0.108-alt10.108-alt1
- Updated to 0.108.
Diffstat (limited to 'elfutils/src/readelf.c')
-rw-r--r--elfutils/src/readelf.c532
1 files changed, 388 insertions, 144 deletions
diff --git a/elfutils/src/readelf.c b/elfutils/src/readelf.c
index 6129e29d..8386a397 100644
--- a/elfutils/src/readelf.c
+++ b/elfutils/src/readelf.c
@@ -1,5 +1,5 @@
/* Print information from ELF file in human-readable form.
- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 1999.
This program is Open Source software; you can redistribute it and/or
@@ -45,30 +45,33 @@
static void print_version (FILE *stream, struct argp_state *state);
void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
+/* Bug report address. */
+const char *argp_program_bug_address = PACKAGE_BUGREPORT;
+
/* Definitions of arguments for argp functions. */
static const struct argp_option options[] =
{
- { NULL, 0, NULL, 0, N_("Output selection:") },
- { "all", 'a', NULL, 0, N_("Equivalent to: -h -l") },
- { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment") },
- { "file-header", 'h', NULL, 0, N_("Display the ELF file header") },
+ { NULL, 0, NULL, 0, N_("Output selection:"), 0 },
+ { "all", 'a', NULL, 0, N_("Equivalent to: -h -l"), 0 },
+ { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 },
+ { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 },
{ "histogram", 'I', NULL, 0,
- N_("Display histogram of bucket list lengths") },
- { "program-headers", 'l', NULL, 0, N_("Display the program headers") },
- { "relocs", 'r', NULL, 0, N_("Display relocations") },
- { "section-headers", 'S', NULL, 0, N_("Display the sections' header") },
- { "symbols", 's', NULL, 0, N_("Display the symbol table") },
- { "version-info", 'V', NULL, 0, N_("Display versioning information") },
+ N_("Display histogram of bucket list lengths"), 0 },
+ { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 },
+ { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 },
+ { "section-headers", 'S', NULL, 0, N_("Display the sections' header"), 0 },
+ { "symbols", 's', NULL, 0, N_("Display the symbol table"), 0 },
+ { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
{ "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL,
N_("Display DWARF section content. SECTION can be one of abbrev, "
- "aranges, frame, info, loc, line, pubnames, str, or macinfo.") },
- { "notes", 'n', NULL, 0, N_("Display the core notes") },
+ "aranges, frame, info, loc, line, pubnames, str, or macinfo."), 0 },
+ { "notes", 'n', NULL, 0, N_("Display the core notes"), 0 },
{ "arch-specific", 'A', NULL, 0,
- N_("Display architecture specific information (if any)") },
+ N_("Display architecture specific information (if any)"), 0 },
- { NULL, 0, NULL, 0, N_("Output control:") },
+ { NULL, 0, NULL, 0, N_("Output control:"), 0 },
- { NULL, 0, NULL, 0, NULL }
+ { NULL, 0, NULL, 0, NULL, 0 }
};
/* Short description of program. */
@@ -81,21 +84,15 @@ static const char args_doc[] = N_("FILE...");
/* Prototype for option handler. */
static error_t parse_opt (int key, char *arg, struct argp_state *state);
-/* Function to print some extra text in the help message. */
-static char *more_help (int key, const char *text, void *input);
-
/* Data structure to communicate with argp functions. */
static struct argp argp =
{
- options, parse_opt, args_doc, doc, NULL, more_help
+ options, parse_opt, args_doc, doc, NULL, NULL, NULL
};
/* Flags set by the option controlling the output. */
-/* True if any of the control options is set. */
-static bool any_control_option;
-
/* True if dynamic segment should be printed. */
static bool print_dynamic_table;
@@ -158,35 +155,27 @@ static void process_elf_file (Elf *elf, const char *prefix, const char *fname,
static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
-static void print_scngrp (Ebl *ebl, GElf_Ehdr *ehdr);
-static void print_dynamic (Ebl *ebl, GElf_Ehdr *ehdr);
-static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr);
-static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
- GElf_Shdr *shdr);
-static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
- GElf_Shdr *shdr);
-static void print_symtab (Ebl *ebl, GElf_Ehdr *ehdr, int type);
-static void handle_symtab (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
- GElf_Shdr *shdr);
-static void print_verinfo (Ebl *ebl, GElf_Ehdr *ehdr);
-static void handle_verneed (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
- GElf_Shdr *shdr);
-static void handle_verdef (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
- GElf_Shdr *shdr);
-static void handle_versym (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
+static void print_scngrp (Ebl *ebl);
+static void print_dynamic (Ebl *ebl);
+static void print_relocs (Ebl *ebl);
+static void handle_relocs_rel (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
+static void handle_relocs_rela (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
+static void print_symtab (Ebl *ebl, int type);
+static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
+static void print_verinfo (Ebl *ebl);
+static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
+static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
+static void handle_versym (Ebl *ebl, Elf_Scn *scn,
GElf_Shdr *shdr);
static void print_debug (Ebl *ebl, GElf_Ehdr *ehdr);
-static void handle_hash (Ebl *ebl, GElf_Ehdr *ehdr);
+static void handle_hash (Ebl *ebl);
static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
-static void print_liblist (Ebl *ebl, GElf_Ehdr *ehdr);
+static void print_liblist (Ebl *ebl);
int
main (int argc, char *argv[])
{
- int remaining;
- bool only_one;
-
/* Set locale. */
setlocale (LC_ALL, "");
@@ -194,29 +183,18 @@ main (int argc, char *argv[])
textdomain (PACKAGE);
/* Parse and process arguments. */
+ int remaining;
argp_parse (&argp, argc, argv, 0, &remaining, NULL);
- /* If no control option or no ELF file is given punt. */
- if ((any_control_option == 0 && print_debug_sections == 0)
- || remaining >= argc)
- {
- argp_help (&argp, stdout, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR,
- program_invocation_short_name);
- exit (1);
- }
-
/* Before we start tell the ELF library which version we are using. */
elf_version (EV_CURRENT);
/* Now process all the files given at the command line. */
- only_one = remaining + 1 == argc;
+ bool only_one = remaining + 1 == argc;
do
{
- int fd;
- Elf *elf;
-
/* Open the file. */
- fd = open (argv[remaining], O_RDONLY);
+ int fd = open (argv[remaining], O_RDONLY);
if (fd == -1)
{
error (0, errno, gettext ("cannot open input file"));
@@ -224,7 +202,7 @@ main (int argc, char *argv[])
}
/* Create an `Elf' descriptor. */
- elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
+ Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
if (elf == NULL)
error (0, 0, gettext ("cannot generate Elf descriptor: %s\n"),
elf_errmsg (-1));
@@ -248,8 +226,12 @@ main (int argc, char *argv[])
/* Handle program arguments. */
static error_t
-parse_opt (int key, char *arg, struct argp_state *state)
+parse_opt (int key, char *arg,
+ struct argp_state *state __attribute__ ((unused)))
{
+ /* True if any of the control options is set. */
+ static bool any_control_option;
+
switch (key)
{
case 'a':
@@ -339,6 +321,20 @@ parse_opt (int key, char *arg, struct argp_state *state)
program_invocation_short_name);
exit (1);
}
+ any_control_option = true;
+ break;
+ case ARGP_KEY_NO_ARGS:
+ fputs (gettext ("Missing file name.\n"), stderr);
+ goto do_argp_help;
+ case ARGP_KEY_FINI:
+ if (! any_control_option)
+ {
+ fputs (gettext ("No operation specified.\n"), stderr);
+ do_argp_help:
+ argp_help (&argp, stderr, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR,
+ program_invocation_short_name);
+ exit (1);
+ }
break;
default:
return ARGP_ERR_UNKNOWN;
@@ -347,37 +343,16 @@ parse_opt (int key, char *arg, struct argp_state *state)
}
-static char *
-more_help (int key, const char *text, void *input)
-{
- char *buf;
-
- switch (key)
- {
- case ARGP_KEY_HELP_EXTRA:
- /* We print some extra information. */
- if (asprintf (&buf, gettext ("Please report bugs to %s.\n"),
- PACKAGE_BUGREPORT) < 0)
- buf = NULL;
- return buf;
-
- default:
- break;
- }
- return (char *) text;
-}
-
-
/* Print the version information. */
static void
-print_version (FILE *stream, struct argp_state *state)
+print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
{
fprintf (stream, "readelf (%s) %s\n", PACKAGE_NAME, VERSION);
fprintf (stream, gettext ("\
Copyright (C) %s Red Hat, Inc.\n\
This is free software; see the source for copying conditions. There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
-"), "2004");
+"), "2005");
fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
}
@@ -497,21 +472,21 @@ process_elf_file (Elf *elf, const char *prefix, const char *fname,
if (print_program_header)
print_phdr (ebl, ehdr);
if (print_section_groups)
- print_scngrp (ebl, ehdr);
+ print_scngrp (ebl);
if (print_dynamic_table)
- print_dynamic (ebl, ehdr);
+ print_dynamic (ebl);
if (print_relocations)
- print_relocs (ebl, ehdr);
+ print_relocs (ebl);
if (print_histogram)
- handle_hash (ebl, ehdr);
+ handle_hash (ebl);
if (print_symbol_table)
- print_symtab (ebl, ehdr, SHT_DYNSYM);
+ print_symtab (ebl, SHT_DYNSYM);
if (print_version_info)
- print_verinfo (ebl, ehdr);
+ print_verinfo (ebl);
if (print_symbol_table)
- print_symtab (ebl, ehdr, SHT_SYMTAB);
+ print_symtab (ebl, SHT_SYMTAB);
if (print_arch)
- print_liblist (ebl, ehdr);
+ print_liblist (ebl);
if (print_debug_sections != 0)
print_debug (ebl, ehdr);
if (print_notes)
@@ -851,6 +826,7 @@ print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
/* Iterate over the sections. */
bool in_relro = false;
+ bool in_ro = false;
for (inner = 1; inner < shnum; ++inner)
{
Elf_Scn *scn = elf_getscn (ebl->elf, inner);
@@ -895,6 +871,45 @@ print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
else if (has_relro && in_relro
&& shdr->sh_addr + shdr->sh_size > relro_to)
fputs_unlocked ("] <RELRO:", stdout);
+ else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
+ {
+ if (!in_ro)
+ {
+ fputs_unlocked (" [RO:", stdout);
+ in_ro = true;
+ }
+ }
+ else
+ {
+ /* Determine the segment this section is part of. */
+ size_t cnt2;
+ GElf_Phdr *phdr2 = NULL;
+ for (cnt2 = 0; cnt2 < ehdr->e_phnum; ++cnt2)
+ {
+ GElf_Phdr phdr2_mem;
+ phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
+
+ if (phdr2 != NULL && phdr2->p_type == PT_LOAD
+ && shdr->sh_addr >= phdr2->p_vaddr
+ && (shdr->sh_addr + shdr->sh_size
+ <= phdr2->p_vaddr + phdr2->p_memsz))
+ break;
+ }
+
+ if (cnt2 < ehdr->e_phnum)
+ {
+ if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
+ {
+ fputs_unlocked (" [RO:", stdout);
+ in_ro = true;
+ }
+ else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
+ {
+ fputs_unlocked ("]", stdout);
+ in_ro = false;
+ }
+ }
+ }
printf (" %s",
elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
@@ -908,7 +923,7 @@ print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
}
}
}
- if (in_relro)
+ if (in_relro || in_ro)
fputs_unlocked ("]", stdout);
/* Finish the line. */
@@ -918,7 +933,7 @@ print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
static void
-handle_scngrp (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
+handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
{
Elf_Data *data;
Elf32_Word *grpref;
@@ -985,7 +1000,7 @@ handle_scngrp (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
static void
-print_scngrp (Ebl *ebl, GElf_Ehdr *ehdr)
+print_scngrp (Ebl *ebl)
{
/* Find all relocation sections and handle them. */
Elf_Scn *scn = NULL;
@@ -997,7 +1012,7 @@ print_scngrp (Ebl *ebl, GElf_Ehdr *ehdr)
GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
if (shdr != NULL && shdr->sh_type == SHT_GROUP)
- handle_scngrp (ebl, ehdr, scn, shdr);
+ handle_scngrp (ebl, scn, shdr);
}
}
@@ -1112,7 +1127,7 @@ print_dt_posflag_1 (int class, GElf_Xword d_val)
static void
-handle_dynamic (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
+handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
{
int class = gelf_getclass (ebl->elf);
GElf_Shdr glink;
@@ -1244,7 +1259,7 @@ handle_dynamic (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
/* Print the dynamic segment. */
static void
-print_dynamic (Ebl *ebl, GElf_Ehdr *ehdr)
+print_dynamic (Ebl *ebl)
{
/* Find all relocation sections and handle them. */
Elf_Scn *scn = NULL;
@@ -1257,7 +1272,7 @@ print_dynamic (Ebl *ebl, GElf_Ehdr *ehdr)
if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
{
- handle_dynamic (ebl, ehdr, scn, shdr);
+ handle_dynamic (ebl, scn, shdr);
break;
}
}
@@ -1266,7 +1281,7 @@ print_dynamic (Ebl *ebl, GElf_Ehdr *ehdr)
/* Print relocations. */
static void
-print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
+print_relocs (Ebl *ebl)
{
/* Find all relocation sections and handle them. */
Elf_Scn *scn = NULL;
@@ -1280,9 +1295,9 @@ print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
if (shdr != NULL)
{
if (shdr->sh_type == SHT_REL)
- handle_relocs_rel (ebl, ehdr, scn, shdr);
+ handle_relocs_rel (ebl, scn, shdr);
else if (shdr->sh_type == SHT_RELA)
- handle_relocs_rela (ebl, ehdr, scn, shdr);
+ handle_relocs_rela (ebl, scn, shdr);
}
}
}
@@ -1290,7 +1305,7 @@ print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
/* Handle a relocation section. */
static void
-handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
+handle_relocs_rel (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
{
int class = gelf_getclass (ebl->elf);
int nentries = shdr->sh_size / shdr->sh_entsize;
@@ -1456,7 +1471,7 @@ handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
/* Handle a relocation section. */
static void
-handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
+handle_relocs_rela (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
{
int class = gelf_getclass (ebl->elf);
int nentries = shdr->sh_size / shdr->sh_entsize;
@@ -1604,7 +1619,7 @@ handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
/* Print the program header. */
static void
-print_symtab (Ebl *ebl, GElf_Ehdr *ehdr, int type)
+print_symtab (Ebl *ebl, int type)
{
/* Find the symbol table(s). For this we have to search through the
section table. */
@@ -1617,13 +1632,13 @@ print_symtab (Ebl *ebl, GElf_Ehdr *ehdr, int type)
GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
- handle_symtab (ebl, ehdr, scn, shdr);
+ handle_symtab (ebl, scn, shdr);
}
}
static void
-handle_symtab (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
+handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
{
Elf_Data *versym_data = NULL;
Elf_Data *verneed_data = NULL;
@@ -1863,7 +1878,7 @@ handle_symtab (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
/* Print version information. */
static void
-print_verinfo (Ebl *ebl, GElf_Ehdr *ehdr)
+print_verinfo (Ebl *ebl)
{
/* Find the version information sections. For this we have to
search through the section table. */
@@ -1878,11 +1893,11 @@ print_verinfo (Ebl *ebl, GElf_Ehdr *ehdr)
if (shdr != NULL)
{
if (shdr->sh_type == SHT_GNU_verneed)
- handle_verneed (ebl, ehdr, scn, shdr);
+ handle_verneed (ebl, scn, shdr);
else if (shdr->sh_type == SHT_GNU_verdef)
- handle_verdef (ebl, ehdr, scn, shdr);
+ handle_verdef (ebl, scn, shdr);
else if (shdr->sh_type == SHT_GNU_versym)
- handle_versym (ebl, ehdr, scn, shdr);
+ handle_versym (ebl, scn, shdr);
}
}
}
@@ -1921,7 +1936,7 @@ get_ver_flags (unsigned int flags)
static void
-handle_verneed (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
+handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
{
Elf_Data *data;
int class = gelf_getclass (ebl->elf);
@@ -1998,7 +2013,7 @@ handle_verneed (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
static void
-handle_verdef (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
+handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
{
Elf_Data *data;
int class = gelf_getclass (ebl->elf);
@@ -2081,7 +2096,7 @@ handle_verdef (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
static void
-handle_versym (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
+handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
{
Elf_Data *data;
int class = gelf_getclass (ebl->elf);
@@ -2374,7 +2389,7 @@ handle_versym (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
static void
-handle_hash (Ebl *ebl, GElf_Ehdr *ehdr)
+handle_hash (Ebl *ebl)
{
/* Find the symbol table(s). For this we have to search through the
section table. */
@@ -2500,7 +2515,7 @@ handle_hash (Ebl *ebl, GElf_Ehdr *ehdr)
static void
-print_liblist (Ebl *ebl, GElf_Ehdr *ehdr)
+print_liblist (Ebl *ebl)
{
/* Find the library list sections. For this we have to search
through the section table. */
@@ -2916,7 +2931,7 @@ dwarf_lang_string (unsigned int lang)
if (lang >= DW_LANG_lo_user && lang <= DW_LANG_hi_user)
{
- static char buf[100];
+ static char buf[30];
snprintf (buf, sizeof (buf), "lo_user+%u", lang - DW_LANG_lo_user);
return buf;
}
@@ -2925,6 +2940,180 @@ dwarf_lang_string (unsigned int lang)
}
+static const char *
+dwarf_inline_string (unsigned int code)
+{
+ static const char *known[] =
+ {
+ [DW_INL_not_inlined] = "not_inlined",
+ [DW_INL_inlined] = "inlined",
+ [DW_INL_declared_not_inlined] = "declared_not_inlined",
+ [DW_INL_declared_inlined] = "declared_inlined"
+ };
+
+ if (code < sizeof (known) / sizeof (known[0]))
+ return known[code];
+
+ return "???";
+}
+
+
+static const char *
+dwarf_encoding_string (unsigned int code)
+{
+ static const char *known[] =
+ {
+ [DW_ATE_void] = "void",
+ [DW_ATE_address] = "address",
+ [DW_ATE_boolean] = "boolean",
+ [DW_ATE_complex_float] = "complex_float",
+ [DW_ATE_float] = "float",
+ [DW_ATE_signed] = "signed",
+ [DW_ATE_signed_char] = "signed_char",
+ [DW_ATE_unsigned] = "unsigned",
+ [DW_ATE_unsigned_char] = "unsigned_char",
+ [DW_ATE_imaginary_float] = "imaginary_float"
+ };
+
+ if (code < sizeof (known) / sizeof (known[0]))
+ return known[code];
+
+ if (code >= DW_ATE_lo_user && code <= DW_ATE_hi_user)
+ {
+ static char buf[30];
+ snprintf (buf, sizeof (buf), "lo_user+%u", code - DW_ATE_lo_user);
+ return buf;
+ }
+
+ return "???";
+}
+
+
+static const char *
+dwarf_access_string (unsigned int code)
+{
+ static const char *known[] =
+ {
+ [DW_ACCESS_public] = "public",
+ [DW_ACCESS_protected] = "protected",
+ [DW_ACCESS_private] = "private"
+ };
+
+ if (code < sizeof (known) / sizeof (known[0]))
+ return known[code];
+
+ return "???";
+}
+
+
+static const char *
+dwarf_visibility_string (unsigned int code)
+{
+ static const char *known[] =
+ {
+ [DW_VIS_local] = "local",
+ [DW_VIS_exported] = "exported",
+ [DW_VIS_qualified] = "qualified"
+ };
+
+ if (code < sizeof (known) / sizeof (known[0]))
+ return known[code];
+
+ return "???";
+}
+
+
+static const char *
+dwarf_virtuality_string (unsigned int code)
+{
+ static const char *known[] =
+ {
+ [DW_VIRTUALITY_none] = "none",
+ [DW_VIRTUALITY_virtual] = "virtual",
+ [DW_VIRTUALITY_pure_virtual] = "pure_virtual"
+ };
+
+ if (code < sizeof (known) / sizeof (known[0]))
+ return known[code];
+
+ return "???";
+}
+
+
+static const char *
+dwarf_identifier_case_string (unsigned int code)
+{
+ static const char *known[] =
+ {
+ [DW_ID_case_sensitive] = "sensitive",
+ [DW_ID_up_case] = "up_case",
+ [DW_ID_down_case] = "down_case",
+ [DW_ID_case_insensitive] = "insensitive"
+ };
+
+ if (code < sizeof (known) / sizeof (known[0]))
+ return known[code];
+
+ return "???";
+}
+
+
+static const char *
+dwarf_calling_convention_string (unsigned int code)
+{
+ static const char *known[] =
+ {
+ [DW_CC_normal] = "normal",
+ [DW_CC_program] = "program",
+ [DW_CC_nocall] = "nocall",
+ };
+
+ if (code < sizeof (known) / sizeof (known[0]))
+ return known[code];
+
+ if (code >= DW_CC_lo_user && code <= DW_CC_hi_user)
+ {
+ static char buf[30];
+ snprintf (buf, sizeof (buf), "lo_user+%u", code - DW_CC_lo_user);
+ return buf;
+ }
+
+ return "???";
+}
+
+
+static const char *
+dwarf_ordering_string (unsigned int code)
+{
+ static const char *known[] =
+ {
+ [DW_ORD_row_major] = "row_major",
+ [DW_ORD_col_major] = "col_major"
+ };
+
+ if (code < sizeof (known) / sizeof (known[0]))
+ return known[code];
+
+ return "???";
+}
+
+
+static const char *
+dwarf_discr_list_string (unsigned int code)
+{
+ static const char *known[] =
+ {
+ [DW_DSC_label] = "label",
+ [DW_DSC_range] = "range"
+ };
+
+ if (code < sizeof (known) / sizeof (known[0]))
+ return known[code];
+
+ return "???";
+}
+
+
static void
print_ops (Dwarf *dbg, int level, unsigned int addrsize, Dwarf_Word len,
unsigned char *data)
@@ -3249,7 +3438,9 @@ print_ops (Dwarf *dbg, int level, unsigned int addrsize, Dwarf_Word len,
static void
-print_debug_abbrev_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
+print_debug_abbrev_section (Ebl *ebl __attribute__ ((unused)),
+ GElf_Ehdr *ehdr __attribute__ ((unused)),
+ Elf_Scn *scn __attribute__ ((unused)),
GElf_Shdr *shdr, Dwarf *dbg)
{
printf (gettext ("\nDWARF section '%s' at offset %#" PRIx64 ":\n"
@@ -3262,10 +3453,12 @@ print_debug_abbrev_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
size_t length;
Dwarf_Abbrev abbrev;
- if (dwarf_offabbrev (dbg, offset, &length, &abbrev) != 0)
+ int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
+ if (res != 0)
{
- printf (gettext (" *** error while reading abbreviation: %s\n"),
- dwarf_errmsg (-1));
+ if (res < 0)
+ printf (gettext (" *** error while reading abbreviation: %s\n"),
+ dwarf_errmsg (-1));
break;
}
@@ -3306,7 +3499,9 @@ print_debug_abbrev_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
not have to know a bit about the structure of the section, libdwarf
takes care of it. */
static void
-print_debug_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
+print_debug_aranges_section (Ebl *ebl __attribute__ ((unused)),
+ GElf_Ehdr *ehdr __attribute__ ((unused)),
+ Elf_Scn *scn __attribute__ ((unused)),
GElf_Shdr *shdr, Dwarf *dbg)
{
Dwarf_Aranges *aranges;
@@ -3360,8 +3555,11 @@ print_debug_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
static void
-print_debug_frame_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
- GElf_Shdr *shdr, Dwarf *dbg)
+print_debug_frame_section (Ebl *ebl __attribute__ ((unused)),
+ GElf_Ehdr *ehdr __attribute__ ((unused)),
+ Elf_Scn *scn __attribute__ ((unused)),
+ GElf_Shdr *shdr __attribute__ ((unused)),
+ Dwarf *dbg __attribute__ ((unused)))
{
}
@@ -3448,17 +3646,52 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
if (unlikely (dwarf_formudata (attrp, &num) != 0))
goto attrval_out;
- if (attr == DW_AT_language)
+ const char *valuestr = NULL;
+ switch (attr)
{
- printf (" %*s%-20s %s (%d)\n",
- (int) (level * 2), "", dwarf_attr_string (attr),
- dwarf_lang_string (num), (int) num);
+ case DW_AT_language:
+ valuestr = dwarf_lang_string (num);
+ break;
+ case DW_AT_encoding:
+ valuestr = dwarf_encoding_string (num);
+ break;
+ case DW_AT_accessibility:
+ valuestr = dwarf_access_string (num);
+ break;
+ case DW_AT_visibility:
+ valuestr = dwarf_visibility_string (num);
+ break;
+ case DW_AT_virtuality:
+ valuestr = dwarf_virtuality_string (num);
+ break;
+ case DW_AT_identifier_case:
+ valuestr = dwarf_identifier_case_string (num);
+ break;
+ case DW_AT_calling_convention:
+ valuestr = dwarf_calling_convention_string (num);
+ break;
+ case DW_AT_inline:
+ valuestr = dwarf_inline_string (num);
+ break;
+ case DW_AT_ordering:
+ valuestr = dwarf_ordering_string (num);
+ break;
+ case DW_AT_discr_list:
+ valuestr = dwarf_discr_list_string (num);
+ break;
+ default:
+ /* Noting. */
break;
}
- printf (" %*s%-20s %" PRIuMAX "\n",
- (int) (level * 2), "", dwarf_attr_string (attr),
- (uintmax_t) num);
+ if (valuestr == NULL)
+ printf (" %*s%-20s %" PRIuMAX "\n",
+ (int) (level * 2), "", dwarf_attr_string (attr),
+ (uintmax_t) num);
+ else
+ printf (" %*s%-20s %s (%" PRIuMAX ")\n",
+ (int) (level * 2), "", dwarf_attr_string (attr),
+ valuestr, (uintmax_t) num);
break;
case DW_FORM_flag:;
@@ -3500,7 +3733,9 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
static void
-print_debug_info_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
+print_debug_info_section (Ebl *ebl __attribute__ ((unused)),
+ GElf_Ehdr *ehdr __attribute__ ((unused)),
+ Elf_Scn *scn __attribute__ ((unused)),
GElf_Shdr *shdr, Dwarf *dbg)
{
printf (gettext ("\
@@ -3511,7 +3746,7 @@ print_debug_info_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
if (shdr->sh_size == 0)
return;
- size_t maxdies = 20;
+ int maxdies = 20;
Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
Dwarf_Off offset = 0;
@@ -3554,7 +3789,7 @@ print_debug_info_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
do
{
offset = dwarf_dieoffset (&dies[level]);
- if (offset == -1l)
+ if (offset == ~0ul)
{
error (0, 0, gettext ("cannot get DIE offset: %s"),
dwarf_errmsg (-1));
@@ -3648,7 +3883,7 @@ print_debug_info_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
break;
default:
- if (tag < sizeof (lowtags) / sizeof (lowtags[0]))
+ if (tag < (int) (sizeof (lowtags) / sizeof (lowtags[0])))
tagstr = lowtags[tag];
else
tagstr = "???";
@@ -3703,8 +3938,8 @@ print_debug_info_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
static void
-print_debug_line_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
- GElf_Shdr *shdr, Dwarf *dbg)
+print_debug_line_section (Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
+ Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
{
printf (gettext ("\
\nDWARF section '%s' at offset %#" PRIx64 ":\n"),
@@ -4114,8 +4349,11 @@ define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
static void
-print_debug_loc_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
- GElf_Shdr *shdr, Dwarf *dbg)
+print_debug_loc_section (Ebl *ebl __attribute__ ((unused)),
+ GElf_Ehdr *ehdr __attribute__ ((unused)),
+ Elf_Scn *scn __attribute__ ((unused)),
+ GElf_Shdr *shdr,
+ Dwarf *dbg __attribute__ ((unused)))
{
printf (gettext ("\
\nDWARF section '%s' at offset %#" PRIx64 ":\n"),
@@ -4149,8 +4387,9 @@ mac_compare (const void *p1, const void *p2)
static void
-print_debug_macinfo_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
- GElf_Shdr *shdr, Dwarf *dbg)
+print_debug_macinfo_section (Ebl *ebl __attribute__ ((unused)),
+ GElf_Ehdr *ehdr __attribute__ ((unused)),
+ Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
{
printf (gettext ("\
\nDWARF section '%s' at offset %#" PRIx64 ":\n"),
@@ -4265,7 +4504,7 @@ print_debug_macinfo_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
get_uleb128 (u128_2, readp);
/* Find the CU DIE for this file. */
- ptrdiff_t macoff = readp - (const unsigned char *) data->d_buf;
+ size_t macoff = readp - (const unsigned char *) data->d_buf;
const char *fname = "???";
if (macoff >= cus[0].offset)
{
@@ -4304,7 +4543,8 @@ print_debug_macinfo_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
/* Callback for printing global names. */
static int
-print_pubnames (Dwarf *dbg, Dwarf_Global *global, void *arg)
+print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
+ void *arg)
{
int *np = (int *) arg;
@@ -4318,7 +4558,9 @@ print_pubnames (Dwarf *dbg, Dwarf_Global *global, void *arg)
/* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
static void
-print_debug_pubnames_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
+print_debug_pubnames_section (Ebl *ebl __attribute__ ((unused)),
+ GElf_Ehdr *ehdr __attribute__ ((unused)),
+ Elf_Scn *scn __attribute__ ((unused)),
GElf_Shdr *shdr, Dwarf *dbg)
{
printf (gettext ("\nDWARF section '%s' at offset %#" PRIx64 ":\n"),
@@ -4330,7 +4572,9 @@ print_debug_pubnames_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
/* Print the content of the DWARF string section '.debug_str'. */
static void
-print_debug_str_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
+print_debug_str_section (Ebl *ebl __attribute__ ((unused)),
+ GElf_Ehdr *ehdr __attribute__ ((unused)),
+ Elf_Scn *scn __attribute__ ((unused)),
GElf_Shdr *shdr, Dwarf *dbg)
{
/* Compute floor(log16(shdr->sh_size)). */