summaryrefslogtreecommitdiffstats
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* readelf.c: Avoid repeating calls to gettext _() in hotpathupstream/users/amerey/try-readelf-concurrencyAaron Merey2025-07-031-53/+169
| | | | | | | | | | | | | | | | | | | | | Calls to the gettext _() macro in hotpaths cause many runtime lookups of the same translation strings. This patch introduces macro __() which caches the result of _() at each call site where __() is used. When a cached translation string is used as the format string for fprintf, the compiler might raise a -Wformat-nonliteral warning. To avoid this, the -Wformat-nonliteral warning is suppressed using _Pragma around affected fprintf calls, using IGNORE_FMT_NONLITERAL_BEGIN and _END wrappers. To avoid suppressing -Wformat-nonliteral across every printf-style function using _(), __() and IGNORE_FMT_NONLITERAL_* are mostly used within hotpath loops where caching makes a signficant difference. Runtime improvements of up to 13% faster have been observed with this patch applied. Signed-off-by: Aaron Merey <[email protected]>
* src/readelf.c: Support concurrency for -w, --debug-dumpAaron Merey2025-07-031-4/+160
| | | | | | | | | | | | | | | | | | | | | | | Implement concurrent execution of print_debug_* functions during handling of -w, --debug-dump using libthread.a. A new `-C, --concurrency=NUM` command line option controls the maximum number of threads that may be used. This value defaults to the number of CPUs. Job output is buffered and printed in the order that jobs were added to the queue. This helps preserve the existing order of stdout output. * src/readelf.c (default_concurrency): Function estimating the maximum number of threads. (parse_opt): Handle -C, --concurrency=NUM. (do_job): Entry point function for threads. (schedule_job): If thread safety is enabled, add job to the job queue. Otherwise just run the job from the main thread. (print_debug): Pass print_debug_* function pointers and args to schedule_job. Also call run_jobs if thread safety is enabled. Signed-off-by: Aaron Merey <[email protected]>
* src/readelf.c: Add support for print_debug_* output bufferingAaron Merey2025-07-031-1102/+1150
| | | | | | | | | | | | | | | | Safely handle stdout output during concurrent calls to print_debug_* functions. For any print_debug_* function and any function that could be called from print_debug_* which also prints to stdout: add a FILE * argument and replace all printf, puts, putchar with fprintf. All printing to stdout will now be written to this FILE instead. The FILE * is an interface to a per-thread dynamically-sized buffer. libthread.a manages the allocation, printing and deallocation of these buffers. Signed-off-by: Aaron Merey <[email protected]>
* src: Add threadlib library for parallel job executionAaron Merey2025-07-033-0/+327
| | | | | | | | | | | | | | | | | | | | | | | | | | Add new internal static library libthread.a that provides infrastructure for eu-* tools to run functions concurrently using pthreads. threadlib.c manages per-job threads as well as per-job buffers for stdout output. Output for each job is printed to stdout in the order that the jobs were added to the job queue. This helps preserve the order of output when parallelization is added to an eu-* tool. threadlib.h declares functions add_job and run_jobs. Jobs are added to a threadlib.c internal job queue using add_job. run_jobs concurrently executes jobs in parallel. eu-readelf now links against libthread.a when elfutils is configured with --enable-thread-safety. * src/Makefile.am: libthread.a is compiled and and linked with readelf when USE_LOCKS is defined. * src/threadlib.c: New file. Manages job creation, concurrent execution and output handling. * src/threadlib.h: New file. Declares functions add_job and run_jobs. Signed-off-by: Aaron Merey <[email protected]>
* unstrip: update unstripped_shnum when adding a new sectionMark Wielaard2025-06-031-0/+1
| | | | | | | | | If some section doesn't match between the stripped and unstripped file we invent a new one. Make sure to also update the shnum value. * src/unstrip.c (copy_elided_sections): Update unstripped_shnum. Signed-off-by: Mark Wielaard <[email protected]>
* unstrip: exit early if there are no sections in the stripped fileMark Wielaard2025-06-021-1/+1
| | | | | | | | | | If there is only section zero that shouldn't count. Then we would still try to work on an empty set of sections and give an obscure error later. * src/unstrip.c (copy_elided_sections): Check stripped_shnum <= 1. Signed-off-by: Mark Wielaard <[email protected]>
* src/readelf.c: Access symbol and version data only if availableAaron Merey2025-05-211-33/+63
| | | | | | | | | | | | | handle_dynamic_symtab can attempt to read symbol and version data from file offset of 0 or address of 0 if the associated DT_ tags aren't found. Fix this by only reading symbol and version data when non-zero file offsets/addresses have been found. https://sourceware.org/bugzilla/show_bug.cgi?id=32864 Suggested-by: Constantine Bytensky <[email protected]> Signed-off-by: Aaron Merey <[email protected]>
* unstrip: Check symtab and strtab sections have data before use.Mark Wielaard2025-04-301-0/+6
| | | | | | | | * src/unstrip.c (copy_elided_sections): Check elf_getdata result for symtab and strtab sections. Suggested-by: Anton Moryakov <[email protected]> Signed-off-by: Mark Wielaard <[email protected]>
* readelf: Pass around GElf_Ehdr instead of calling gelf_getehdrMark Wielaard2025-04-291-10/+10
| | | | | | | | | | | | | | | | handle_core_item calls gelf_getehdr for each item without checking if the call succeeds. It should always succeed because process_elf_file already checked gelf_getehdr returned a valid Ehdr before passing it to handle_notes. Just pass the Ehdr down a couple more function calls. * readelf.c (handle_core_item): Take const Gelf_Ehdr and use it. (handle_core_items): Take const Gelf_Ehdr and pass it to handle_core_item. (handle_core_note): Take const Gelf_Ehdr and pass it to handle_core_items. (handle_notes_data): Pass ehdr to handle_core_note. Signed-off-by: Mark Wielaard <[email protected]>
* ar: Check elf_getahdr doesn't return NULLMark Wielaard2025-04-291-0/+6
| | | | | | | | | | | | When elf_getahdr returns NULL we shouldn't even try to handle the ar header, but immediately go to the next entry. * src/ar.c (do_oper_extract): If elf_getahdr goto next. (do_oper_delete): Likewise. (do_oper_insert): Likewise. Suggested-by: Anton Moryakov <[email protected]> Signed-off-by: Mark Wielaard <[email protected]>
* src/.gitignore: Add stacktraceAaron Merey2025-04-251-0/+1
| | | | Signed-off-by: Aaron Merey <[email protected]>
* eu-stacktrace [12/12]: use dwflst_perf_sample_getframesSerhei Makarov2025-04-251-246/+30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Remove the code from src/stacktrace.c that is now covered by libdwfl_stacktrace/dwflst_perf_frame.c and dwflst_perf_sample_getframes. * src/stacktrace.c (show_memory_reads): Remove this verbose option as the relevant code is inside libdwfl_stacktrace now. (struct __sample_arg): Remove, handled by libdwfl_stacktrace/dwflst_perf_frame.c. (sample_next_thread): Ditto. (sample_getthread): Ditto. (copy_word_64): Ditto. (copy_word_32): Ditto. (elf_memory_read): Ditto. (sample_memory_read): Ditto. (sample_set_initial_registers): Ditto. (sample_detach): Ditto. (sample_thread_callbacks): Ditto. (sysprof_find_dwfl): Now also return the Elf* so that it can be passed to dwflst_perf_sample_getframes. Don't create sample_arg. Do record sp in sui->last_sp. Don't dwfl_attach_state, dwflst_perf_sample_getframes handles that now. (sysprof_unwind_cb): Adapt to sysprof_find_dwfl changes, now invoke dwflst_perf_sample_getframes instead of dwfl_getthread_frames. (parse_opt): Remove show_memory_reads. (main): Remove show_memory_reads. Signed-off-by: Serhei Makarov <[email protected]>
* eu-stacktrace [10/12]: use dwflst_tracker_find_pidSerhei Makarov2025-04-251-27/+36
| | | | | | | | | | | | | | | | | | | Initial minimal change to ensure dwflst_tracker_find_pid is tested. For now, we keep the additional dwfltab implementation in stacktrace.c, since it's being used to track statistics. In future follow-ups, it will be good to switch to storing eu-stacktrace statistics e.g. in dwfl->process->callbacks_arg. This requires some additional design to keep the statistics from being lost when a pid is reused and the corresponding processtracker table entry is replaced. * src/stacktrace.c (sysprof_init_dwfl): New function. (sysprof_find_dwfl): Rename the existing sysprof_init_dwfl. Also use dwflst_tracker_find_pid with callback. (sysprof_unwind_cb): Rename the existing sysprof_init_dwfl. Signed-off-by: Serhei Makarov <[email protected]>
* eu-stacktrace [7/12]: use Dwflst_Process_Tracker for Elf * cachingSerhei Makarov2025-04-252-4/+11
| | | | | | | | | | | | * src/Makefile.am (AM_CPPFLAGS): Include headers from ../libdwfl_stacktrace. * src/stacktrace.c (tracker): New global variable. (sample_callbacks): Use dwflst_tracker_linux_proc_find_elf for caching. (sysprof_init_dwfl): Use dwflst_tracker_dwfl_begin. (main): Initialize and clean up tracker. Signed-off-by: Serhei Makarov <[email protected]>
* libebl [3/12]: eu-stacktrace: use new register handling apiSerhei Makarov2025-04-252-7/+31
| | | | | | | | | | | | | | | | | Dummy commit to show how the sample_set_initial_registers callback in eu-stacktrace would use the proper libebl ebl_set_initial_registers_sample function (if it were public). * src/Makefile.am (stacktrace_LDADD): Add libebl. * src/stacktrace.c (sample_registers_cb): New function, though identical to pid_thread_state_registers_cb. (sample_set_initial_registers): (XXX Invoke ebl_set_initial_registers_sample instead of containing platform-specific code directly. This is now commented out. Patch12 in the series replaces with code in libdwfl_stacktrace/dwflst_perf_frame.c.) Signed-off-by: Serhei Makarov <[email protected]>
* readelf: Add 'Key to Flags' to eu-readelf --section-headers outputSamuel Zeter2025-04-041-0/+11
| | | | | | | | | | | | | | | | | | When printing section headers, also include a key to what each flag is at the end of the section header output. * src/readelf.c (print_flag_info): New function. (print_shdr): Call print_flag_info. * tests/run-copyadd-sections.sh: Fix .extra grep by escaping \. * tests/run-large-elf-file.sh: Likewise. * tests/test-copymany-subr.sh: Likewise. * tests/run-readelf-z.sh: Add Key to Flags to expected output. * tests/run-retain.sh: Likewise. * tests/run-strip-remove-keep.sh: Likewise. https://sourceware.org/bugzilla/show_bug.cgi?id=29571 Signed-off-by: Samuel Zeter <[email protected]>
* readelf: Add support for printing DW_AT_language_name DW_LNAMEsMark Wielaard2025-03-111-0/+26
| | | | | | | | | | | | | | | | | | Add a testfile using GCC 15 (experimental). * libdw/dwarf.h: Add DW_LNAME_lo_user and DW_LNAME_hi_user. * src/readelf.c (dwarf_lname_string): New function. (dwarf_lname_name): Likewise. (attr_callback): Handle DW_AT_language_name by calling dwarf_lname_name. * run-readelf-lnames.sh: New test. * testfile-lnames.bz2: New testfile. * tests/Makefile.am (TESTS): Add run-readelf-lnames.sh. (EXTRA_DIST): Add run-readelf-lnames.sh and testfile-lnames.bz2. Signed-off-by: Mark Wielaard <[email protected]>
* libelf: Rewrite elf_scnshndx, extended index table handlingMark Wielaard2025-03-011-9/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | elf_scnshndx is a elfutils extension to libelf that given a SHT_SYMTAB section returns the index to the corresponding SHT_SYMTAB_SHNDX section, if it exists. This is needed when there are more than 64K sections and there are symbols that have to refer to a section with an index larger than 64K, because the Elf Sym st_shndx field is only 16 bits. This was implemented by adding an shndx_index field to the Elf_Scn struct which is updated when reading the section headers. This takes up space in every section and is hard to proof correct. In the case of using ELF_C_READ_MMAP the shndx_index field was only updated when the shdrs needed to be converted from file to memory order. And the two places were this function was used in readelf.c and elf-print-reloc-syms.c the wrong section was used to lookup the extended index table. There were also no tests for this functionality. Replace the elf_scnshndx implementation with a simpler lookup over all sections. This sounds inefficient, but in practice the SHT_SYMTAB_SHNDX section is the next section after the SHT_SYMTAB section. elf_scnshndx only needs to be called when there are more than SHN_LORESERVE (0xff00) sections. And normally a user would just lookup the SHT_SYMTAB and SHT_SYMTAB_SHNDX sections at the same time (which is what readelf does when showing the symbol table, as does nm, objcopy and libdwfl). Add a testfile manyfuncs.c that when compiled contains 64K symbols and sections. Make sure to use -fasynchronous-unwind-tables so there is at least one relocatable section that uses all function symbols (e.g. on arm32 where there is no .eh_frame by default). This can then be used to verify the readelf --relocs support. Add another test, test-manyfuncs that explicitly goes through the symbol table and associated extended index table and verify each function symbol matches the section name. There are For riscv there are local, notype, symbols at the start of each executable section which relocations refer to instead of the section symbol. Since all these local symbols are called ".L0" this isn't very useful, so print the section name instead. For powerpc ELFv1 all function symbols go through the .opd section. Allow this in the new test-manyfuncs test. * libelf/elf32_getshdr.c (load_shdr_wrlock): Remove handling of shndx_index. * libelf/elf_begin.c (file_read_elf): Likewise. * libelf/elf_scnshndx.c (elf_scnshndx): Rewritten. * libelf/libelf.h (elf_scnshndx): Added full documentation. * libelf/libelfP.h (struct Elf_Scn): Remove shndx_index field. (__elf_scnshndx_internal): Removed. * src/readelf.c (handle_relocs_rel): Use symscn in call to elf_scnshndx. Print section name for local start section label. (handle_relocs_rela): Likewise. * tests/Makefile.am (check_PROGRAMS): Add test-manyfuncs. (manyfuncs.o): New target. (check-local): New target, depends on manyfuncs.o. (TESTS): Add run-readelf-r-manyfuncs.sh and run-test-manyfuncs.sh. (EXTRA_DIST): Add run-readelf-r-manyfuncs.sh, run-test-manyfuncs.sh and manyfuncs.c. (test_manyfuncs_LDADD): New variable. (EXTRA_test_manyfuncs_DEPENDENCIES): New variable. (CLEANFILES): Add manyfuncs.o. * tests/elf-print-reloc-syms.c (print_reloc_symnames): Use symscn in call to elf_scnshndx. * tests/manyfuncs.c: New test file to generate 64K symbols and sections. * tests/run-readelf-r-manyfuncs.sh: New test wrapper. * tests/run-test-manyfuncs.sh: Likewise. * tests/test-manyfuncs.c: New test. Signed-off-by: Mark Wielaard <[email protected]>
* readelf: Use section_name instead of elf_strptr in print_debug_frame_sectionMark Wielaard2025-02-271-1/+1
| | | | | | | | | | | | All other print_debug_* functions use section_name (ebl, shdr) to get the current section name. Be consistent and use the same method in print_debug_frame_section to make static analyzers happy who might think elf_strptr can return NULL in this case. * src/readelf.c (print_debug_frame_section): Use section_name instead of elf_strptr to get the section name. Signed-off-by: Mark Wielaard <[email protected]>
* readelf: check elf_getarhdr returns NULL in dump_archive_indexAnton Moryakov2025-02-271-2/+2
| | | | | | | | | | | | | Report of the static analyzer: DEREF_OF_NULL.RET Pointer, returned from function 'elf_getarhdr' at readelf.c:13551, may be NULL and is dereferenced at readelf.c:13553. * src/readelf.c (dump_archive_index): Check elf_getarhdr doesn't return NULL. Triggers found by static analyzer Svace. Signed-off-by: Anton Moryakov <[email protected]>
* strip: Verify symbol table is a real symbol tableMark Wielaard2025-02-141-3/+11
| | | | | | | | | | | | | | | | | We didn't check the symbol table referenced from the relocation table was a real symbol table. This could cause a crash if that section happened to be an SHT_NOBITS section without any data. Fix this by adding an explicit check. * src/strip.c (INTERNAL_ERROR_MSG): New macro that takes a message string to display. (INTERNAL_ERROR): Use INTERNAL_ERROR_MSG with elf_errmsg (-1). (remove_debug_relocations): Check the sh_link referenced section is real and isn't a SHT_NOBITS section. https://sourceware.org/bugzilla/show_bug.cgi?id=32673 Signed-off-by: Mark Wielaard <[email protected]>
* readelf: Skip trying to uncompress sections without a nameMark Wielaard2025-02-141-2/+2
| | | | | | | | | | | | | | | When combining eu-readelf -z with -x or -p to dump the data or strings in an (corrupted ELF) unnamed numbered section eu-readelf could crash trying to check whether the section name starts with .zdebug. Fix this by skipping sections without a name. * src/readelf.c (dump_data_section): Don't try to gnu decompress a section without a name. (print_string_section): Likewise. https://sourceware.org/bugzilla/show_bug.cgi?id=32656 Signed-off-by: Mark Wielaard <[email protected]>
* readelf: Handle NULL phdr in handle_dynamic_symtabMark Wielaard2025-02-141-1/+1
| | | | | | | | | | | | | | A corrupt ELF file can have broken program headers, in which case gelf_getphdr returns NULL. This could crash handle_dynamic_symtab while searching for the PT_DYNAMIC phdr. Fix this by checking whether gelf_phdr returns NULL. * src/readelf.c (handle_dynamic_symtab): Check whether gelf_getphdr returns NULL. https://sourceware.org/bugzilla/show_bug.cgi?id=32655 Signed-off-by: Mark Wielaard <[email protected]>
* libelf, readelf: Use validate_str also to check dynamic symstr dataMark Wielaard2025-02-141-3/+15
| | | | | | | | | | | | | | | | | | When dynsym/str was read through eu-readelf --dynamic by readelf process_symtab the string data was not validated, possibly printing unallocated memory past the end of the symstr data. Fix this by turning the elf_strptr validate_str function into a generic lib/system.h helper function and use it in readelf to validate the strings before use. * libelf/elf_strptr.c (validate_str): Remove to... * lib/system.h (validate_str): ... here. Make inline, simplify check and document. * src/readelf.c (process_symtab): Use validate_str on symstr_data. https://sourceware.org/bugzilla/show_bug.cgi?id=32654 Signed-off-by: Mark Wielaard <[email protected]>
* elflint: process_file both prefix and suffix are NULL or both are non-NULLMark Wielaard2025-02-111-0/+4
| | | | | | | | | Add an assert of this property to help static analyzers (or humans) reading this code. * src/elflint.c (process_file): Add assert. Signed-off-by: Mark Wielaard <[email protected]>
* objdump: Handle elf_getarhdr returning NULL in handle_arAnton Moryakov2025-02-071-1/+2
| | | | | | | | | | | | | | | | | Report of the static analyzer: Pointer, returned from function 'elf_getarhdr' at objdump.c:314, may be NULL and is dereferenced at objdump.c:317. (CWE-476, CWE-690) Corrections explained: When processing archive elements, the code could dereference a NULL pointer if 'elf_getarhdr' returns NULL. This patch adds a check to ensure 'arhdr' is not NULL before using it. The fix ensures that the function safely handles cases where 'elf_getarhdr' fails, avoiding potential crashes. Triggers found by static analyzer Svace. Signed-off-by: Anton Moryakov <[email protected]>
* stacktrace: Add missing locale.hAlfred Wingate2025-01-301-0/+1
| | | | | | | | | | | | The missing header is only obvious on musl and on glibc when you don't have optimizations enabled. Normally the header would transitively come from config.h -> ./lib/eu-config.h -> glibc libintl.h. with __OPTIMIZE__. https://sourceware.org/git/?p=glibc.git;a=blob;f=intl/libintl.h;hb=HEAD#l103 Signed-off-by: Alfred Wingate <[email protected]>
* src/readelf.c: Close skel_fdAaron Merey2025-01-241-1/+7
| | | | | | | | | skel_fd is passed to create_dwfl, which calls dup() on skel_fd. create_dwfl handles closing the duped fd but not the original. Ensure the original skel_fd is closed after it's passed to create_dwfl. Signed-off-by: Aaron Merey <[email protected]>
* Replace usage of ar with stored library manifest filesMichael Pratt2025-01-211-1/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The ar program is called to assemble a list of objects within each archive to assist in building combined libraries, however make already has this information when processing the subdirectory for that respective library. The list can be saved in a "manifest" file instead of being generated whenever it is needed for use with other subdirectories. Even though the difference in time is insignificant, a simple "echo" and "cat" is as much as 10 times faster than a call to "ar t" for printing the archive members. Since elfutils builds ar, this also removes the awkward circular dependency where an installation of ar is required to build the libraries for ar. Additionally, not every version of ar is equally portable, as native versions of ar on macOS and other BSD-like distributions may print out a special archive member like "__.SYMDEF" which is not a compiled object but rather just metadata from ranlib, leading to a build failure. Avoid these limitations by removing usage of ar and adding build and clean rules for the usage of archive manifest files. * .gitignore: exclude ".manifest" file extension. * backends/Makefile.am: add manifest file build and clean rules. * debuginfod/Makefile.am: Likewise. * lib/Makefile.am: Likewise. * libasm/Makefile.am: Likewise. * libcpu/Makefile.am: Likewise. * libdw/Makefile.am: Likewise, and set object lists to manifest contents. * libdwelf/Makefile.am: Likewise. * libdwfl/Makefile.am: Likewise. * libebl/Makefile.am: Likewise. * libelf/Makefile.am: Likewise, and set object lists to manifest contents. * src/Makefile.am: Likewise. Signed-off-by: Michael Pratt <[email protected]>
* srcfiles.cxx: Prevent fd and entry leakAaron Merey2024-11-251-12/+17
| | | | | | | Make sure to free fd and the archive entry if an error is encountered while adding source files to the archive. Signed-off-by: Aaron Merey <[email protected]>
* Consolidate and add files to clean target variablesupstream/users/amerey/try-cleanMichael Pratt2024-11-081-5/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | To increase the consistency of how automatic clean targets run, define the variables together without +=, default to MOSTLYCLEANFILES when there is no need for different levels or add more clean levels to match other subdirectories, add more files that are built, remove duplication, and cleanup. Do the same for EXTRA_DIST where it is equally messy. * backends/Makefile.am: add more objects to clean, improve spacing. * debuginfod/Makefile.am: Likewise, and remove duplicates. * lib/Makefile.am: improve spacing. * libasm/Makefile.am: add more objects to clean, split similar to debuginfod. * libcpu/Makefile.am: use normal =, add more objects to clean. * libdw/Makefile.am: add more objects to clean, split similar to debuginfod. * libdwelf/Makefile.am: add more objects to clean, use lowest clean level. * libdwfl/Makefile.am: Likewise. * libebl/Makefile.am: add more objects to clean. * libelf/Makefile.am: add more objects to clean, split similar to debuginfod. * src/Makefile.am: consolidate including EXTRA_DIST, split clean levels, define with normal =, define with variables. * tests/Makefile.am: Likewise, but not including EXTRA_DIST. Signed-off-by: Michael Pratt <[email protected]>
* strip: Ignore --reloc-debug-sections-only for non-ET_REL files.Aaron Merey2024-11-051-0/+7
| | | | | | | | | | | | | | | | | | | | strip --reloc-debug-sections-only is expected to be a no-op for non-ET_REL files. This was not enforced in the code. Sections were copied over to a new output file and normally its contents would be identical to the input file. However the output file is not identical to a non-ET_REL input file if the linker organized sections such that the indices of SHF_ALLOC sections are not in a contigous group. In this case strip will modify sections in order to keep all SHF_ALLOC sections in a contiguous group. Fix this by ignoring --reloc-debug-sections-only for non-ET_REL files. https://sourceware.org/bugzilla/show_bug.cgi?id=32253 Signed-off-by: Aaron Merey <[email protected]>
* stacktrace: Init elf_fd in sysprof_init_dwflMark Wielaard2024-10-241-1/+1
| | | | | | | | | | | | | | | | | | When building with LTO gcc believes elf_fd can be used uninitialized: In function ‘sysprof_init_dwfl’, inlined from ‘sysprof_unwind_cb’ at stacktrace.c:1235:16: stacktrace.c:1087:7: error: ‘elf_fd’ may be used uninitialized [-Werror=maybe-uninitialized] 1087 | close (elf_fd); | ^ This code won't be reached because if find_procfile doesn't initialize elf_fd, it will return an error. But help the compiler by initializing elf_fd to -1. * src/stacktrace.c (sysprof_init_dwfl): Init elf_fd to -1. Signed-off-by: Mark Wielaard <[email protected]>
* eu-stacktrace [4/5]: src: add unwind origin diagnostics to eu-stackSerhei Makarov2024-10-171-7/+23
| | | | | | | | | | | | | | | | | | | Since we obtain diagnostics about unwind method, another logical place to show them is in eu-stack. * src/stack.c (show_unwound_source): New global variable. (struct frame): Add unwound_source field. (frame_callback): Copy over unwound_source from Dwfl_Frame. (print_frame): Take unwound_source string and print it. (print_inline_frames): Take unwound_source argument and pass it on, except for subsequent frames where we pass the string "inline". (print_frames): Take unwound_source field from struct frame and pass it on. (parse_opt): Add --cfi-type,-c option to set show_unwound_source. (main): Ditto. * tests/run-stack-i-test.sh: Add testcase for --cfi-type. Signed-off-by: Serhei Makarov <[email protected]>
* eu-stacktrace [3/5]: libdwfl: add unwind origin diagnosticsSerhei Makarov2024-10-171-5/+28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Track the method used to unwind each Dwfl_Frame using an enum field unwound_source; provide access to the field. Then use that in eu-stacktrace to display the unwind methods used for each process. This is an important diagnostic to verify how many processes are adequately covered by the eh_frame unwinder. * libdw/libdw.map (ELFUTILS_0.192): Add dwfl_frame_unwound_source, dwfl_unwound_source_str. * libdwfl/libdwfl.h (Dwfl_Unwound_Source): New enum. (dwfl_frame_unwound_source) (dwfl_unwound_source_str): New functions. * libdwfl/dwfl_frame.c (dwfl_frame_unwound_source) (dwfl_unwound_source_str): New functions. * libdwfl/libdwflP.h: Add INTDECL for dwfl_frame_unwound_source, dwfl_unwound_source_str. (struct Dwfl_Frame): Add unwound_source field. * libdwfl/frame_unwind.c (__libdwfl_frame_unwind): Set state->unwound_source depending on the unwind method used. * src/stacktrace.c (struct sysprof_unwind_info): Add last_pid field to provide access to the current sample's dwfltab entry. (sysprof_unwind_frame_cb): Add unwound_source to the data displayed with the show_frames option. (sysprof_unwind_cb): Set last_pid when processing a sample. (main): Add unwind_source to the data displayed in the final summary table. Signed-off-by: Serhei Makarov <[email protected]>
* eu-stacktrace [2/5]: configure.ac: initial version (x86/sysprof only)Serhei Makarov2024-10-171-1/+8
| | | | | | | | | | | | | | | | | | | | | Due to the x86-specific code in the initial version the configury has significant restrictions. If --enable-stacktrace is not explicitly provided, then eu-stacktrace will be disabled by default. The way we test for x86 is a bit unusual. What we actually care about is that the register file provided by perf_events on the system is an x86 register file; this is done by checking that <asm/perf_regs.h> is Linux kernel arch/x86/include/uapi/asm/perf_regs.h. Once eu-stacktrace is properly portable across architectures, these grody checks can be simplified. Enablement of the feature by default depends on a released Sysprof version we can point to for the patches. * configure.ac: Add configure checks and conditionals for stacktrace tool. * src/Makefile.am: Add stacktrace tool conditional on ENABLE_STACKTRACE. Signed-off-by: Serhei Makarov <[email protected]>
* eu-stacktrace [1/5]: src: add eu-stacktrace toolSerhei Makarov2024-10-171-0/+1571
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | eu-stacktrace is a utility to process a stream of raw stack samples (such as those obtained from the Linux kernel's PERF_SAMPLE_STACK facility) into a stream of stack traces (such as those obtained from PERF_SAMPLE_CALLCHAIN), freeing other profiling utilities from having to implement their own backtracing logic. eu-stacktrace accepts data from a profiling tool via a pipe or fifo. The initial version of the tool works on x86 architectures and accepts data from Sysprof [1]. For future work, it will make sense to expand support to other profilers, in particular perf tool. Further patches in this series provide configury, docs, and improved diagnostics for tracking the method used to unwind each frame in the stack trace. [1]: The following patched version of Sysprof (upstream submission ETA ~very_soon) can produce data with stack samples: https://git.sr.ht/~serhei/sysprof-experiments/log/serhei/samples-via-fifo Invoking the patched sysprof with eu-stacktrace: $ sudo sysprof-cli --use-stacktrace $ sudo sysprof-cli --use-stacktrace --stacktrace-path=/path/to/eu-stacktrace Invoking the patched sysprof and eu-stacktrace manually through a fifo: $ mkfifo /tmp/test.fifo $ sudo eu-stacktrace --input /tmp/test.fifo --output test.syscap & $ sysprof-cli --sample-method=stack --use-fifo=/tmp/test.fifo test.syscap Note that sysprof polkit actions must be installed systemwide (e.g. installing the system sysprof package will provide these). Otherwise, "Action org.gnome.sysprof3.profile is not registered" error will result. * src/stacktrace.c: Add new tool. Signed-off-by: Serhei Makarov <[email protected]>
* Remove usage of "unlocked" variant of stdio print functionsMichael Pratt2024-10-175-81/+81
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | These "unlocked" Linux Standard Base variants of standard functions are not available on some systems that are still capable of building Linux and ELFs. The difference is negligible for simple printing to stdout. POSIX also states for the similar putc_unlocked(): These functions can safely be used in a multi-threaded program if and only if they are called while the invoking thread owns the (FILE *) object, as is the case after a successful call to the flockfile() or ftrylockfile() functions. ... These unlocked versions can be safely used only within explicitly locked program regions, using exported locking primitives. and these precautions were never done. Use the standard forms of these print functions. There is inconsistent use of fputc_unlocked() with putc_unlocked(), so consistently use the safer fputc() instead. Signed-off-by: Michael Pratt <[email protected]>
* elflint: Fix memory leak in check_gnu_hash functionMaks Mishin2024-09-201-0/+1
| | | | | | | | | Dynamic memory, referenced by 'collected', is allocated at elflint.c:2235 and lost at elflint.c:2296. Found by RASU JSC with SVACE. Signed-off-by: Maks Mishin <[email protected]>
* readelf: Allow .gdb_index const table to be emptyMark Wielaard2024-09-101-1/+1
| | | | | | | | | | | The .gdb_index const table can be empty, if no symbol table entry refers to a name or CU. Which technically means the symbol table is empty or has only zero members. * src/readelf.c (print_gdb_index_section): Check const_off is not past the end of the data section, it can be at the end. Signed-off-by: Mark Wielaard <[email protected]>
* srcfiles: Fix compile with --disable-libdebuginfodMark Wielaard2024-09-101-1/+1
| | | | | | | | | | | | | | | | | The eu-srcfiles --no-backup option is only valid when build with libdebuginfod support. Adjust the ENABLE_LIBDEBUGINFOD conditional to not use no_backup anywhere. Also only run the run-srcfiles-self.sh test when debuginfod is enabled. * src/srcfiles.cxx (zip_files): Move endif ENABLE_LIBDEBUGINFOD after no_backup check. * tests/Makefile.am (TESTS): Only add run-srcfiles-self.sh if DEBUGINFOD and !DUMMY_LIBDEBUGINFOD. * tests/run-srcfiles.self.sh: Use local DEBUGINFOD_CACHE_PATH. https://sourceware.org/bugzilla/show_bug.cgi?id=32155 Signed-off-by: Mark Wielaard <[email protected]>
* readelf: Fix printing of .gdb_index symbol table offset.Mark Wielaard2024-09-071-1/+1
| | | | | | | | | | | | | We were printing the addr_off instead of the sym_off. And the testcases all expected the address offset instead of the symbol table offset. * src/readelf.c (print_gdb_index_section): Print sym_off as Symbol table offset. * tests/run-readelf-gdb_index.sh: Fix up all symbol table offsets that were the same as the address offset. Signed-off-by: Mark Wielaard <[email protected]>
* debuginfod: Make sure extra libs are also included in static link in src/ tooFrank Ch. Eigler2024-09-061-1/+1
| | | | | | | | | commit 742fb81f3 did most of the work for supporting --enable-gcov, but one debuginfod client is hiding in the src/ directory, namely srcfiles, which also needs this enumeration of dependent libraries for static linkage. Signed-off-by: Frank Ch. Eigler <[email protected]>
* Avoid overriding libcxx system headerAlfred Wingate2024-08-141-0/+2
| | | | | | | | | | Replace -I with -iquote to avoid overriding stack system header from libcxx-18 with the previously built stack binary. Override DEFAULT_INLCUDES because m4 adds -I. by default. https://bugs.gentoo.org/925241 Signed-off-by: Aaron Merey <[email protected]>
* strip.c: Apply --permissive when writing the debug fileAaron Merey2024-07-231-0/+2
| | | | | | | | | The --permissive command line option is applied when writing the binary being stripped but is not applied when writing its separate debug file. Change this so that --permissive applies to writing the debug file as well. Signed-off-by: Aaron Merey <[email protected]>
* eu-stack: add support for sysroot optionLuke Diamand2024-07-041-0/+9
| | | | | | | | | | | Use the dwfl_set_sysroot() function to set the sysroot to be used when analysing a core: e.g. $ eu-stack --core core --sysroot /path/to/sysroot -e crashing_prog Signed-off-by: Luke Diamand <[email protected]> Signed-off-by: Michal Sekletar <[email protected]>
* readelf: Fix memory leak in print_hash_info()Maks Mishin2024-07-021-0/+1
| | | | Signed-off-by: Maks Mishin <[email protected]>
* ar, ranlib: Don't double close file descriptorsMark Wielaard2024-06-232-8/+8
| | | | | | | | | | | | | | | Found by GCC14 -Wanalyzer-fd-double-close. close always closes the given file descriptor even on error. So don't try to close a file descriptor again on error (even on EINTR). This could be bad in a multi-threaded environment. * src/ar.c (do_oper_extract): Call close and set newfd to -1. (do_oper_delete): Likewise. (do_oper_insert): Likewise. * src/ranlib.c (handle_file): Likewise. Signed-off-by: Mark Wielaard <[email protected]>
* readelf: Fix printing of DW_FORM_strx and DW_MACRO parsingMark Wielaard2024-05-141-10/+3
| | | | | | | | | | | | | | | | | | | | | | print_form_data didn't take the offset_len (4 or 8 bytes) into account causing the wrong entry to be read from .debug_str_offsets. print_debug_macro_section did sanity checking before calling print_form_data, which does sanity checking itself. The sanity check for DW_FORM_strx was wrong in print_debug_macro_section (but correct in print_form_data). Add a new testfile for run-readelf-macro.sh, this one compiled with clang -gdwarf-5 -fdebug-macro. * src/readelf.c (print_form_data): Multiply by offset_len for strx_val. (print_debug_macro_section): Remove sanity checks before calling print_form_data. * tests/testfileclangmacro.bz2: New testfile. * tests/Makefile.am (EXTRA_DIST): Add testfileclangmacro.bz2. * tests/run-readelf-macro.sh: Add testfileclangmacro output. Signed-off-by: Mark Wielaard <[email protected]>
* ar: Replace one alloca use by xmallocMark Wielaard2024-05-121-1/+5
| | | | | | | | | | | This alloca use is inside a lexical block and is used to replace one element of argv. Use a function local variable, xmalloc and free to make memory usage pattern more clear. * src/ar.c (main): Move newp char pointer declaration up. Use xmalloc to allocate space. free at end of main. Signed-off-by: Mark Wielaard <[email protected]>