fix(asm): make arm64 and loong64 relocations match the toolchain

This commit is contained in:
2026-09-14 18:22:00 +02:00
parent c6f0286732
commit 953c258d6a
9 changed files with 286 additions and 45 deletions
+17 -10
View File
@@ -6,6 +6,7 @@ package asm
import (
"fmt"
"sort"
"strconv"
"sourcedock.dev/petrbalvin/gasm-devkit/ast"
)
@@ -15,7 +16,7 @@ import (
// file-local static symbols are encoded RIP-relative and resolved within the
// image, so the raw bytes are self-consistent and executable at any base
// address; references to external symbols are recorded as relocations
// (Funcs[i].Relocs, Externals) and left unresolved — the object-file
// (Funcs[i].Relocs, Externals) and left unresolved, the object-file
// emitters turn them into linker relocations.
type Image struct {
Code []byte // concatenated function bodies
@@ -96,8 +97,9 @@ const (
RelPCRelAbs // 32-bit absolute (R_RISCV_32)
RelLoong64AddrHi // R_LOONG64_ADDR_HI (pcalau12i)
RelLoong64AddrLo // R_LOONG64_ADDR_LO (addi.d/ld/st)
RelArm64Addr // R_ADDRARM64 (ADRP + ADD/LDR/STR pair)
RelArm64Addr // R_ADDRARM64 (ADRP + ADD pair)
RelArm64Branch // R_CALLARM64 (BL instruction)
RelArm64LDST64 // R_ARM64_PCREL_LDST64 (ADRP + 64-bit LDR/STR pair)
)
type Reloc struct {
@@ -132,7 +134,7 @@ func (img *Image) Bytes() []byte {
// reference to a file-local static symbol becomes a RIP-relative load whose
// displacement is resolved against that layout; a reference to a symbol no
// GLOBL defines is recorded as an external relocation (Externals) with its
// displacement left zero — the object-file emitters resolve it at link
// displacement left zero, the object-file emitters resolve it at link
// time, while the raw image (Bytes) cannot represent it.
func AssembleFile(f *ast.File) (*Image, error) {
dataSyms, err := collectData(f)
@@ -451,13 +453,18 @@ func collectData(f *ast.File) ([]dataSym, error) {
ds.rodata = true
case "DUPOK":
ds.dupok = true
case "1":
ds.dupok = true
case "8":
ds.rodata = true
case "9":
ds.dupok = true
ds.rodata = true
default:
// Legacy numeric flag constants (runtime/textflag.h):
// DUPOK is 2, RODATA is 8; combinations arrive as one
// number (e.g. 10 = RODATA|DUPOK).
if n, err := strconv.Atoi(f); err == nil {
if n&2 != 0 {
ds.dupok = true
}
if n&8 != 0 {
ds.rodata = true
}
}
}
}
syms = append(syms, ds)