diff options
author | Dmitry V. Levin <ldv@altlinux.org> | 2005-05-27 15:05:34 +0000 |
---|---|---|
committer | Dmitry V. Levin <ldv@altlinux.org> | 2005-05-27 15:05:34 +0000 |
commit | adf16cc80af8833e2516ed7345cc5fae50a20aa5 (patch) | |
tree | 4da6071004ace465a2219458f6dbb81457696551 /elfutils/src/readelf.c | |
parent | 6c721476c2e4977e4e59d676c01a40e584077c26 (diff) | |
download | elfutils-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.c | 532 |
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)). */ |