appender

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 9, 2026 License: BSD-3-Clause Imports: 2 Imported by: 0

Documentation

Overview

Package appender is a tiny pure-Go appender for sections to a PE32/PE32+ image. It is the equivalent of `objcopy --add-section`, restricted to the case that matters for UEFI Unified Kernel Images: appending new sections at the end of the file, leaving every existing section's RVA, file offset and data untouched.

The package only depends on the standard library and is intentionally small so it can be vendored or audited in one sitting. It is the companion to github.com/go-coff/peln/linker; together they cover the two PE assembly modes the cloud-boot toolchain needs (append sections to an existing PE, vs. link .o files into a fresh PE).

References:

  • Microsoft PE/COFF specification rev 11+
  • systemd-stub PE annex

Limitations:

  • Section names are limited to 8 bytes (PE truncates longer names via a string table that this package does not write).
  • SizeOfHeaders is not grown, so the input PE must reserve enough header padding to hold the added section-header entries. The systemd UEFI stubs (`linux{x64,aa64,riscv64}.efi.stub`) all reserve plenty.
  • The Optional Header CheckSum field is zeroed; UEFI does not enforce it and recomputing requires the full PE checksum algorithm. Tools that need a valid checksum (e.g. Secure Boot signers) should run their own pass afterwards.

Index

Constants

View Source
const (
	SCN_CNT_INITIALIZED_DATA uint32 = 0x00000040
	SCN_MEM_READ             uint32 = 0x40000000
	SCN_MEM_WRITE            uint32 = 0x80000000
	SCN_MEM_EXECUTE          uint32 = 0x20000000

	// DefaultCharacteristics is the set of flags objcopy applies to a
	// `--add-section` of an arbitrary binary blob: read-only initialised data.
	DefaultCharacteristics = SCN_CNT_INITIALIZED_DATA | SCN_MEM_READ
)

IMAGE_SCN_* characteristics.

Variables

This section is empty.

Functions

func Append

func Append(stub []byte, sections []Section) ([]byte, error)

Append takes a PE32 / PE32+ binary `stub` and returns a new image with `sections` appended after the last existing section. Existing section data is preserved byte-for-byte; only NumberOfSections, SizeOfImage and the new section-table entries are written. The PE CheckSum field is zeroed.

Returns an error if the section table cannot grow inside SizeOfHeaders, or if any input field is malformed.

func AppendBefore added in v0.3.0

func AppendBefore(stub []byte, beforeName string, sections []Section) ([]byte, error)

AppendBefore is like Append, but inserts the new section-table entries immediately before the entry named `beforeName` (rather than at the end of the table). The raw bodies of the new sections still go at the end of the file, with VirtualAddresses past every existing section — so the on-disk VA layout is identical to what Append produces. Only the section-header ORDER changes.

Why this exists: some firmware PE loaders (notably parts of EDK2's DXE pipeline that hand off via the relocation directory) walk the section table in declared order and stop iterating once they have applied the relocation pass. Placing application sections (e.g. a self-extracting stub's `.payload`) AFTER `.reloc` causes those loaders to never copy the section's raw bytes into memory, even though the section header itself is present. Inserting before `.reloc` puts the new headers ahead of the loader's relocation cutoff while preserving the section's body at the usual end-of-file location.

If `beforeName` is empty, AppendBefore behaves like Append. If the named section is not found, an error is returned and the input is unchanged.

Types

type Section

type Section struct {
	Name            string // up to 8 bytes; longer names are rejected
	Data            []byte
	Characteristics uint32 // see SCN_* constants; DefaultCharacteristics is fine
}

Section describes one new section to append.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL