[PATCH 11/16] dwarf_loader: Handle DW_FORM_block in attr_numeric for Rust discriminant values
Arnaldo Carvalho de Melo <[email protected]> Mon, 22 Jun 2026 17:24:34 -0300
| Newsgroups | org.kernel.vger.dwarves |
|---|---|
| Message-ID | <[email protected]> |
From: Arnaldo Carvalho de Melo <[email protected]> Rust enums with 128-bit discriminant types (i128/u128) encode their DW_AT_discr_value as a DW_FORM_block1 containing a 16-byte little-endian integer, rather than using a standard data form like DW_FORM_data*. Since attr_numeric did not handle DW_FORM_block*, these discriminant values were not read and produced 311 warnings on a real Rust binary like sashiko-cli: DW_AT_<0x16>=0xa DW_AT_<0x16>=0xa ... (0x16 = DW_AT_discr_value, 0xa = DW_FORM_block1) Add DW_FORM_block1/block2/block4/block to attr_numeric, reading up to 8 bytes from the block into a uint64_t via memcpy and converting from little-endian with le64toh() so the result is correct on big-endian hosts as well. This covers all practical discriminant values. Before (sashiko-cli): $ pahole --btf_encode sashiko-cli 2>&1 | grep -c 'DW_AT_' 311 After: $ pahole --btf_encode sashiko-cli 2>&1 | wc -l 0 All warnings from Rust DWARF encoding of sashiko-cli are now resolved. Assisted-by: Claude:claude-opus-4-6 Signed-off-by: Arnaldo Carvalho de Melo <[email protected]> --- dwarf_loader.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/dwarf_loader.c b/dwarf_loader.c index fc88221ae339e7cd..9f7d2bd23359191b 100644 --- a/dwarf_loader.c +++ b/dwarf_loader.c @@ -7,6 +7,7 @@ #include <assert.h> #include <dirent.h> #include <dwarf.h> +#include <endian.h> #include <elfutils/libdwfl.h> #include <elfutils/version.h> #include <errno.h> @@ -353,6 +354,19 @@ static uint64_t attr_numeric(Dwarf_Die *die, uint32_t name) return value; } break; + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + case DW_FORM_block: { + Dwarf_Block block; + if (dwarf_formblock(&attr, &block) == 0 && block.length > 0) { + uint64_t value = 0; + size_t n = block.length > sizeof(value) ? sizeof(value) : block.length; + memcpy(&value, block.data, n); + return le64toh(value); + } + } + break; default: fprintf(stderr, "DW_AT_<0x%x>=0x%x\n", name, form); break; -- 2.54.0