dynasm/relocations

Relocation model for x64/x86 (SimpleRelocation only). Mirrors runtime/src/relocations.rs.

Types

RelocationKind = enum
  rkRelative = 0,           ## PC-relative, no adjust on move
  rkAbsToRel = 1,           ## absolute -> relative, needs adjust
  rkRelToAbs = 2,           ## relative -> absolute, needs adjust
  rkAbsolute = 3             ## absolute, no adjust
RelocationSize = enum
  rsByte = 1, rsWord = 2, rsDWord = 4, rsQWord = 8
SimpleRelocation = object
  kind*: RelocationKind
  size*: RelocationSize
  arch*: int8 ## -1 for plain x64/x86 relocations, else an AArch64 arch-specific
              ## encoding id (mirrors dynasm-rs Aarch64RelocationEncoding):
              ## 0=B, 1=BCOND, 2=ADR, 3=ADRP, 4=TBZ.

Consts

AarchAdr = 2
adr: split 21 bit, byte aligned
AarchAdrp = 3
adrp: split 21 bit, 4096-byte aligned
AarchB = 0
b, bl: 26 bits, dword aligned
AarchBCond = 1
b.cond, cbz, cbnz, ldr literal: 19 bits, dword aligned
AarchTbz = 4
tbz, tbnz: 14 bits, dword aligned
EncByte = 0
EncDWord = 2
EncQWord = 3
EncWord = 1

Procs

proc decodeKind(code: uint8): RelocationKind {....raises: [], tags: [], forbids: [].}
proc encodeAarchReloc(id: int): uint8 {....raises: [], tags: [], forbids: [].}
Pack an AArch64 arch-specific relocation for macro emission. Plain x64/x86 codes always have low 6 bits 0..3, so ids live at 4..8 with zero kind bits (mirrors how rs keeps arch codes disjoint from the simple ones). Addition, not OR: 0x04|4 would collapse back to 0x04 and mistarget TBZ as B.
proc encodeKind(kind: RelocationKind; size: RelocationSize): uint8 {....raises: [],
    tags: [], forbids: [].}
Pack for macro emission, matches common.rs RelocationEncoding::encode.
proc fitsSigned(value: int64; bits: int): bool {....raises: [], tags: [],
    forbids: [].}
proc fromEncoding(code: uint8): SimpleRelocation {....raises: [ValueError],
    tags: [], forbids: [].}
Decode packed byte emitted by macro: kind<<6 | size-code, or 0x04|id for AArch64 arch-specific relocations.
proc fromSize(kind: RelocationKind; size: RelocationSize): SimpleRelocation {.
    ...raises: [], tags: [], forbids: [].}
proc readAarchValue(id: int; buf: openArray[byte]): int64 {....raises: [],
    tags: [], forbids: [].}
Inverse of writeAarchValue, with sign extension.
proc readValue(r: SimpleRelocation; buf: openArray[byte]): int64 {....raises: [],
    tags: [], forbids: [].}
proc relSize(r: SimpleRelocation): int {....raises: [], tags: [], forbids: [].}
proc relSize(s: RelocationSize): int {....raises: [], tags: [], forbids: [].}
proc writeAarchValue(id: int; buf: var openArray[byte]; value: int64): bool {.
    ...raises: [], tags: [], forbids: [].}
Masked read-modify-write of one LE u32, mirroring Aarch64RelocationEncoding::encode in dynasm-rs.
proc writeValue(r: SimpleRelocation; buf: var openArray[byte]; value: int64): bool {.
    ...raises: [], tags: [], forbids: [].}
Returns false on overflow (caller maps to ImpossibleRelocation).