From: Ulrich Drepper Date: Sat, 17 Jan 2009 01:58:54 +0000 (-0800) Subject: Finish implementation of exception handling table dumping in readelf. X-Git-Tag: elfutils-0.139~21 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=05d2b20ec250a51de74066a203b516f11bc30d89;p=platform%2Fupstream%2Felfutils.git Finish implementation of exception handling table dumping in readelf. --- diff --git a/NEWS b/NEWS index b48aeed..e041437 100644 --- a/NEWS +++ b/NEWS @@ -2,7 +2,8 @@ Version 0.139: libcpu: Add Intel SSE4 disassembler support -readelf: Implement call frame information dumping. +readelf: Implement call frame information and exception handling dumping. + Add -e option. Enable it implicitly for -a. libdwfl: Support automatic gzip/bzip2 decompression of ELF files. diff --git a/src/ChangeLog b/src/ChangeLog index 0d4149e..ab13810 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -2,6 +2,7 @@ * readelf.c: Add -e option. Dump exception and unwind related sections. Add -e to -a. + (print_encoding_base): Handle DW_EH_PE_omit. (print_debug_exception_table): Beginning of support. (print_debug): Hook up print_debug_exception_table for .gcc_except_table sections. diff --git a/src/readelf.c b/src/readelf.c index df56599..5d74cb5 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -4463,23 +4463,28 @@ print_encoding_base (const char *pfx, unsigned int fde_encoding) { printf ("(%s", pfx); - unsigned int w = fde_encoding; + if (fde_encoding == DW_EH_PE_omit) + puts ("omit)"); + else + { + unsigned int w = fde_encoding; - if (w & 0xf) - w = print_encoding (w); + if (w & 0xf) + w = print_encoding (w); - if (w & 0x70) - { - if (w != fde_encoding) - fputc_unlocked (' ', stdout); + if (w & 0x70) + { + if (w != fde_encoding) + fputc_unlocked (' ', stdout); - w = print_relinfo (w); - } + w = print_relinfo (w); + } - if (w != 0) - printf ("(%s%x", w != fde_encoding ? " " : "", w); + if (w != 0) + printf ("%s%x", w != fde_encoding ? " " : "", w); - puts (")"); + puts (")"); + } } @@ -6074,7 +6079,7 @@ static void print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)), Ebl *ebl __attribute__ ((unused)), GElf_Ehdr *ehdr __attribute__ ((unused)), - Elf_Scn *scn __attribute__ ((unused)), + Elf_Scn *scn, GElf_Shdr *shdr __attribute__ ((unused)), Dwarf *dbg __attribute__ ((unused))) { @@ -6090,6 +6095,135 @@ print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)), ".gcc_except_table", elf_errmsg (-1)); return; } + + const unsigned char *readp = data->d_buf; + const unsigned char *const dataend = readp + data->d_size; + + if (unlikely (readp + 1 > dataend)) + { + invalid_data: + error (0, 0, gettext ("invalid data")); + return; + } + unsigned int lpstart_encoding = *readp++; + printf (gettext (" LPStart encoding: %#x "), lpstart_encoding); + print_encoding_base ("", lpstart_encoding); + if (lpstart_encoding != DW_EH_PE_omit) + { + uint64_t lpstart; + readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg); + printf (" LPStart: %#" PRIx64 "\n", lpstart); + } + + if (unlikely (readp + 1 > dataend)) + goto invalid_data; + unsigned int ttype_encoding = *readp++; + printf (gettext (" TType encoding: %#x "), ttype_encoding); + print_encoding_base ("", ttype_encoding); + const unsigned char *ttype_base = NULL; + if (ttype_encoding != DW_EH_PE_omit) + { + unsigned int ttype_base_offset; + get_uleb128 (ttype_base_offset, readp); + printf (" TType base offset: %#x\n", ttype_base_offset); + ttype_base = readp + ttype_base_offset; + } + + if (unlikely (readp + 1 > dataend)) + goto invalid_data; + unsigned int call_site_encoding = *readp++; + printf (gettext (" Call site encoding: %#x "), call_site_encoding); + print_encoding_base ("", call_site_encoding); + unsigned int call_site_table_len; + get_uleb128 (call_site_table_len, readp); + + const unsigned char *const action_table = readp + call_site_table_len; + if (unlikely (action_table > dataend)) + goto invalid_data; + unsigned int u = 0; + unsigned int max_action = 0; + while (readp < action_table) + { + if (u == 0) + puts (gettext ("\n Call site table:")); + + uint64_t call_site_start; + readp = read_encoded (call_site_encoding, readp, dataend, + &call_site_start, dbg); + uint64_t call_site_length; + readp = read_encoded (call_site_encoding, readp, dataend, + &call_site_length, dbg); + uint64_t landing_pad; + readp = read_encoded (call_site_encoding, readp, dataend, + &landing_pad, dbg); + unsigned int action; + get_uleb128 (action, readp); + max_action = MAX (action, max_action); + printf (gettext (" [%4u] Call site start: %#" PRIx64 "\n" + " Call site length: %" PRIu64 "\n" + " Landing pad: %#" PRIx64 "\n" + " Action: %u\n"), + u++, call_site_start, call_site_length, landing_pad, action); + } + assert (readp == action_table); + + unsigned int max_ar_filter = 0; + if (max_action > 0) + { + puts ("\n Action table:"); + + const unsigned char *const action_table_end + = action_table + max_action + 1; + + u = 0; + do + { + int ar_filter; + get_sleb128 (ar_filter, readp); + if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter) + max_ar_filter = ar_filter; + int ar_disp; + get_sleb128 (ar_disp, readp); + + printf (" [%4u] ar_filter: %d\n" + " ar_disp: %d\n", + u++, ar_filter, ar_disp); + } + while (readp < action_table_end); + } + + if (max_ar_filter > 0) + { + puts ("\n TType table:"); + + // XXX Not *4, size of encoding; + switch (ttype_encoding & 7) + { + case DW_EH_PE_udata2: + case DW_EH_PE_sdata2: + readp = ttype_base - max_ar_filter * 2; + break; + case DW_EH_PE_udata4: + case DW_EH_PE_sdata4: + readp = ttype_base - max_ar_filter * 4; + break; + case DW_EH_PE_udata8: + case DW_EH_PE_sdata8: + readp = ttype_base - max_ar_filter * 8; + break; + default: + error (1, 0, gettext ("invalid TType encoding")); + } + + do + { + uint64_t ttype; + readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype, + dbg); + printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype); + } + while (readp < ttype_base); + } }