Inferensys

Glossary

ELF Sections

Contiguous segments within an Executable and Linkable Format (ELF) binary file that contain specific types of data, such as executable code (.text), initialized data (.data), or symbol tables (.symtab).
Data scientist building training data pipeline on laptop, data preprocessing visible, technical workspace.
BINARY FORMAT

What is ELF Sections?

ELF sections are the fundamental, contiguous data blocks within an Executable and Linkable Format (ELF) binary file, each holding a specific type of information required for program execution, linking, and debugging.

An ELF section is a named, contiguous segment in an ELF file that contains a homogeneous type of data, such as executable machine instructions (.text), initialized global variables (.data), or a symbol table (.symtab). The ELF header points to a section header table, which is an array of structures describing each section's type, virtual address, file offset, and size. Sections are the primary unit of organization for linkers, which combine sections from multiple object files, and for debuggers, which use sections like .debug_info to map machine code back to source-level constructs.

In the context of NPU acceleration and vendor SDKs, ELF sections are critical for packaging compiled kernels and runtime data for hardware accelerators. A vendor toolchain will generate specialized sections—such as .rodata for constant weights or a vendor-named section for NPU instruction bundles—that the vendor runtime and driver interpret. The linker script precisely controls the placement of these sections into the final binary's memory layout, ensuring data is aligned for the target NPU's memory hierarchy and accessible via the correct hardware abstraction layer APIs.

VENDOR SDK AND INTRINSIC MAPPING

Key ELF Sections in System Programming

ELF sections are contiguous segments within an Executable and Linkable Format binary that contain specific types of data, such as executable code, initialized data, or symbol tables. Understanding their structure is critical for low-level optimization, linking, and debugging on hardware accelerators like NPUs.

01

.text (Executable Code)

The .text section contains the executable machine code instructions for a program. This is the read-only segment that the CPU or NPU fetches and executes. For NPU programming, this section may hold kernels compiled to the vendor's specific ISA.

  • Key Property: Marked with the SHF_ALLOC and SHF_EXECINSTR flags.
  • NPU Context: Vendor toolchains place optimized, intrinsic-heavy kernel code here.
  • Example: The compiled binary for a matrix multiplication kernel optimized for a specific NPU tensor core.
02

.data & .bss (Program Data)

These sections manage a program's static and global variables.

  • .data section: Contains initialized static/global data (e.g., int x = 5;). It is read-write and occupies space in the binary.
  • .bss section (Block Started by Symbol): Holds uninitialized static/global data (e.g., int buffer[1000];). It is read-write but occupies no space in the binary file, only a size descriptor, reducing file size. The loader allocates and zero-initializes this memory at runtime.

NPU Context: Pre-allocated weight tensors or constant lookup tables may reside in .data, while large scratchpad buffers may be declared in .bss.

03

.rodata (Read-Only Data)

The .rodata section stores constant, immutable data used by the program.

  • Contents: String literals, global constants, jump tables, and switch-case data.
  • Key Property: Marked as SHF_ALLOC (needs memory) but not writable (SHF_WRITE is false).
  • NPU Context: Often holds quantization scales, bias constants, or activation lookup tables that kernels read during execution. Placing this data in .rodata allows for potential caching in the NPU's constant memory hierarchy.
04

.symtab & .strtab (Symbol Management)

These sections form the program's symbol table, essential for linking and debugging.

  • .symtab (Symbol Table): An array of Elf64_Sym structures defining all symbols (functions, variables) – their names, binding (local/global), type, and associated section.
  • .strtab (String Table): Holds the null-terminated string names for the symbols in .symtab. The .symtab entries contain offsets into this table.

Critical Role: The linker uses .symtab to resolve references between object files. For NPU binaries, this includes kernel function names exposed to the host CPU driver via the driver API.

05

.rel.* & .rela.* (Relocation Information)

Relocation sections provide instructions to the linker or dynamic loader on how to adjust symbolic references in the code once final memory addresses are known.

  • Format: .rel.* contains entries with just an offset and symbol index. .rela.* adds an explicit addend.
  • Process: When linking, the linker reads these sections and patches the actual bytes in sections like .text or .data with correct addresses.

NPU Context: Vital when a kernel compiled for an NPU references a global variable whose address isn't known until the final executable is linked. The vendor toolchain generates these entries.

06

.shstrtab & Section Headers

These metadata sections describe the ELF file itself.

  • .shstrtab (Section Header String Table): Contains the null-terminated names of all sections (e.g., ".text", ".data"). The section header table references this.
  • Section Header Table: An array of Elf64_Shdr structures, one for every section in the file, including those describing other sections. Each header defines a section's name (as an index into .shstrtab), type, flags, address, offset, and size.

System Tool Dependency: Tools like readelf, objdump, and the linker itself rely entirely on these structures to parse the binary.

VENDOR SDK AND INTRINSIC MAPPING

The Role of ELF Sections in NPU Acceleration

In NPU acceleration, ELF (Executable and Linkable Format) sections are not merely passive containers; they are active, structured components that a vendor's toolchain and runtime use to orchestrate hardware-specific execution, memory allocation, and kernel dispatch.

An ELF section is a contiguous block within an ELF binary file that holds a specific category of data or instructions, such as executable code (.text), initialized variables (.data), or symbol information (.symtab). For NPU programming, vendor SDKs define proprietary sections (e.g., .rodata.npu_weights, .text.npu_kernel) that segregate accelerator-specific code and data, enabling the vendor runtime and driver to efficiently locate, validate, and load computational graphs and kernels onto the hardware.

The strategic placement of data into these specialized sections is dictated by linker scripts and managed by the vendor toolchain. This allows for optimized memory hierarchy management, where constant weights can be placed in fast, read-only memory and executable kernels are aligned for direct submission to the NPU's processing cores. This section-level organization is critical for meeting the strict alignment, padding, and addressing requirements of a vendor's Instruction Set Architecture (ISA) and Application Binary Interface (ABI).

SECTION COMPARISON

Standard vs. NPU-Specific ELF Sections

This table compares standard Executable and Linkable Format (ELF) sections, common in general-purpose executables, with sections specific to binaries targeting Neural Processing Units (NPUs). NPU-specific sections are defined by vendor SDKs to encode hardware-specific metadata, tensor data, and kernel code.

Section NameStandard ELFNPU-Specific ELFPrimary Purpose

.text

Contains executable machine instructions. For NPUs, this holds the compiled accelerator kernel code.

.data

Contains initialized global and static variables. Used for constant model parameters or weights on NPUs.

.bss

Reserves space for uninitialized static data. Usage on NPUs is minimal due to static memory allocation.

.rodata

Contains read-only data, such as string literals and constants. Holds immutable model metadata on NPUs.

.symtab

Symbol table containing debugging symbols. Essential for linking and dynamic loading on both.

.strtab

String table for symbol names referenced in .symtab.

.shstrtab

String table for section header names.

.dynamic

Contains information for dynamic linking. Often absent in bare-metal NPU binaries.

.got

Global Offset Table for position-independent code. Rarely used in NPU execution models.

.plt

Procedure Linkage Table for dynamic function calls. Not typical for NPU kernels.

.debug_*

Various sections (e.g., .debug_info) for source-level debugging. Often stripped from production NPU binaries.

.note.*

Contains vendor or toolchain notes. May be repurposed by NPU vendors for build metadata.

.tensor

Vendor-specific section storing tensor descriptors, shapes, data types, and memory layout information.

.weights

Section dedicated to pre-quantized or formatted neural network weights for direct loading into NPU memory.

.metadata

Contains NPU-specific execution metadata: kernel launch parameters, memory barriers, and synchronization points.

.constbuf

Holds constant buffers or uniform data that is read-only during kernel execution.

.shared

Defines the layout and size of shared memory regions for inter-core communication on the NPU.

.cmdqueue

Encodes a sequence of low-level commands for the NPU's command processor or DMA engine.

.vendor.isa

Proprietary section containing binary-encoded instructions for a vendor-specific NPU ISA.

.vendor.config

Hardware configuration data: clock settings, power profiles, and core activation masks.

ELF SECTIONS

Frequently Asked Questions

ELF sections are fundamental building blocks of executable and object files, organizing code, data, and metadata for linking, loading, and debugging. Understanding their structure is critical for low-level optimization and deployment on hardware accelerators like NPUs.

An ELF section is a contiguous block of data within an Executable and Linkable Format (ELF) binary file that serves a specific, defined purpose, such as holding executable instructions, initialized variables, or symbol information. Its primary purpose is to organize the different components of a program (code, data, metadata) into logical units for the linker and loader. The linker uses sections to combine code from multiple object files, while the loader maps sections into memory with appropriate permissions (read, write, execute) during program execution. This organization is essential for creating functional binaries and for tools like debuggers and profilers to understand the program's structure.

Prasad Kumkar

About the author

Prasad Kumkar

CEO & MD, Inference Systems

Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.

His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.