ARM64 ELF Relocator (Pure Java)
ARM64 Linker relocation implemented in pure Java! This is a fully functional ARM64 ELF relocator that requires no native code.
42+ ARM64 relocation types
Complete instruction-level relocation (ADR/ADD/LDR/MOVW)
GOT/PLT relocation support
TLS relocation support
PC-relative branch relocation
Pure Java implementation , no JNI required
java_relocator/
├── src/main/java/rprop/java/relocator/
│ ├── ElfParser.java # ELF file parser
│ ├── Arm64Relocator.java # ARM64 relocation engine
│ └── Main.java # Demo program
└── README.md
Supported Relocation Types
Type
Description
R_AARCH64_ABS64
64-bit absolute address
R_AARCH64_ABS32
32-bit absolute address
R_AARCH64_ABS16
16-bit absolute address
Type
Description
R_AARCH64_PREL64
64-bit PC-relative
R_AARCH64_PREL32
32-bit PC-relative
R_AARCH64_PREL16
16-bit PC-relative
Type
Description
R_AARCH64_GLOB_DAT
Global data pointer
R_AARCH64_JUMP_SLOT
PLT jump slot
R_AARCH64_GOT_LD_PREL19
GOT load PC-relative
R_AARCH64_GOT_GOTPAGE_LO15
GOT page low bits
R_AARCH64_GOT_GOTREL_PAGE
GOT page-relative
Type
Description
R_AARCH64_ADR_PREL_LO21
ADR low 21-bit
R_AARCH64_ADR_PREL_PG_HI21
ADR page high bits
R_AARCH64_ADR_PREL_PG_HI21_NC
ADR page high bits (no check)
Type
Description
R_AARCH64_ADD_ABS_LO12_NC
ADD low 12-bit
R_AARCH64_LDST8_ABS_LO12_NC
8-bit load/store
R_AARCH64_LDST16_ABS_LO12_NC
16-bit load/store
R_AARCH64_LDST32_ABS_LO12_NC
32-bit load/store
R_AARCH64_LDST64_ABS_LO12_NC
64-bit load/store
R_AARCH64_LDST128_ABS_LO12_NC
128-bit load/store
Type
Description
R_AARCH64_JUMP26
Unconditional jump (26-bit)
R_AARCH64_CALL26
Function call (26-bit)
R_AARCH64_CONDBR19
Conditional branch (19-bit)
R_AARCH64_LD_PREL_LO19
LDR PC-relative (19-bit)
Type
Description
R_AARCH64_MOVW_ABS_G0
MOVW absolute G0 group
R_AARCH64_MOVW_ABS_G1
MOVW absolute G1 group
R_AARCH64_MOVW_ABS_G2
MOVW absolute G2 group
R_AARCH64_MOVW_ABS_G3
MOVW absolute G3 group
R_AARCH64_MOVW_PREL_G0~G3
MOVW PC-relative G0~G3 groups
Type
Description
R_AARCH64_TLS_DTPMOD64
TLS module ID
R_AARCH64_TLS_DTPREL64
TLS dynamic offset
R_AARCH64_TLS_TPREL64
TLS thread-local offset
cd java_relocator
javac -d . src/main/java/rprop/java/relocator/* .java
java rprop.java.relocator.Main
// 1. Parse ELF file
byte [] elfData = readFile ("libnative.so" );
Arm64Relocator relocator = new Arm64Relocator (elfData );
// 2. Load into memory
long loadBase = 0x7fff00000000L ;
relocator .load (loadBase );
// 3. Add external symbols
relocator .addSymbol ("printf" , 0x7fff00001234L );
relocator .addSymbol ("malloc" , 0x7fff00005678L );
relocator .addSymbol ("strlen" , 0x7fff00009abcL );
// 4. Apply relocations
relocator .applyRelocations ();
// 5. Get result
byte [] relocatedImage = relocator .getLoadedImage ();
relocator .addTlsSymbol ("thread_local_var" , 0x100L );
relocator .applyRelocations ();
Core Implementation Principles
ARM64 uses specific instruction formats; relocation requires modifying instruction fields:
// ADR_PREL_PG_HI21 relocation
case R_AARCH64_ADR_PREL_PG_HI21 :
// Target page address
long targetPage = (symbolValue + addend ) & ~0xFFF ;
// Current page address
long currentPage = (baseAddress + relAddr ) & ~0xFFF ;
// Calculate page offset
long pageOffset = targetPage - currentPage ;
// Read instruction
int instr = readInstruction32 (relAddr );
// Clear original field and set new value
instr = (instr & ~0x3FFFE0 ) | ((pageOffset & 0x1FFFFC ) >> 2 );
// Write back
writeInstruction32 (relAddr , instr );
case R_AARCH64_JUMP_SLOT :
// GOT entry = symbol address
write64 (relAddr , symbolValue );
case R_AARCH64_RELATIVE :
// *offset = base + addend
write64 (relAddr , baseAddress + addend );
=== ARM64 ELF Relocator Demo (Pure Java) ===
Created mini ARM64 ELF (4096 bytes)
=== ARM64 Relocator Summary ===
ELF Type: 64-bit ARM64 (AArch64)
Machine: AArch64
Symbols: 7
Relocations: 6
Load Base: 0x400000
Page Size: 4096
Added external symbols:
printf = 0x7fff00001234
malloc = 0x7fff00005678
free = 0x7fff00005688
memcpy = 0x7fff00005698
GOT = 0x7fff00010000
Applying relocations...
Applied: 6, Skipped: 0
=== Demo Complete ===
This ARM64 relocator supports:
- 42+ relocation types
- ADR/ADD/LDR/MOVW instructions
- GOT/PLT relocations
- TLS relocations
- PC-relative branches
All implemented in pure Java!
Comparison with Real Linker
Feature
Java Implementation
bionic/linker
Architecture
Simulated memory
Real memory
Performance
Slightly lower
High
Memory Protection
No
Yes (mprotect)
Completeness
42+ types
Complete
Security
Educational use
Production grade
Support more types : TLSDESC, other special relocations
Optimize performance : Use ByteBuffer batch operations
Android integration : Combine with NativeMemoryUtils to write to real memory
Symbol resolution : Resolve DSO dependency chains
For educational and research purposes only.