pw_elf Python package#

pw_elf: ELF file support

The pw_elf Python package provides utilities to programmatically build ELF32 and ELF64 binary files from scratch.

pw_elf.builder#

Classes for working with ELF files.

class pw_elf.builder.ElfBuilder(
elf_machine: ElfMachine,
elf_class: ElfClass,
byteorder: Literal['little', 'big'],
elf_type: ElfType,
)#

Facilitates building up an ELF image and then writing it to a file.

__init__(
elf_machine: ElfMachine,
elf_class: ElfClass,
byteorder: Literal['little', 'big'],
elf_type: ElfType,
) None#

Initializes the ElfBuilder.

Parameters:
  • elf_machine – Target CPU architecture (ARM, XTENSA, etc.).

  • elf_class – Target ELF class bit width (CLASS32 or CLASS64).

  • byteorder – Endianness representation (little or big).

  • elf_type – Target ELF object file type (CORE, EXEC, etc.).

Raises:

ValueError – If class or byteorder parameters are invalid.

add_memory_region(vaddr: int, data: bytes, align: int = 1) None#

Registers a loadable memory segment in the builder.

Parameters:
  • vaddr – Target virtual address where the segment is loaded.

  • data – Raw binary byte segment payload.

  • align – Dynamic segment alignment constraint in memory. Must be a positive power-of-two.

Raises:

ValueError – If alignment is invalid, the address is unaligned, or the segment overlaps with an existing region.

add_note(note_type: int, name: bytes, desc: bytes) None#

Registers an ELF note to be written into a note segment.

Parameters:
  • note_type – Platform-specific note type code.

  • name – Dynamic note name string (owner identifier).

  • desc – Dynamic note descriptor payload.

build(writer: IO[bytes]) None#

Builds and writes the ELF image to the underlying target.

Parameters:

writer – Output binary stream to write the ELF target into.

class pw_elf.builder.ElfClass(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)#
class pw_elf.builder.ElfMachine(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)#
class pw_elf.builder.ElfType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)#

pw_elf.coredump#

Classes for programmatically building crash coredump ELF files.

class pw_elf.coredump.CoredumpBuilder(
elf_machine: ElfMachine,
elf_class: ElfClass,
byteorder: Literal['little', 'big'],
)#

Facilitates programmatically building crash coredump ELF files.

__init__(
elf_machine: ElfMachine,
elf_class: ElfClass,
byteorder: Literal['little', 'big'],
) None#

Initializes the CoredumpBuilder.

Parameters:
  • elf_machine – Target CPU architecture (ARM, etc.).

  • elf_class – Target ELF class bit width (CLASS32 or CLASS64).

  • byteorder – Endianness representation (little or big).

add_build_id(build_id: bytes) None#

Adds a GNU build ID note segment to the coredump.

Note

This note is informational only. Standard debuggers (GDB, LLDB) resolve a crashed process’s build ID post-mortem by parsing its memory-mapped first page (which maps the binary’s ELF header).

Because bare-metal embedded targets boot directly from flash memory (Execute In Place) and do not map their ELF headers in memory, debuggers cannot resolve the build ID automatically.

Adding a GNU build ID note segment to the coredump itself allows host-side triage processors to easily match the post-mortem dump to its corresponding symbols binary.

Parameters:

build_id – The binary software build uuid / signature.

add_thread(*, thread_id: int, registers: list[int]) None#

Adds a thread register dump (PRSTATUS note) to the coredump.

Parameters:
  • thread_id – The unique numeric thread identifier (PID).

  • registers – The general-purpose register values (GP registers). For ARM (32-bit), exactly 18 register values must be supplied mapping r0-r12, sp, lr, pc, psr, and orig_r0.

Raises:

ValueError – If target architecture/class is unsupported, or the register list size is incorrect.