Sigminer

Project Summary

Sigminer is a C/C++ library for extracting function signatures and type metadata from ELF object files using DWARF debug information and LLVM. I built it to support production-adjacent BPF tracing workflows where accurate user-space function prototypes are required, but existing tools such as readelf and objdump only provide inspection-oriented string output rather than a reusable programmatic API to embed in our applications at Dematic.

Given an object file and function name, Sigminer returns structured information such as return type, parameter count, parameter types, signedness, pointer/value classification, and related type descriptors. By focusing specifically on function symbols and their associated type data, it avoids unrelated object-file metadata and produces targeted output that is easier to consume by C/C++ tooling.

The library can be used to generate function prototypes for bpftrace scripts, support FFI binding generation, and power other binary-introspection workflows. My SQLite integration demo shows Sigminer extracting type information from a real codebase and using it to generate tracing scripts.

Development Highlights

  • Built a C/C++ library extracting type information pertaining to function symbols from ELF object files using DWARF debug information and LLVM.

  • Implemented structured type extraction for function return types, parameter counts, parameter types, signedness, pointer/value classification, and user defined type descriptors.

  • Designed a programmatic API as opposed to a CLI tool and extended the C++ library implementation with a C ABI for use in pure C codebases.

  • Extended Sigminer with rich type graphs and namespaces, enabling the bpftrace renderer to decode x86_64 uprobe arguments from registers or stack slots and display values by walking DWARF-derived type metadata.

Technical Design and Constraint

The core data flow is:

  1. Load an ELF object file or binary.
  2. Locate function symbols and match the requested function name.
  3. Traverse DWARF metadata for the function’s return type and parameters.
  4. Normalize the discovered types into Sigminer’s structured metadata model.
  5. Expose the result through a C/C++ API and renderers such as bpftrace.

The main constraint is that Sigminer depends on binaries containing usable DWARF debug information. Stripped binaries, optimized builds, unsupported architectures, or incomplete debug metadata can limit the accuracy or availability of extracted type data.

Why did I write Sigminer?

To develop BPF tracing scripts for our systems at Dematic, we needed a reliable dataset of the user-space functions in our codebase, including accurate signature information such as parameter counts, parameter types, return types, and type classifications.

BPF probes require this information to be explicitly defined in the probe or uprobe header. Although previously mentioned tools such as readelf and objdump can be used to inspect object files, their output is primarily string-based and often contains complex user-defined types. Our codebase makes extensive use of structures, unions, aliases, pointers, and other custom types, so determining the underlying primitive types and correctly distinguishing pointers from values or structures from unions required a more advanced method.

I created Sigminer to solve this problem. Sigminer is a library that uses DWARF debugging information together with LLVM to discover functions within ELF binaries and extract their signatures with a high degree of precision. It identifies each function’s parameter count, parameter types, return type, and the exact nature of those types, producing the structured type information needed to generate accurate BPF tracing scripts.

Demonstration

Screenshots and video from the SQL integration demo:

Sigminer in the SQLite Makefile

Current Progress

Current

Sigminer can currently extract function signature metadata from ELF binaries with DWARF debug information and expose that data through a programmatic API, we can generate bpftrace scripts and also render complex information like aggregates and pointer dereferencing.

Next Feature

Current development is focused on feature/return-line-numbers, which aims to generate BPF tracing scripts that can probe function return locations and identify exactly where a function exited.