feat(asm): emit the riscv64 local-exec TLS sequence
Assisted-by: GLM 5.3
This commit is contained in:
1 parent
f8dbd4f017
commit
f2892e4f59
6 files changed
+114
-29
No files matched your search
+35
-1
@@ -98,6 +98,7 @@ const (
|
||||
RelRISCVPCRELIType // R_RISCV_PCREL_ITYPE (AUIPC + I-type pair)
|
||||
RelRISCVPCRELSType // R_RISCV_PCREL_STYPE (AUIPC + S-type pair)
|
||||
RelRISCVJal // R_RISCV_JAL (J-type call)
|
||||
RelRISCVTLSLE // R_RISCV_TLS_LE (LUI + I-type local-exec pair)
|
||||
RelLoong64AddrHi // R_LOONG64_ADDR_HI (pcalau12i)
|
||||
RelLoong64AddrLo // R_LOONG64_ADDR_LO (addi.d/ld/st)
|
||||
RelArm64Addr // R_ADDRARM64 (ADRP + ADD pair)
|
||||
@@ -335,6 +336,35 @@ func AssembleFile(f *ast.File, opts ...AssembleOption) (*Image, error) {
|
||||
return img, nil
|
||||
}
|
||||
|
||||
// riscvTLSSymbols names the symbols the file declares with the TLSBSS flag
|
||||
// (or its legacy numeric constant 256 from textflag.h): the assembler gives
|
||||
// their SB references the local-exec TLS sequence.
|
||||
func riscvTLSSymbols(f *ast.File) map[string]bool {
|
||||
var tls map[string]bool
|
||||
for _, d := range f.Decls {
|
||||
gd, ok := d.(*ast.Globl)
|
||||
if !ok || gd.Name == nil || gd.Name.Pseudo != "SB" {
|
||||
continue
|
||||
}
|
||||
for _, fl := range gd.Flags {
|
||||
isTLS := fl == "TLSBSS"
|
||||
if !isTLS {
|
||||
if n, err := strconv.Atoi(fl); err == nil && n&256 != 0 {
|
||||
isTLS = true
|
||||
}
|
||||
}
|
||||
if isTLS {
|
||||
if tls == nil {
|
||||
tls = map[string]bool{}
|
||||
}
|
||||
tls[gd.Name.Name] = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return tls
|
||||
}
|
||||
|
||||
// AssembleFileRISCV assembles every TEXT function of a parsed RISC-V file
|
||||
// and lays out its static symbols (GLOBL/DATA) in a data section behind the
|
||||
// code. SB references in the code are encoded as AUIPC pairs with zero
|
||||
@@ -344,6 +374,10 @@ func AssembleFileRISCV(f *ast.File) (*Image, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// The symbols the file declares TLSBSS resolve through the local-exec
|
||||
// sequence (LUI + ADDIW + ADD of TP), exactly as the toolchain routes
|
||||
// every SB reference whose symbol carries the STLSBSS type.
|
||||
tlsSyms := riscvTLSSymbols(f)
|
||||
// The pooled $i64 constants the wide MOV immediate loads refer to join
|
||||
// the declared data as read-only symbols, deduplicated across the file
|
||||
// (the toolchain synthesises the same symbols into its rodata).
|
||||
@@ -355,7 +389,7 @@ func AssembleFileRISCV(f *ast.File) (*Image, error) {
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
code, labels, relocs, lines, spadj, lits, err := assembleRISCV(t)
|
||||
code, labels, relocs, lines, spadj, lits, err := assembleRISCV(t, tlsSyms)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: %w", t.Name.Name, err)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user