Relocation is the process performed by a linker or loader of adjusting symbolic addresses in compiled object code to reflect the actual, absolute memory addresses where the code and data will reside during execution. This is a critical step in creating a final executable binary, as individual object files are compiled assuming a base address of zero; the linker resolves these relative references into concrete locations within the program's final memory layout, as defined by a linker script or the target's memory map.
Glossary
Relocation

What is Relocation?
A core process in low-level software toolchains for hardware accelerators.
In the context of NPU acceleration and vendor SDKs, relocation is essential when combining hand-optimized kernels (using hardware intrinsics or inline assembly) with higher-level framework code. The linker must resolve calls to vendor runtime functions and map data buffers to correct memory regions (e.g., shared vs. global memory). The process also handles position-independent code and is governed by the platform's Application Binary Interface (ABI), ensuring binary compatibility between modules compiled with different parts of the vendor toolchain.
Core Characteristics of Relocation
Relocation is the critical final-stage process where symbolic references in compiled code are resolved and adjusted to reflect actual memory addresses at load or link time. It bridges the gap between hardware-agnostic object files and hardware-specific executable binaries.
Address Adjustment
The core function of relocation is to adjust memory addresses in an object file's code and data sections. These addresses are initially relative or placeholder values. The linker or loader calculates the final absolute addresses based on the memory layout defined by the linker script and the load address, then patches them into the binary.
- Example: A function call
call 0x0000in an object file is changed tocall 0x40001000in the final executable after determining the function's actual location in memory.
Symbol Resolution
Relocation depends on symbol resolution, where undefined references to functions or variables (e.g., printf) are matched with their definitions found in other object files or libraries. The symbol table in each object file is searched to find the address of each symbol. Unresolved symbols cause a linker error.
- Internal vs. External: Resolves both internal symbols (within the same module) and external symbols (from other libraries).
- Strong vs. Weak: Strong symbol definitions (functions, initialized globals) override weak ones.
Relocation Types & Entries
Object files contain relocation entries (in a .rel or .rela section) that instruct the linker how to patch the code. Each entry specifies:
- Offset: The location in the object file to patch.
- Symbol: Which symbol's address to use.
- Type: The relocation type (e.g.,
R_X86_64_PC32,R_AARCH64_ADR_PREL_PG_HI21) that defines the exact calculation for the address adjustment, accounting for instruction size and PC-relative vs. absolute addressing.
Static vs. Dynamic Relocation
Static Relocation is performed by the linker during the creation of an executable. All addresses are finalized, producing a ready-to-run binary. Used for static libraries.
Dynamic Relocation is performed by the loader (dynamic linker) at program startup or during runtime for shared libraries (dynamic libraries). Addresses may be adjusted based on where the library is loaded into memory (Address Space Layout Randomization - ASLR). This uses the Procedure Linkage Table (PLT) and Global Offset Table (GOT).
Position-Independent Code (PIC)
PIC is code that executes correctly regardless of its absolute memory address, essential for shared libraries. It uses PC-relative addressing for code and indirect accesses via the GOT for global data. This minimizes the number of relocation entries required at load time, speeding up startup and enabling ASLR.
- PIE (Position-Independent Executable): An entire executable built as PIC, enhancing security.
- Relocation for PIC primarily involves filling the GOT with correct addresses.
NPU & Accelerator Context
For NPUs and hardware accelerators, relocation is managed by the vendor toolchain and vendor runtime. When compiling kernels for an NPU:
- The cross-compiler generates object code with unresolved references to device-side APIs or memory buffers.
- The vendor's linker performs relocation, resolving symbols against the vendor SDK libraries and mapping code/data to the NPU's specific memory map (e.g., SRAM, global memory).
- The final binary (often embedded in a fat binary or loaded separately) contains addresses valid for that specific NPU architecture's Vendor ISA.
How Relocation Works: A Step-by-Step Mechanism
Relocation is the critical final-stage process performed by a linker or loader that adjusts symbolic addresses in compiled object code to reflect the actual, absolute memory addresses where the code and data will reside during execution.
The process begins after compilation, when the assembler outputs object files containing machine code with symbolic references and relocation entries. These entries are directives that identify every memory address in the code that is not yet final—such as jumps to functions or accesses to global variables. The linker's primary role is to resolve these symbols by combining multiple object files and libraries, assigning a tentative logical address to each code and data section based on a linker script that defines the target memory map.
Finally, the loader performs the actual runtime relocation when it copies the program into memory for execution. It reads the relocation entries and calculates the final physical addresses by adding a base address offset—the actual load address—to each relocatable reference. For position-independent code (PIC), this often involves adjusting entries in a Global Offset Table (GOT). This adjustment transforms all relative and unresolved addresses into absolute, executable pointers, creating a coherent binary image ready for the processor.
Relocation vs. Related Processes
A comparison of the low-level processes involved in preparing compiled code for execution, focusing on address resolution and binary generation.
| Process / Feature | Relocation | Linking | Loading |
|---|---|---|---|
Primary Function | Adjusts address references in object code to reflect final load addresses. | Resolves symbols and combines multiple object files into a single executable or library. | Copies the executable code and data from storage into memory and prepares it for execution. |
Execution Stage | Performed by the linker (static relocation) and/or the loader (dynamic relocation). | Occurs after compilation, producing a final executable or shared library (static/dynamic linking). | Occurs at program launch (load-time) or during execution (runtime linking). |
Address Binding | Binds relative/virtual addresses to absolute/physical addresses. | Binds external symbol references to their definitions, assigning tentative addresses. | Binds absolute addresses to actual physical memory addresses (if required by the OS). |
Input | Object files with relocation records (.rela, .rel sections). | Object files (.o), static libraries (.a), and shared library references. | Executable or shared library file (e.g., ELF, PE format). |
Output | Modified object code with resolved addresses, or a binary with relocation tables. | Executable file, shared library, or partially linked object. | Program image loaded into process memory, with segments mapped. |
Key Data Structures | Relocation entries (symbol, offset, type), Global Offset Table (GOT), Procedure Linkage Table (PLT). | Symbol table, section headers, relocation tables. | Program headers, segment descriptors, memory mapping structures. |
Vendor NPU Specificity | Highly specific; relocation records must match the vendor's Instruction Set Architecture (ISA) and memory model. | Linker must understand vendor-specific object formats and ABI; may use vendor toolchain. | Loader (often part of vendor runtime) must map code to NPU-accessible memory and handle device-specific setup. |
Modifies Executable Code |
Relocation in Practice: NPU & AI Acceleration Contexts
Relocation is the critical process where a linker or loader adjusts symbolic addresses in compiled object code to absolute memory locations, enabling code to execute correctly at its final load address. In NPU programming, this process is specialized for accelerator memory spaces and vendor-specific address mappings.
Symbol Resolution & Address Binding
The first phase of relocation involves symbol resolution, where the linker matches every symbolic reference (e.g., a call to a function conv2d()) with its precise definition from an object file or library. Address binding then assigns a tentative virtual address to each symbol. For NPUs, this includes mapping symbols to specific accelerator memory regions (e.g., NPU SRAM, device DRAM) defined by the vendor's memory map. Unresolved symbols at this stage result in linker errors.
Relocation Entry Processing
Object files contain relocation entries (or relocation records) that identify every place in the code where an address needs adjustment. Each entry specifies:
- The offset within the object file's section.
- The symbol whose address is needed.
- A relocation type defining the exact calculation (e.g., absolute, relative). The linker iterates through these entries, fetching the final address of the referenced symbol and performing the mandated calculation to patch the binary code. NPU toolchains add vendor-specific relocation types for hardware register addresses and tensor memory buffers.
Position-Independent Code (PIC) & Relocation
Position-Independent Code (PIC) is designed to execute correctly regardless of its base load address, minimizing the need for load-time relocation. It uses Global Offset Tables (GOT) and Procedure Linkage Tables (PLT) to indirect address references. For NPU kernels, PIC is less common due to the need for maximum performance and deterministic memory layouts. However, Position-Independent Executables (PIE) are used for host-side driver code to enhance security through Address Space Layout Randomization (ASLR).
NPU-Specific Relocation Challenges
Relocating code for NPUs introduces unique complexities:
- Multiple Address Spaces: Code must reference host CPU memory, NPU device memory, and mapped hardware registers, each with different base addresses.
- Vendor-Specific Sections: Object files contain special sections (e.g.,
.nv.infofor NVIDIA,.rodata.clfor OpenCL) that require custom relocation logic. - Kernel Argument Buffers: Addresses for tensor buffers passed to NPU kernels must be relocated to point to their final locations in device memory.
- Shared Library Interposition: Ensuring calls to vendor runtime libraries (e.g.,
libcudart.so) are correctly resolved on the target system.
Linker Scripts & Memory Layout Control
Linker scripts (e.g., .ld files) provide explicit control over the relocation process by defining the final memory layout. They are essential for embedded NPU systems. A script specifies:
- MEMORY regions (e.g.,
NPU_ITCM,DRAM), their origin, length, and attributes. - SECTION commands dictating where input sections (
.text,.data) are placed in output memory. - Symbol assignments (e.g.,
_npubuffer_start = .;) to expose layout details to code. This allows engineers to place performance-critical kernel code in fast, tightly-coupled NPU memory (TCM) and data buffers in larger, slower DRAM.
Dynamic Relocation at Load Time
For executables using dynamic/shared libraries, final relocation occurs at load time by the dynamic linker/loader (e.g., ld-linux.so). It performs:
- Runtime relocation (RTLD): Patches the Global Offset Table (GOT) with the actual addresses of dynamically loaded symbols.
- Lazy binding: Defers resolution of function addresses via the Procedure Linkage Table (PLT) until the first call, improving startup speed.
In NPU contexts, the vendor runtime library (e.g., AMD ROCm, Intel oneAPI) is typically a dynamic library, and its symbols (like
hipMalloc) are resolved and relocated when the host application launches.
Frequently Asked Questions
Relocation is a fundamental process in software compilation and linking, critical for deploying code to specific memory addresses on hardware accelerators like NPUs. These questions address its core mechanisms and role in low-level programming.
Relocation is the process performed by a linker or loader of adjusting symbolic addresses in compiled object code to reflect the actual, absolute memory addresses where the code and data will reside during execution on a hardware accelerator like a Neural Processing Unit (NPU).
When a compiler generates code, it doesn't know the final memory layout. It uses placeholder addresses or labels. The relocation process resolves these placeholders using information stored in relocation entries within the object file's ELF sections. This is essential for vendor SDKs where kernel code must be placed in specific NPU memory regions (e.g., shared memory, constant cache) for optimal performance. Without correct relocation, code would reference invalid memory, causing crashes or incorrect results.
Enabling Efficiency, Speed & Accuracy
Intelligent Analysis, Decision & Execution
We build AI systems for teams that need search across company data, workflow automation across tools, or AI features inside products and internal software.
Talk to Us
Search across company data
Give teams answers from docs, tickets, runbooks, and product data with sources and permissions.
Useful when people spend too long searching or get different answers from different systems.

Automate internal workflows
Use AI to route work, draft outputs, trigger actions, and keep approvals and logs in place.
Useful when repetitive work moves across multiple tools and teams.

Add AI to products and internal tools
Build assistants, guided actions, or decision support into the software your team or customers already use.
Useful when AI needs to be part of the product, not a separate tool.
Related Terms
Relocation is a core process in the software toolchain for NPUs. These related concepts define the components and specifications that govern how code is prepared, linked, and ultimately executed on specialized hardware.
Linker Script
A configuration file that provides the linker with a precise memory map for the target hardware. It defines:
- The memory regions available on the NPU (e.g., SRAM, DRAM, cache).
- Where specific sections of code (
.text) and data (.data,.bss) should be placed. - The entry point address for program execution.
The linker uses this script to perform relocation, assigning final, absolute addresses to all symbols based on this layout, which is critical for NPUs with complex, non-uniform memory hierarchies.
Application Binary Interface (ABI)
The low-level contract between separately compiled program modules and the operating system. It defines the rules for:
- Calling conventions: How functions pass arguments and return values using registers or the stack.
- System call mechanisms.
- Data representation (size, alignment, endianness).
- Object file format (e.g., ELF).
The ABI is essential for relocation because the linker must resolve cross-module references (e.g., function calls) according to these standardized rules to ensure binary compatibility.
Executable and Linkable Format (ELF)
The standard file format for executables, object code, shared libraries, and core dumps on many Unix-like systems and embedded platforms, including NPU targets. Key components for relocation include:
- Sections: Contiguous blocks like
.text(code),.data(initialized data), and.rel.text(relocation entries for code). - Segments: Units used by the loader to map sections into memory.
- Relocation tables: Data structures (e.g.,
RELorRELAsections) that list every symbol reference requiring address adjustment. The linker reads ELF files, processes relocation tables, and writes a new ELF executable with resolved addresses.
Loader
The system program (often part of the OS kernel) responsible for loading an executable into memory and preparing it for execution. Its duties related to relocation are:
- Memory allocation: Reserving address space as specified by the ELF program headers.
- Address space layout randomization (ASLR): Applying a random offset to the load address for security, which necessitates runtime relocation.
- Dynamic linking: Loading shared libraries and performing relocation on-the-fly to resolve symbols in those libraries.
- Jumping to the entry point to start execution. For NPUs, a vendor runtime often acts as a specialized loader.
Position-Independent Code (PIC)
Code that can execute correctly regardless of its absolute address in memory. It is a strategy to minimize the need for relocation at load time, which is crucial for shared libraries and security (ASLR). Techniques include:
- PC-relative addressing: Using offsets from the current program counter (PC) to access data and code.
- Global Offset Table (GOT): A table of pointers to global variables, with a fixed offset from the code.
- Procedure Linkage Table (PLT): A table used for lazy binding of function calls to shared libraries. PIC increases flexibility but may introduce a small performance overhead due to indirection.
Symbol Resolution
The process by which a linker associates each symbolic reference in object code with its precise definition. This is a prerequisite for relocation. The linker:
- Scans all input object files and libraries to build a global symbol table.
- For each undefined reference (e.g., a call to
printf), it searches the table for a matching definition. - Upon finding a match, it records the symbol's eventual address.
- Relocation then uses these resolved addresses to patch the machine code. Unresolved symbols result in a linker error.

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.
Partnered with leading AI, data, and software stack.
How We Work
Custom AI workflows for your Business
One-fit-all AI don't work for modern businesses. At Inferensys, we aim to understand your business & custom requirements; which we use to define most efficient agentic workflows, the data, and the tools for your business.
01
Review the use case
We understand the task, the users, and where AI can actually help.
Read more02
Pick the right approach
We define what needs search, automation, or product integration.
Read more03
Build the first useful version
We implement the part that proves the value first.
Read more04
Improve from there
We add the checks and visibility needed to keep it useful.
Read moreThe first call is a practical review of your use case and the right next step.
Talk to Us