Mark Wielaard [Tue, 26 May 2026 16:18:25 +0000 (18:18 +0200)]
elfcompress: Handle shstrtab/symtab names more consistently
We track the shstrtab and symtab section names in case they need to be
renamed. These names are sometimes assigned a static string (from the
shstrtab string pool), sometimes created as a copy of an existing
string name and sometimes created by constructing a new string. This
means they might leak because they are never freed.
Fix this leak by defining the variables early (as NULL) before looping
over all sections, making sure to always assign a allocated (copy) of
the (new) name and explicitly free them at cleanup (run both on
success and failure).
This makes it easier to reason about allocation status and string
"ownership" making it easy to see there are no memory issues even in
the rare case of a .[z]debug section being used as a symtab or
shstrtab table (which is why there is no testcase, because it is
questionable whether such a file is actually valid).
* src/elfcompress.c (process_file): Define shstrtab_name,
shstrtab_newname, symtab_name and symtab_newname
early. xstrdup shstrtab_name and symtab_name if they were
assigned to a static string. Free all four strings at
cleanup.
Mark Wielaard [Mon, 18 May 2026 16:47:21 +0000 (18:47 +0200)]
libelf: Get orig_addralign the same way for 32/64 bit ELF in elf_compress
Depending on whether the ELF was 32 or 64 bit elf_compress would get
the original sh_addralign, as embedded in the Chdr, differenly. For
64bit ELF we would simply get the sh_addralign from the Shdr. For
32bit ELF we would take the (max) alignment of the underlying
Elf_Data, provided by __libelf_compress. Use the second method for
both since the Shdr might not have been setup yet, so what counts is
the Elf_Data alignment.
* libelf/elf_compress.c (elf_compress): Remove sh_addralign.
Set chdr.ch_addralign to orig_addralign in 64bit case.
Mark Wielaard [Mon, 18 May 2026 17:33:26 +0000 (19:33 +0200)]
elfcompress: Don't over allocate sections bitmap
In process_file we allocate a bitmap sections to track which sections
we want to (de)compress. This allocates shnum / 8 + 1 unsigned
ints. But an unsigned int can contain more bits than just 8. In all
other places we use WORD_BITS defined as 8U * sizeof (unsigned int).
Also use WORD_BITS to calculate how many unsigned ints we need for the
sections bitmap.
* src/elfcompress.c (process_file): Use shnum / WORD_BITS + 1
to allocate sections.
Aaron Merey [Thu, 14 May 2026 21:12:59 +0000 (17:12 -0400)]
dwarf_getsrclines.c: Restore initialization of debug_str_offset
Prior to commit d4b0848b ("libdw: dwarf_getsrcfiles should not imply
dwarf_getsrclines") debug_str_offset was initialized with a default
value of 0. This default initialization was removed as part of the
refactor introduced in d4b0848b.
Restore debug_str_offset's default initialization to 0. For a
well-formed binary, it wasn't possible to use debug_str_offset
uninitialized. The value is only relevant for line headers using
NVIDIA's CUBIN extension, in which case the real offset was always
stored in debug_str_offset before use. However it's possible for a
malformed binary to cause uninitialized use and static analyzers
may complain about this.
Mark Wielaard [Wed, 13 May 2026 15:56:18 +0000 (17:56 +0200)]
debuginfod: Don't trust x-debuginfod-size in debuginfod_validate_imasig
Double check file size the server sent against the file size we
actually got in debuginfod_validate_imasig. So we check the signature
over the whole file size as we received it. Otherwise we might be
creating a hash over a shorter (possibly zero sized) data. This makes
sure the server sents a signature that should match the full file (and
not just an arbitrary shorter prefix).
* debuginfod/debuginfod-client.c (debuginfod_validate_imasig):
Call fstat on fd and check x-debuginfod-size equals received
file size.
Mark Wielaard [Wed, 13 May 2026 13:57:57 +0000 (15:57 +0200)]
debuginfod-client: Use CURLOPT_MAXREDIRS
Guard against bad servers. Older libcurl allowed unlimited
redirects. Newer libcurl default to max 30. Explicitly set
CURLOPT_MAXREDIRS to 6 (twice the number of redirects that seems
"reasonable"). This guards against badly setup servers that keep
redirecting. https://curl.se/libcurl/c/CURLOPT_MAXREDIRS.html
Aaron Merey [Fri, 1 May 2026 17:11:47 +0000 (13:11 -0400)]
tests/Makefile.am: Add --track-destroy=yes to valgrind_cmd
Add --track-destroy=yes to valgrind_cmd when --tool=helgrind. This
reports missing pthread_{mutex,rwlock}_destroy calls when a lock is
initialized at the address of a live rwlock or mutex.
Aaron Merey [Sun, 10 May 2026 20:13:02 +0000 (16:13 -0400)]
src/strip.c: Unconditionally re-iterate when preserving sh_link/sh_info
handle_elf may perform multiple iterations over section headers to
ensure that if a section is included in the debug file, then its
sh_link and sh_info sections are also included in the debug file.
handle_elf contains an optimization where an additional iteration may
be avoided if the sh_link or sh_info of a section marked for inclusion
in the main elf file have yet to be investigated by the current iteration.
The additional iteration is scheduled only if the loop index 'cnt' has
already passed the sh_link or sh_info.
This optimization can cause a bug where the sh_link or sh_info of
a section in the debug file may not be present in the debug file.
sh_link/sh_info cross references between .symtab and .rel.* sections
might be ordered such that .symtab is marked for stripping while iterating
over all the .rel.debug_* sections that reference .symtab in their sh_link,
resulting in no additional debug-preservation handling for .symtab.
However, it's possible later in the loop for a .rel.* section to refer
to an allocated section via sh_info and .symtab via sh_link. In this case,
.symtab gets marked for preservation in the main elf file. If no other
.rel.debug_* sections are encountered for the rest of the iteration, then
debug-preservation isn't triggered for .symtab. This results in the debug
file containing a NOBITS .symtab despite .rel.debug_* sections referencing
.symtab in their sh_link. If --reloc-debug-sections is given, a segfault
or error may occur when attempting to resolve these relocations.
Fix this by unconditionally scheduling another iteration across section
headers when an sh_link or sh_info gets flagged for inclusion in the main
elf file.
For the above case, the additional iteration will trigger debug-preservation
for .symtab upon detection that a .rel.debug_* sh_link is being kept in the
main elf file. .symtab will then be present in both the main elf file and
debug file.
Mark Wielaard [Mon, 4 May 2026 15:26:14 +0000 (17:26 +0200)]
libdwfl: Fix out of memory handling in link_map.c report_r_debug
In report_r_debug we don't fully handle an out of memory condition
when trying to allocate memory for the r_debug_info_module struct.
Deallocated allocated buffers and return -1 immediately instead of
trying to continue.
* libdwfl/link_map.c (report_r_debug): Call release_buffer
with -1 and return on malloc failure.
"gelf_*.3*" is the glob intended to include all gelf man pages in %files.
Man page gelf.3 was recently added and does not match the glob. Fix
this by also including "gelf.3*" in %files.
Serhei Makarov [Mon, 23 Mar 2026 18:53:56 +0000 (14:53 -0400)]
src/stacktrace.c: Enable ARM support
Since we plan to replace stacktrace with stackprof (& the associated
test case) in a subsequent patchset, this is a minimal patch to
illustrate where the existing code using libdwfl_stacktrace needs to
generalize.
* configure.ac: Expand ac_cv_has_asm_x86_perf_regs_h
to ac_cv_has_compat_asm_perf_regs_h also allowing arm/arm64.
* src/stacktrace.c: Enable for ARM architectures.
(expected_frame_nregs): New function.
(sp_reg_index): New function.
(sysprof_find_dwfl): Replace hardcoded SP index with new functions.
(sysprof_unwind_frame_cb): Likewise.
(main): Open default_ebl backend appropriate to the current arch.
Serhei Makarov [Fri, 6 Mar 2026 20:49:45 +0000 (15:49 -0500)]
backends/: add 32-bit ARM sample_regs support
After developing the common pieces in prior patches, adding register
sample support for another architecture is fairly predictable. Here we
add support for 32-bit ARM.
* backends/Makefile.am (arm_SRCS): Add arm_initreg_sample.c.
* backends/arm_init.c (arm_init): Add hooks for
sample_sp_pc, perf_frame_regs_mask.
* backends/arm_initreg_sample.c: New file. Use default
arm_set_initial_registers_sample implementation.
* backends/libebl_PERF_FLAGS.h (PERF_FRAME_REGISTERS_ARM): New
constant describing registers needed for 32-bit arm unwinding. Also
define it on 64-bit arm to allow profiling programs running in 32-bit
compatibility mode.
Serhei Makarov [Fri, 6 Mar 2026 20:25:16 +0000 (15:25 -0500)]
backends/: should use size_t n_regs_mapping for *_sample_sp_pc
These should have been size_t all along, matching the public
libdwfl_stacktrace dwflst_sample_getframes interface. Fix.
* backends/aarch64_initreg_sample.c (aarch64_sample_sp_pc): Fixup
argument type for n_regs_mapping.
* backends/i386_initreg_sample.c (i386_sample_sp_pc): Fixup argument
type for n_regs_mapping.
* backends/libebl_PERF_FLAGS.h (generic_sample_sp_pc): Fixup argument
type for n_regs_mapping, adjust loop index var accordingly.
* backends/x86_64_initreg_sample.c (x86_64_sample_sp_pc): Fixup
argument type for n_regs_mapping.
* libebl/ebl-hooks.h (sample_sp_pc): Fixup argument type for
n_regs_mapping.
Serhei Makarov [Fri, 6 Mar 2026 17:21:47 +0000 (12:21 -0500)]
libebl/eblinitreg_sample.c: fix a potential off-by-one error
I believe the way things were setup on x86 meant this never triggered
(since n_regs == n_regs_mapping, the for loop would stop at the
correct moment), but the logic here looks clearly incorrect for the
general case. Fix.
* libebl/eblinitreg_sample.c (ebl_set_initial_registers_sample):
Be sure to break when i == n_regs_mapping, which is out of range.
Serhei Makarov [Fri, 6 Mar 2026 17:33:49 +0000 (12:33 -0500)]
backends/: fixup x86 initreg_sample to share code with aarch64
A bunch of x86 sample_regs code should be common across
architectures. In particular, sample_sp_pc() implementation looks to
be universally applicable apart from the register positions.
* backends/x86_initreg_sample.c (x86_sample_sp_pc): Remove in favour
of generic_sample_sp_pc (added to libebl_PERF_FLAGS.h in prev patch).
(x86_sample_perf_regs_mapping): This should have been an inline
function. Fix.
* backends/i386_init.c (i386_init): Use
__libebl_init_cached_regs_mapping.
* backends/x86_64_init.c (x86_64_init): Use
__libebl_init_cached_regs_mapping.
* backends/i386_initreg_sample.c (i386_sample_sp_pc): Use
generic_sample_sp_pc.
* backends/x86_64_init.c (x86_64_initreg_sample): Use
generic_sample_sp_pc.
Serhei Makarov [Fri, 6 Mar 2026 17:10:29 +0000 (12:10 -0500)]
backends/: add aarch64 sample_regs support
Expanding the libdwflst support for handling perf sample_regs register
files to other architectures. First, add the pieces for aarch64.
* backends/Makefile.am (aarch64_SRCS): Add aarch64_initreg_sample.c.
* backends/aarch64_init.c (aarch64_init): Add hooks for
set_initial_registers_sample, sample_sp_pc, perf_frame_regs_mask.
* backends/aarch64_initreg_sample.c: New file. Implement
aarch64_set_initial_registers_sample mirroring the ptrace->dwarf_regs
logic in aarch64_initreg.c.
* backends/libebl_PERF_FLAGS.h (PERF_FRAME_REGISTERS_AARCH64): New
constant describing registers needed for aarch64 unwinding.
(generic_sample_sp_pc): New inline function generalizing existing
x86_sample_sp_pc code to any arch given sp_index and pc_index.
* libebl/eblinitreg_sample.c (ebl_sample_perf_regs_mapping): Update
with a default implementation for arches where perf_regs and
dwarf_regs order coincides (we just need the mapping to account for
present/absent registers in perf_regs mask).
* libebl/eblopenbackend.c (__libebl_init_cached_regs_mapping): New
function generalizing a bit of ARCH_init regs_mapping boilerplate.
* libebl/eblopenbackend.c (__libebl_init_cached_regs_mapping):
Implement new function.
Mark Wielaard [Mon, 13 Apr 2026 21:30:45 +0000 (23:30 +0200)]
libdw: Recognize .debug_dwp section in scn_dwarf_type as TYPE_DWO
dwarf_begin_elf tries to guess what type of Dwarf we have. When it
sees a .debug_dwp section it assumed it was TYPE_PLAIN instead of
TYPE_DWO and would try to find more "plain" .debug sections (ignoring
other .dwo sections). This would cause it to not detect any debug
sections in a .dwp file containing a .debug_dwp section.
* libdw/dwarf_begin_elf.c (scn_dwarf_type): Recognize
.debug_dwp or .zdebug_dwp sections.
Mark Wielaard [Mon, 13 Apr 2026 12:29:27 +0000 (14:29 +0200)]
elf_newdata: Make sure to set d_type to ELF_T_BYTE and d_align to one
If d_align isn't explicitly set in elf_newdata it will default to
zero. This confuses elf_update when more than one Elf_Data has been
added to a (new) Elf_Section. Only the last will appear to be added.
ELF_T_BYTE happens to be zero and so d_type did appear to be setup
correctly. Also set it explicitly to show the defaults.
The elf_newdata test happened to pass because it set d_align to 1
explicitly. But would fail if it wouldn't set it. Add some extra
checks.
Also update the elf_newdata man page with the new defaults.
* libelf/elf_newdata.c (elf_newdata): Explicitly set d_type
and d_align.
* tests/newdata.c (add_section_data): Check d_buf, d_size,
d_type, d_align and d_version default values.
* doc/elf_newdata.3: Document d_align defaults to one.
Mark Wielaard [Thu, 9 Apr 2026 12:40:44 +0000 (14:40 +0200)]
elflint: Recognize debug dwo sections
.debug dwo sections can include the SHF_EXCLUDE flag to indicate that
the linker shouldn't process them. Also a .debug_str.dwo section is
like a normal .debug_str section. There is no .debug_line_str.dwo
section, so that doesn't need special casing.
Add some dwo files to run-elflint-test.sh to make sure debug files
with .dwo sections aren't flagged by eu-elflint with --gnu --debug.
* src/elflint.c (special_sections): Add .debug_str.dwo.
(IS_DEBUG_DWO): New macro.
(check_sections): For IS_DEBUG_DWO files allow SHF_EXCLUDE.
* tests/run-elflint-test.sh: Add .dwo testfiles.
Mark Wielaard [Mon, 23 Mar 2026 18:01:53 +0000 (19:01 +0100)]
readelf: print .debug_cu_index and .debug_tu_index sections
DWARF Package files (.dwp) might contain a .debug_cu_index and/or
.debug_tu_index section. Print the contents of these sections. Handles
version 2 (DWARF4 + GNU Debugfission extension), version 5
(standardized) and version 6 (prelimenary, adds 64bit offsets). Use
the existing dwp4 and dwp5 testfiles.
* src/readelf.c (options): Add cu_index to debug-dump docs.
(section_e): Add section_cu_index.
(section_all): Likewise.
(parse_opt): handle "cu_index" arg for debug-dump.
(dwarf_section_short_string): New static function.
(print_cu_index_section): Likewise.
(print_debug): Move up implicit_info and explicit_info. Only
search for skeleton file if .debug_info is needed. Handle both
.debug_cu_index and .debug_tu_index through
print_cu_index_section.
* tests/run-readelf-cu-index.sh: New test.
* tests/Makefile.am (TESTS): Add run-readelf-cu-index.sh.
(EXTRA_DIST): Likewise.
Josef Cejka [Wed, 18 Mar 2026 11:02:13 +0000 (12:02 +0100)]
debuginfod: add metadata query by buildid
This patch extends current metadata by search by buildid.
It allows clients to query for all packages (with exact versions)
and files associated with a specific buildid.
I'd like to use the exact package versions during core dump
analysis to match them with already known issues/bugs,
to check that involved packages are reasonable up-to-date
and to identify other invalid setup, such as mixing packages
from different Linux distros.
Search by buildid prepares alternative db query, handling
of results incl. gathering results from federated servers
remains the same.
It does not search for source files or source file archives.
Mark Wielaard [Thu, 26 Mar 2026 12:32:18 +0000 (13:32 +0100)]
debuginfod: Make sure PATH_MAX exists in debuginfod-client.c
Some systems (Hurd) don't define PATH_MAX (which is optional according
to POSIX). Make sure it is defined and no special linux specific
headers are used in debuginfod-client.c.
* debuginfod/debuginfod-client.c: Include limits.h instead of
linux/limits. If PATH_MAX isn't define it to 4K (the default
on GNU/Linux).
Mark Wielaard [Sat, 21 Mar 2026 22:56:58 +0000 (23:56 +0100)]
readelf: Print split DWARF CU version, unit type and id
When printing the split units we reused the version, unit type and id
found in the skeleton unit. The version and id really should match,
but the unit type shouldn't. We could hard code the expected values,
but it is better to look them up explicitly. One testcase needed
updating to show the correct split_compile unit type.
* src/readelf.c (print_debug_units): Call dwarf_cu_die and
dwarf_cu_info to explicitly fetch split_version,
split_unit_type and split_unit_id.
* tests/run-readelf-loc.sh: Adjust Unit type.
Fabian Rast [Fri, 20 Mar 2026 13:50:35 +0000 (14:50 +0100)]
elflint: add additional lints to LOAD, INTERP and PHDR segments
* src/elflint.c (check_program_header):
- PT_PHDR may not occur more than once
- PT_INTERP must precede any loadable segment entry
- PT_LOAD entries must be sorted on the p_vaddr member
debuginfod_default_progressfn was added without a corresponding dummy
variant, causing an error when building with --disable-debuginfod and
--enable-libdebuginfod=dummy.
Commit d7cb72f7 changed debuginfod-find to always set a progress
callback function in order to handle interrupts during downloading.
Previously debuginfod-find set a progressfn only when the -v command
line option was given. If the DEBUGINFOD_PROGRESS environment variable
is set, libdebuginfod automatically sets a default progressfn as long as
no other progressfn has been set using debuginfod_set_progressfn.
Commit d7cb72f7 therefore resulted in DEBUGINFOD_PROGRESS no longer
affecting debuginfod-find when invoked without -v.
This patch restores the old behaviour: when DEBUGINFOD_PROGRESS is set
and -v is not given, the default progressfn will trigger during
downloading.
Aaron Merey [Wed, 11 Mar 2026 14:01:38 +0000 (10:01 -0400)]
libdebuginfod: Add the default progress callback function to the public API
Rename default_progressfn to debuginfod_default_progressfn and expose it
in libdebuginfod's public API. Previously this function could only be
indirectly invoked by clients by setting the DEBUGINFOD_PROGRESS
environment variable and not explicitly setting a progress callback
function with debuginfod_set_progressfn.
The purpose of this change is to make debuginfod_default_progressfn
directly callable so that custom progress callback functions can
delegate progress reporting to it.
Aaron Merey [Fri, 13 Mar 2026 21:46:48 +0000 (17:46 -0400)]
gelf_update_move.c: Handle ELFCLASS32 and ELFCLASS64 separately
Similar to commit c460e2088, gelf_update_move does not distinguish
between ELFCLASS32 and ELFCLASS64 binaries.
The code assumes that Elf32_Move and Elf64_Move structs are the same
size but they are not. The m_info and m_poffset fields have type
uint32_t for Elf32_Move but uint64_t for Elf64_Move.
Fix this by handling ELFCLASS32 and ELFCLASS64 cases separately.
Mark Wielaard [Sat, 7 Mar 2026 14:55:48 +0000 (15:55 +0100)]
libelf: elf_update should make sure section zero exists
elf_update might crash for 65280+ sections when section zero headers
aren't loaded. Make sure section zero is loaded before trying to write
to it.
Add testcase to tests/test-manyfuncs.c but use ELF_C_READ_MMAP_PRIVATE
to workaround https://sourceware.org/bugzilla/show_bug.cgi?id=33968
* libelf/elf32_updatenull.c (updatenull_wrlock): Call
getshdr_wrlock to load shdr.
* tests/test-manyfuncs.c (check_elf): Use elf_begin with
ELF_C_READ_MMAP_PRIVATE if use_mmap. Call elf_update early.
Mark Wielaard [Mon, 2 Mar 2026 14:51:48 +0000 (15:51 +0100)]
libdwfl: Work around ET_REL files with sh_addr fields set to non-zero
libdwfl tries to model the loading of modules (executables, shared
libraries, the linux kernel and/or kernel modules) in
memory. Depending on the (offline) load address it then also applies
(simple) relocations for ET_REL (object files or kernel modules). Load
addresses are normally represented through phdr segments for ET_EXEC
or ET_DYN, but for ET_REL files (which don't have phdrs) the Elf
section sh_addr fields are used.
The sh_addr fields of the ET_REL Elf images are updated in two places
__libdwfl_elf_address_range (through __libdwfl_report_elf) and
__libdwfl_relocate (through dwfl_module_getelf and
dwfl_module_getdwarf). Both rely on sh_addr being zero if no load
address has been set yet, so the address layout for each (SHF_ALLOC)
section is done only once.
Recent linux kernels use a linker script that does set the sh_addr
fields to (random, linker assigned) non-zero addresses. See commit 1ba9f8979426 ("vmlinux.lds: Unify TEXT_MAIN, DATA_MAIN, and related
macros").
The sh_addr values seems unnecessary, but because they aren't zero
anymore our layout/relocation code doesn't know it still has to figure
out a "real" load value for these sections.
Introduce __libdwfl_reset_sh_addr which resets all sh_addr fields to
zero for SHF_ALLOC sections in ET_REL files.
We don't call __libdwfl_reset_sh_addr on aux_sym files (from
.gnu_debugdata) and when constructing an Elf from a core file. In all
other cases we know (or assume) that the Elf file is being opened
through libdw_open_elf (called indirectly through __libdw_open_elf,
__libdwfl_report_offline, dwfl_module_getelf and dwfl_module_getdwarf)
This technically changes the Elf that goes through libdwfl, but we
would already update the sh_addr fields for ET_REL Elf sections in
memory anyway to represent the load address as libdwfl would see
them. So this isn't really a change in behavior (it just might update
the sh_addr field twice).
Mark Wielaard [Tue, 24 Feb 2026 21:19:48 +0000 (22:19 +0100)]
aarch64: Recognize SHT_AARCH64_ATTRIBUTES
Recognize SHT_AARCH64_ATTRIBUTES. This is enough to stop elflint
complaining about unknown section types. But doesn't implement parsing
the attributes.
* backends/aarch64_symbol.c (aarch64_section_type_name):
New function.
* backends/aarch64_init.c (aarch64_init): Hook
section_type_name.
Aaron Merey [Tue, 24 Feb 2026 21:08:07 +0000 (16:08 -0500)]
dwarf_begin_elf.c: Fix lock resource leak
dwarf_begin_elf might free memory for a struct Dwarf after its rwlock and
mutex fields have been initialized without calling the corresponding
destroy functions to release the lock resources.
Fix this by moving lock inits to the end of the valid_p function, after
the struct Dwarf being intialized has passed all error checking.
Samuel Dainard [Tue, 17 Feb 2026 22:07:06 +0000 (23:07 +0100)]
readelf: Fix NULL pointer dereference in process_symtab with -D flag
When using eu-readelf with the -D (use_dynamic_segment) flag on malformed
ELF files, process_symtab can receive a NULL symstr_data pointer if
elf_getdata_rawchunk fails or the dynamic segment is malformed.
The function then dereferences symstr_data->d_buf without checking,
causing a segmentation fault.
Add NULL check before accessing symstr_data fields.
Fixes regression introduced in 0.194 where process_symtab was refactored
to handle dynamic segment symbol tables.
Signed-off-by: Samuel Dainard <sdainard@amazon.com>
Mark Wielaard [Tue, 10 Feb 2026 17:25:42 +0000 (18:25 +0100)]
tests: Skip tests on non-ELF bitcode object files
clang with -flto produces object files that contain bitcode. This
breaks various (self) testcases that expect those .o files are ELF
files. eu-readelf, eu-nm, eu-elfline and eu-elfcompress won't work on
such files.
Add a helper function is_obj_bitcode in test-subr.sh that tests can
use to possibly skip a check on an .o file.
* tests/test-subr.sh (is_obj_bitcode): New function.
(testrun_on_self): Use is_obj_bitcode to possibly skip a file.
(testrun_on_self_obj): Likewise.
(testrun_on_self_compressed): Likewise.
(testrun_on_self_quiet): Likewise.
* tests/run-elfclassify-self.sh: Check if the object files are
actually ELF files.
* tests/run-nm-self.sh: Use is_obj_bitcode to possibly skip file.
* tests/run-reverse-sections-self.sh: Likewise.
* tests/run-strip-reloc-self.sh: Likewise.
* tests/run-strip-strmerge.sh: Likewise.
* tests/strip-reloc-subr.sh: Likewise.
Mark Wielaard [Thu, 5 Feb 2026 18:58:05 +0000 (19:58 +0100)]
readelf: Handle CUs that share an addr_base or str_offsets_base
readelf assumed each .debug_addr and .debug_str_offsets was associated
with precisely one CU DIE. But CU DIEs can have the same
DW_AT_addr_base or DW_AT_str_offsets_base. Change the code to find the
first CU associated with the offset.
* src/readelf.c (print_debug_addr_section): Skip CUs that
have an addr_base already handled.
(print_debug_str_offsets_section): Likewise for
str_offsets_base.
Mark Wielaard [Mon, 9 Feb 2026 22:18:40 +0000 (23:18 +0100)]
elflint, readelf, support SHT_LLVM_LTO and SHT_LLVM_ADDRSIG
An SHT_LLVM_LTO section contains LLVM bitcode. An SHT_LLVM_ADDRSIG
section contains ULEB128 integers referring to the symbol table
indexes of address-significant symbols. This patch just recognizes the
SHT constants but doesn't handle the section contents.
* libebl/eblsectiontypename.c (ebl_section_type_name):
Recognize SHT_LLVM_ADDRSIG and SHT_LLVM_LTO.
Mark Wielaard [Mon, 9 Feb 2026 22:17:19 +0000 (23:17 +0100)]
elflint: Accept R_X86_64_DTPOFF64 in ET_REL files
Normally R_X86_64_DTPOFF32, which takes a 32bit TLS offset, is used,
but R_X86_64_DTPOFF64, which takes a 64bit TLS offset may also be used
in ET_REL files.
Aaron Merey [Tue, 3 Feb 2026 21:31:00 +0000 (16:31 -0500)]
src/elfclassify.c: Fix memory leak in check_ar_members
If current_path needs to be reallocated, full_path is assigned a newly
malloced buffer and then full_path is assigned to current_path. This
leaks the previous value of full_path.
Mark Wielaard [Sat, 7 Feb 2026 17:25:09 +0000 (18:25 +0100)]
configure: Add -Wdeprecated-non-prototype and -Wfree-labels if available
Calling a function with one or more arguments declared with an empty
parameter list is an error in C23. In C23 labels applied to
non-statements are allowed, but not in earlier standards (they are as
GNU extension in GCC). Add -Wdeprecated-non-prototype and
-Wfree-labels (available since GCC 15) to catch this.
* configure.ac: Add HAVE_DEPRECATED_NON_PROTOTYPE_WARNING
and HAVE_FREE_LABELS_WARNING check.
* config/eu.am: Set FREE_LABELS_WARNING and
FREE_LABELS_WARNING.
(AM_CFLAGS): Add DEPRECATED_NON_PROTOTYPE_WARNING and
FREE_LABELS_WARNING.
Signed-off-by: Mark Wielaard <mark@klomp.org> Reviewed-by: Sam James <sam@gentoo.org>
Mark Wielaard [Sat, 7 Feb 2026 00:48:26 +0000 (01:48 +0100)]
configure: Add -Wmissing-parameter-name if available
Before C23 omitting parameter names in function definitions isn't
supported. Add -Wmissing-parameter-name (available since GCC 15) to
catch this.
* configure.ac: Add HAVE_MISSING_PARAMETER_NAME_WARNING check.
* config/eu.am: Set MISSING_PARAMETER_NAME_WARNING based on
HAVE_MISSING_PARAMETER_NAME_WARNING.
(AM_CFLAGS): Add MISSING_PARAMETER_NAME_WARNING.
Signed-off-by: Mark Wielaard <mark@klomp.org> Reviewed-by: Sam James <sam@gentoo.org>
Mark Wielaard [Wed, 4 Feb 2026 14:09:06 +0000 (15:09 +0100)]
stacktrace: fix a C23-ism in sigint_handler
clang 21 doesn't like ommitting a parameter name when not in C23 mode.
stacktrace.c:1138:44: error: omitting the parameter name in a function definition is a C23 extension [-Werror,-Wc23-extensions]
1138 | static void sigint_handler (int /* signo */)
| ^
1 error generated.
* src/stacktrace.c (sigint_handler): Use attribute unused.
Serhei Makarov [Thu, 29 Jan 2026 17:27:50 +0000 (12:27 -0500)]
PR33854: fix regression in dwflst_perf_sample_getframes
In commit 3ce0d5ed, I missed the fact that
dwflst_perf_sample_getframes needs to handle the case of an unattached
Dwfl, when dwfl->process->ebl is not yet available to translate the
registers. Thus, it can't be a straightforward wrapper of
dwfl_sample_getframes, but should instead handle the attaching logic
identically to that function.
Also fix a leakage of sample_arg in dwflst_sample_getframes that was
happening on attach failure.
* libdwfl_stacktrace (dwflst_sample_getframes): Fix a leak of
sample_arg on attach failure.
* libdwfl_stacktrace (dwflst_perf_sample_getframes): Implement
attaching the Dwfl identically to dwflst_sample_getframes.
Avoid leaking sample_arg on attach failure.
Aaron Merey [Fri, 19 Dec 2025 22:39:36 +0000 (17:39 -0500)]
Make __libdwfl_debuginfod_find_* functions thread safe
Individual debuginfod_client objects and their underlying CURLM handles
should not be used concurrently during calls to
__libdwfl_debuginfod_find_debuginfo and
__libdwfl_debuginfod_find_executable.
Add a mutex field to struct Dwfl to serialize calls to
__libdwfl_debuginfod_find_*.
Aaron Merey [Wed, 7 Jan 2026 23:43:49 +0000 (18:43 -0500)]
gelf_getmove.c: Handle ELFCLASS32 and ELFCLASS64 separately
Currently gelf_getmove does not distinguish between ELFCLASS32 and
ELFCLASS64 binaries. This is assumes that Elf32_Move and Elf64_Move
structs are the same size.
This assumption is false since the m_info and m_poffset fields have
type uint32_t for Elf32_Move but uint64_t for Elf64_Move.
Fix this by handling ELFCLASS32 and ELFCLASS64 cases separately when
copying Elfxx_Move fields to dst.
Mark Wielaard [Sat, 20 Dec 2025 02:19:36 +0000 (03:19 +0100)]
forge: Add a forgejo workflow to run various tests
This adds a check-debian.yaml file which will run various tests under
Debian and Fedora for new merge requests.
* CONTRIBUTING: Explain how to contribute through the forge.
* .forgejo/workflows/check-debian.yaml: New Debian based workflow.
* .forgejo/workflows/check-fedora.yaml: New Fedora based workflow.
Mark Wielaard [Thu, 18 Dec 2025 15:35:06 +0000 (16:35 +0100)]
tests: Disable valgrind for run-large-elf-file and run-compress-test
Both run-compress-test and run-large-elf-file create really big
files. Processing these under valgrind take a very long time. To
encourage more testing under valgrind memcheck or helgrind disable
valgrind for these two test so people don't have to wait 10 minutes
for make check results.
Mark Wielaard [Mon, 8 Dec 2025 10:44:45 +0000 (11:44 +0100)]
libelf: Add gelf_fsize main check
This test itself isn't super interesting, it just checks that all
Elf_Types are handled by gelf_fsize and that the 32 vs 64 variant
sizes make sense. The interesting part is that it uses the internal
interface (__libelf_type_sizes) to do it. So you don't have to
contruct a whole Elf handle.
It mimics the support for "main checks" in libdw. It adds a way to
compile an individual source file with an optional main function that
can directly access the internal/static functions.
To add new main check tests you have to add an #ifdef MAIN_CHECK with
a main function that calls the test functions to the source file. And
add two make file rules after .SECONDEXPANSION. One starting with
<source_basename>_checks$(EXEEXT) and one starting with
nodist_<source_basename>_check_SOURCES.
Mark Wielaard [Fri, 5 Dec 2025 15:27:04 +0000 (16:27 +0100)]
libdw: Make sure to get .eh_frame_hdr with .eh_frame in getcfi_shdr
If we find a .eh_frame section we want to make sure to also get the
search table section .eh_frame_hdr. Otherwise lookups will be very
slow. Only create a Dwarf_CFI without a search table as a last resort.
* libdw/dwarf_getcfi_elf.c (getcfi_shdr): Keep iterating
through the shdrs till both .eh_frame and .eh_frame_hdr are
found. Check both aren't SHT_NOBITS.
Arnout Engelen [Fri, 5 Dec 2025 14:52:41 +0000 (15:52 +0100)]
tests: improve reliability of run-sysroot.sh
Previously, the 'second' test would test the `RESOLVE_IN_ROOT` feature
when the current libc supports it, even when the currently running
kernel did not yet support it.
Martin Cermak [Fri, 5 Dec 2025 13:33:57 +0000 (14:33 +0100)]
PR33635: Introduce debuginfod --home-redirect and --home-html
NEWS: New entry
debuginfod/debuginfod.cxx: Feature implementation
doc/debuginfod.8: Doc text
tests/Makefile.am: New testcase
tests/run-debuginfod-homesite.sh: New testcase
Mark Wielaard [Fri, 5 Dec 2025 11:56:22 +0000 (12:56 +0100)]
libdw: Translate DW_LANG_Algol68 to DW_LNAME_Algol68 with lversion 1978
1978 is the year of the publication of the Revised Report that defines
the revised language. And this is the version set by gcc a68. So when
we see DW_LANG_Algol68 we translate it to DW_LNAME_Algol68 with
lversion set to 1978 to match gcc a68.
* libdw/dwarf_srclang.c (srclang_to_language): Set lversion to
1978 for DW_LANG_Algol68.
Mark Wielaard [Tue, 2 Dec 2025 14:41:23 +0000 (15:41 +0100)]
libdw: Add Erlang, Elixir and Gleam language constants
The DWARF standard recently added language constants for Erlang,
Elixir and Gleam. https://dwarfstd.org/languages.html
https://dwarfstd.org/languages-v6.html
* libdw/dwarf.h: Add DW_LANG_Erlang, DW_LNAME_Erlang,
DW_LANG_Elixir, DW_LNAME_Elixir, DW_LANG_Gleam and
DW_LNAME_Gleam.
* libdw/dwarf_default_lower_bound.c
(dwarf_default_lower_bound): Add DW_LANG_Gleam, DW_LANG_Erlang
and DW_LANG_Elixir.
(dwarf_language_lower_bound): Add DW_LNAME_Gleam, DW_LNAME_Erlang
and DW_LNAME_Elixir.
* libdw/dwarf_srclang.c (srclang_to_language): Handle
DW_LANG_Erlang, DW_LANG_Elixir and DW_LANG_Gleam.
(language_to_srclang): Handle DW_LNAME_Erlang, DW_LNAME_Elixir
and Add DW_LNAME_Gleam.