summaryrefslogtreecommitdiff
path: root/src/readelf.c
Commit message (Collapse)AuthorAgeFilesLines
* readelf: display dynamic symtab without section headersDi Chen2023-04-181-151/+377
| | | | | | | | | | | | | | | | | | | | | | This commit adds a new option "-D/--use-dynamic" to support printing the dynamic symbol table from the PT_DYNAMIC segment. By using the PT_DYNAMIC segment, eu-readelf can go through the contents of dynamic section entries and the values of each tag. From that, we can get the address and size of the dynamic symbol table, the address of the string table, etc. By using the new option "-D/--use-dynamic", eu-readelf can list the symbols without section headers. Example: $ ./src/readelf -Ds a.out 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UNDEF 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UNDEF __libc_start_main@GLIBC_2.34 (2) 2: 0000000000000000 0 NOTYPE WEAK DEFAULT UNDEF __gmon_start__ https://sourceware.org/bugzilla/show_bug.cgi?id=28873 Signed-off-by: Di Chen <dichen@redhat.com>
* readelf: Handle NULL shdr in section_nameMark Wielaard2023-04-141-1/+1
| | | | | | | | | | In some error cases we want to show the section name but cannot because the section header is corrupt or NULL. Make sure the section_name always returns "???" in that case. * src/readelf.c (section_name): Check for shdr == NULL. Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf: Fix use-after-free ebl pointer issueMark Wielaard2023-03-031-2/+3
| | | | | | | | | | | | | | | | | | | | | With -flto gcc 13 sees that we use the ebl pointer after closing and freeing it. In function ‘process_elf_file’, inlined from ‘process_dwflmod’ at readelf.c:818:3: readelf.c:1070:6: error: pointer ‘ebl_18’ used after ‘free’ [-Werror=use-after-free] 1070 | if (pure_ebl != ebl) | ^ In function ‘ebl_closebackend’, inlined from ‘process_elf_file’ at readelf.c:1068:3, inlined from ‘process_dwflmod’ at readelf.c:818:3: ../libebl/eblclosebackend.c:47:7: note: call to ‘free’ here 47 | free (ebl); | ^ Fix by only calling ebl_closebackend after using it in the comparison. Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw, readelf, elflint: Add get_(u|s)leb128 guardsMark Wielaard2023-02-141-0/+14
| | | | | | | | | Add sanity check making sure an leb128 isn't being read beyond the end of the current data segment. Most code already had these guards, but some were missing. This makes sure an appropriate error is generated instead. Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf: Fix set but not used parameterIlya Leoshkevich2023-02-091-12/+5
| | | | | | | | | | | | | | | | | | | | | | | clang complains: readelf.c:12205:72: error: parameter 'desc' set but not used [-Werror,-Wunused-but-set-parameter] handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc, ^ Mark Wielaard says: It is never really used since as far as I can see we don't have any backend with a core register sets where a register doesn't have a number of bits which isn't a multiple of 8 (only ia64 has some 1 bit registers, but those don't seem part of the core register set). If we do accidentally try to handle such a register having an abort is also not very nice. Lets just warn and return/continue. https://sourceware.org/bugzilla/show_bug.cgi?id=30084 Co-developed-by: Mark Wielaard <mark@klomp.org> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
* readelf: Fix set but not used variableIlya Leoshkevich2023-02-081-2/+0
| | | | | | | | | | | | clang complains: readelf.c:10250:10: error: variable 'nculist' set but not used [-Werror,-Wunused-but-set-variable] size_t nculist = 0; ^ Fix by deleting it. Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
* readelf: Check compression status of .debug section dataMark Wielaard2023-01-161-102/+111
| | | | | | | | | | The various print_debug_*_section functions didn't get the section data in the same way. Add a new get_debug_elf_data function that gets the (possibly relocated) section data and that checks (and warns) if the data might still be compressed in a way that we cannot decompress. Signed-off-by: Mark Wielaard <mark@klomp.org>
* support ZSTD compression algorithmMartin Liska2022-12-231-7/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | config/ChangeLog: * libelf.pc.in: Add LIBLZSTD to Requires.private. ChangeLog: * configure.ac: Detect ZSTD streaming API. libelf/ChangeLog: * Makefile.am: Use zstd_LIBS. * elf_compress.c: (__libelf_compress): Split into ... (__libelf_compress_zlib): ... this. (do_zstd_cleanup): New. (zstd_cleanup): New. (__libelf_compress_zstd): New. (__libelf_decompress): Switch in between zlib and zstd. (__libelf_decompress_zlib): Renamed from __libelf_decompress. (__libelf_decompress_zstd): New. (__libelf_decompress_elf): Dispatch in between compression algorithms. (elf_compress): Likewise. * elf_compress_gnu.c (elf_compress_gnu): Call with ELFCOMPRESS_ZLIB. * libelfP.h (__libelf_compress): Add new argument. (__libelf_decompress): Add chtype argument. src/ChangeLog: * elfcompress.c (enum ch_type): Add ZSTD. (parse_opt): Parse "zstd". (get_section_chtype): New. (process_file): Support zstd compression. (main): Add zstd to help. * readelf.c (elf_ch_type_name): Rewrite with switch. tests/ChangeLog: * Makefile.am: Add ELFUTILS_ZSTD if zstd is enabled. * run-compress-test.sh: Test zstd compression algorithm for debug sections.
* readelf: print warning for -sWMartin Liska2022-11-281-5/+18
| | | | | | | | | | | | | | | | | | | | | The option -s accepts in elfutils (compared to binutils) a positional argument that is name of a symbol table section which should be printed. Thus, print a reasonable warning if -sW is used: ./src/readelf -sW a.out WARNING: cannot find section: 'W' PR29719 src/ChangeLog: * readelf.c (print_symtab): Change signature and return true if something is printed. (process_elf_file): Use it and print warning. tests/ChangeLog: * run-readelf-s.sh: Test -sW.
* readelf: Check gelf_getdyn doesn't return NULLMark Wielaard2022-11-031-1/+1
| | | | Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf: Check phdr != NULL or shdr != NULL in handle_dynamic.Mark Wielaard2022-11-031-5/+5
| | | | | | | | | The compiler doesn't know that when use_dynamic_segment is true, then phdr should/will be non-NULL and otherwise shdr is non-NULL. Add explicit checks to help the compiler out and in case an error is made calling the handle_dynamic function. Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf: add binutils-style --syms optionArsen Arsenović2022-10-301-0/+1
| | | | | | This helps people with a lot of built up muscle memory :) Signed-off-by: Arsen Arsenović <arsen@aarsen.me>
* readelf: Handle DW_LLE_GNU_view_pairMark Wielaard2022-10-271-0/+12
| | | | | | | | DW_LLE_GNU_view_pair is used by gcc -gvariable-location-views=incompat5. As described in http://www.fsfla.org/~lxoliva/papers/sfn/dwarf6-sfn-lvu.txt and proposed for DWARF6 https://dwarfstd.org/ShowIssue.php?issue=170427.1 Signed-off-by: Mark Wielaard <mark@klomp.org>
* Move the #include <libintl.h> into eu-config.hYonggang Luo2022-10-161-1/+0
| | | | | | | | | | So we do not need include in each file. And indeed the macro #define _(Str) dgettext ("elfutils", Str) access libintl function dgettext, so it's make more sense #include <libintl.h> in file eu-config.h Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
* readelf: Handle SHT_RISCV_ATTRIBUTES like SHT_GNU_ATTRIBUTESAndreas Schwab2022-08-131-1/+3
| | | | Signed-off-by: Andreas Schwab <schwab@suse.de>
* readelf: memrchr searches backwards but takes the start buf as argumentMark Wielaard2022-08-011-4/+4
| | | | | | The bug (caught by valgrind) was giving memrchr to end of the buffer. Also as cleanup, Use d_val not d_ptr for calculating offset.
* readelf: Support --dynamic with --use-dynamicDi Chen2022-08-011-26/+186
| | | | | | | | | | | | Currently, eu-readelf is using section headers to dump the dynamic segment information (print_dynamic -> handle_dynamic). This patch adds new options to eu-readelf (-D, --use-dynamic) for (-d, --dynamic). https://sourceware.org/bugzilla/show_bug.cgi?id=28873 Signed-off-by: Di Chen <dichen@redhat.com>
* readelf: Define dyn_mem outside the while loop.Mark Wielaard2022-04-191-1/+1
| | | | | | | The GCC address sanitizer might complain otherwise: stack-use-after-scope src/readelf.c:1787 in get_dyn_ents Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf: Don't consider padding DT_NULL as dynamic section entryDi Chen2022-04-191-6/+25
| | | | | | | | | | | when using `$ eu-readelf -d {FILE}` to get the number of dynamic section entris, it wrongly counts the padding DT_NULLs as dynamic section entries. However, DT_NULL Marks end of dynamic section. They should not be considered as dynamic section entries. https://sourceware.org/bugzilla/show_bug.cgi?id=28928 Signed-off-by: Di Chen <dichen@redhat.com>
* Introduce error_exit as a noreturn variant of error (EXIT_FAILURE, ...)Mark Wielaard2022-03-301-99/+71
| | | | | | | | | | | | error (EXIT_FAILURE, ...) should be noreturn but on some systems it isn't. This may cause warnings about code that should not be reachable. So have an explicit error_exit wrapper that is noreturn (because it calls exit explicitly). Use error_exit in all tools under the src directory. https://bugzilla.redhat.com/show_bug.cgi?id=2068692 Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf: Workaround stringop-truncation errorMark Wielaard2021-12-091-1/+1
| | | | | | | | | | | | | | | | In function ‘strncpy’, inlined from ‘print_ehdr’ at readelf.c:1175:4: error: ‘__builtin_strncpy’ specified bound 512 equals destination size [-Werror=stringop-truncation] strncpy doesn't terminate the copied string if there is not enough room. We compensate later by explicitly adding a zero terminator at buf[sizeof (buf) - 1]. Normally gcc does see this, but with -fsanitize=address there is too much (checking) code in between. But it is actually better to not let strncpy do too much work, so substract one from the size. Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw, readelf: Read inlining info in NVIDIA extended line mapJohn M Mellor-Crummey2021-11-101-0/+62
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As of CUDA 11.2, NVIDIA added extensions to the line map section of CUDA binaries to represent inlined functions. These extensions include - two new fields in a line table row to represent inline information: context, and functionname, - two new DWARF extended opcodes: DW_LNE_NVIDIA_inlined_call, DW_LNE_NVIDIA_set_function_name, - an additional word in the line table header that indicates the offset in the .debug_str function where the function names for this line table begin, and A line table row for an inlined function contains a non-zero "context" value. The “context” field indicates the index of the line table row that serves as the call site for an inlined context. The "functionname" field in a line table row is only meaningful if the "context" field of the row is non-zero. A meaningful "functionname" field contains an index into the .debug_str section relative to the base offset established in the line table header; the position in the .debug_str section indicates the name of the inlined function. These extensions resemble the proposed DWARF extensions (http://dwarfstd.org/ShowIssue.php?issue=140906.1) by Cary Coutant, but are not identical. This commit integrates support for handling NVIDIA's extended line maps into elfutil's libdw library, by adding two functions dwarf_linecontext and dwarf_linefunctionname, and the readelf --debug-dump=line command line utility. Signed-off-by: John M Mellor-Crummey <johnmc@rice.edu> Signed-off-by: Mark Wielaard <mark@klomp.org>
* Use xasprintf instead of asprintf followed by error(EXIT_FAILURE)Dmitry V. Levin2021-09-091-8/+6
| | | | Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
* Remove redundant casts of memory allocating functions returning void *Dmitry V. Levin2021-09-091-8/+6
| | | | | | | Return values of functions returning "void *", e.g. calloc, malloc, realloc, xcalloc, xmalloc, and xrealloc, do not need explicit casts. Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
* readelf: Pull advance_pc() in file scopeTimm Bäder2021-07-151-7/+19
| | | | | | | | | Make advance_pc() a static function so we can get rid of another nested function. Rename it to run_advance_pc() and use a local advance_pc() macro to pass all the local variables. This is similar to what the equivalent code in libdw/dwarf_getsrclines.c is doing. Signed-off-by: Timm Bäder <tbaeder@redhat.com>
* readelf: Handle line tables without line number statements correctlyMark Wielaard2021-07-041-1/+1
| | | | | | | | | When we see a line table without line number statements we need to continue with the next table. Add a testcase for this situation. https://sourceware.org/bugzilla/show_bug.cgi?id=28032 Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf: Fix error message when two attribute names differ in in ↵Mark Wielaard2021-07-031-1/+1
| | | | | | | | | compare_listptr. We were printing the second attribute name twice. Print the first and second. Reported-by: Gabriel Valky <gvalky@tachyum.com> Signed-off-by: Mark Wielaard <mark@klomp.org>
* Come up with startswith function.Martin Liska2021-05-121-6/+5
| | | | | | | New function in system.h that returns true if a string has a given prefix, false otherwise. Use it in place of strncmp. Signed-off-by: Martin Liška <mliska@suse.cz>
* readelf: Sanity check verneed and verdef offsets in handle_symtab.Mark Wielaard2021-03-031-1/+9
| | | | | | | | | | We are going through vna_next, vn_next and vd_next in a while loop. Make sure that all offsets are sane. We don't want things to wrap around so we go in cycles. https://sourceware.org/bugzilla/show_bug.cgi?id=27501 Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf: Type DIE offset is from start of CU.Mark Wielaard2021-02-171-1/+2
| | | | | | | | | While inspecting some type units I noticed the type offset seemed off. We were printing the offset as is, but it should include the offset of the unit. There was actually a testcase for this, run-readelf-types.sh but that had the same bug in the expected output. Fixed both. Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf, libdw: blocks aren't expressions for DWARF version 4Mark Wielaard2021-02-171-1/+3
| | | | | | | | For DWARF version 4 or higher a block form really encodes a block, not an expression location. Also constant offsets can be expressed as DW_FORM_implicit_const in DWARF version 5. Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf: Remove show_op_index variableTimm Bäder2021-02-051-6/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | advance_pc() uses show_op_index to save whether the current op_index is > 0 OR the new op_index is > 0. The new op index is calculated via new_op_index = (op_index + op_advance) % max_ops_per_instr; since all of the variables involved are unsigned, new_op_index >= op_index is always true. So... if op_index > 0, then new_op_index > 0 if op_index == 0, then new_op_index >= 0 and if the new_op_index is > 0, then the old one was as well. In any case, we only need to check the new_op_index, since show_op_index used to OR the two comparisons. In other words: op_index > 0 | new_op_index > 0 || show_op_index ------------------------------------------------ true true true false true true true false true xx false false false ... but since the third line (marked with xx) is not possible, the table becomes: op_index > 0 | new_op_index > 0 || show_op_index ------------------------------------------------ true true true false true true false false false ... and show_op_index is equal to (new_op_index > 0). So, remove the show_op_index variable and simply replace it by comparing the new op_index > 0.
* readelf: Pull regname() into file scopeTimm Bäder2021-01-301-18/+24
| | | | | | Get rid of a nested function this way. Signed-off-by: Timm Bäder <tbaeder@redhat.com>
* readelf: Pull left() info file scopeTimm Bäder2021-01-301-7/+9
| | | | | | Get rid of a nested function this way. Signed-off-by: Timm Bäder <tbaeder@redhat.com>
* readelf: Pull same_set() info file scopeTimm Bäder2021-01-301-10/+15
| | | | | | Get rid of a nested function this way Signed-off-by: Timm Bäder <tbaeder@redhat.com>
* readelf: Pull add_dump_section() into file scopeTimm Bäder2021-01-301-16/+18
| | | | | | Get rid of a nested function this way. Signed-off-by: Timm Bäder <tbaeder@redhat.com>
* src/readelf: use qsort instead of qsort_r.Érico Rolim2021-01-101-4/+10
| | | | | | | | | This program is single threaded, so using qsort with a global variable isn't a danger. The interface for qsort_r isn't standardized (and diverges between glibc and FreeBSD, for example), which makes usage of qsort, where possible, preferrable. Signed-off-by: Érico Rolim <erico.erc@gmail.com>
* Handle SHF_GNU_RETAIN in eu-readelf and eu-elflint.Mark Wielaard2020-12-161-0/+2
| | | | | | | readelf -S now shows 'R' when SHF_GNU_RETAIN is set. elflint accepts SHF_GNU_RETAIN when set on section in --gnu mode. Signed-off-by: Mark Wielaard <mark@klomp.org>
* src: consistently use _(Str) instead of gettext(Str)Dmitry V. Levin2020-12-161-438/+438
| | | | | | | | | Make use of the _(Str) macro provided by <config.h>. The change was made automatically using the following command: $ git grep -l '\<gettext *(' src |xargs sed -i 's/\<gettext *(/_(/g' Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
* src: fix spelling typos in comments and ChangeLogDmitry V. Levin2020-12-121-3/+3
| | | | | | | | | | | | | | | | | | Indeces -> Indices adress -> address affort -> afford dont' -> don't futher -> further higest -> highest indeces -> indices interate -> iterate occured -> occurred overlow -> overflow sectin -> section succesful -> successful teminated -> terminated Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
* src: fix spelling typos in argp help text and error diagnosticsDmitry V. Levin2020-12-121-1/+1
| | | | | | | | | | | | Since all these help text strings are marked for translation, apply the fixes to translation strings as well, this helps to avoid translations becoming fuzzy. lenght -> length occured -> occurred endianess -> endianness reversable -> reversible Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
* readelf: Support showing view pairs in loclists as GNU extension.Mark Wielaard2020-10-021-8/+70
| | | | | | | | | View pairs are encoded in .debug_loclists as they are encoded in .debug_locs sections by the GCC compiler. Scan for DW_AT_GNU_locviews attributes that point to the view pairs just in front of the actual location lists. Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw,readelf: Recognize DW_CFA_AARCH64_negate_ra_stateMark Wielaard2020-09-071-5/+8
| | | | | | | | | | | | | | | | | | | | DW_CFA_AARCH64_negate_ra_state is used on aarch64 to indicate whether or not the return address is mangled or not. This has the same value as the DW_CFA_GNU_window_save. So we have to pass around the e_machine value of the process or core we are inspecting to know which one to use. Note that it isn't actually implemented yet. It needs ARMv8.3 hardware. If we don't have such hardware it is enough to simply ignore the DW_CFA_AARCH64_negate_ra_state (and not confuse it with DW_CFA_GNU_window_save) to get backtraces to work on aarch64. Add a testcase for eu-readelf --debug-dump=frames to show the value is correctly recognized. Also don't warn we cannot find any DWARF if we are just dumping frames (those will come from .eh_frame if there is no .debug_frame). Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf: base address entry can be firstMark Wielaard2020-09-071-2/+14
| | | | | | | | | In both debug_ranges and debug_loc a base address entry can be the first in the range or loc list. If so print the offset and set first to false. Otherwise don't print the entry list offset, but do set first to false. Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf: It is not an error if there are no line number statementsMark Wielaard2020-08-261-1/+7
| | | | | | | | | | It can happen that there are no line number statements at the end of a debug line section. So don't check that there are any more bytes after the last file entry. And print "No line number statements." libdw already got this corner case correct. Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw, readelf: Handle GCC LTO .gnu.debuglto_ prefix.Mark Wielaard2020-04-221-2/+7
| | | | | | | | | GCC puts (partial) DWARF debuginfo into sections prefixed with .gnu.debuglto_. Handle those sections as if they are normal .debug sections (which they are). This allows showing the DWARF that gcc puts into ET_REL files compiled with -flto. Signed-off-by: Mark Wielaard <mark@klomp.org>
* elflint, readelf: enhance error diagnosticsDmitry V. Levin2019-10-041-1/+1
| | | | | | | When an input file cannot be opened, include its name into the error diagnostics. Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
* readelf: Add --dyn-sym option.Mark Wielaard2019-09-101-1/+13
| | | | | | | | | | | It is already possible to select the symbol table to print by name, using --symbols=SECTION. This allows printing the dynamic symbol table with --symbols=.dynsym. binutils readelf allows printing just the dynamic symbol table by type using --dyn-sym. Add the same option and document it. Also add a testcase to show --symbols=.dynsym and --dyn-sym produce the same output. Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf: Actually dump hex or strings when -p or -x get section number.Mark Wielaard2019-08-291-0/+1
| | | | | | | | The readelf code did parse section numbers, but then failed to actually dump the section found. Fixed by actually calling the dump function (either the hex or string variant). Add testcase for readelf -x num. Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf: Add optional "SECTION" argument for --notes.Mark Wielaard2019-08-261-1/+12
| | | | | | | | | There are multiple sections that can contain ELF Notes. It is sometimes nice to just list the notes from a specific section. -n, --notes[=SECTION] Display the ELF notes Signed-off-by: Mark Wielaard <mark@klomp.org>