feat(asm): symbol-valued DATA, division slash in symbols and plain semicolons
Assisted-by: GLM 5.3 Flash
This commit is contained in:
@@ -463,6 +463,61 @@ func (img *Image) emitGOObject(pkgPath, srcPath string, pre []byte, minLC int, r
|
||||
symRelocs[si] = append(symRelocs[si], rec[:]...)
|
||||
}
|
||||
}
|
||||
// The data symbols' own relocations: the symbol-valued DATA fields
|
||||
// ("DATA s+0(SB)/8, $other(SB)"). The toolchain patches each field
|
||||
// with the target's absolute address through an R_ADDR of the DATA
|
||||
// line's width, on every architecture (the code relocations are
|
||||
// per-architecture PC-relative shapes; a data pointer word is not), so
|
||||
// this mapping bypasses relocField. The definitions were appended in
|
||||
// DataSyms order, so data symbol i is definition index i.
|
||||
for i, d := range img.DataSyms {
|
||||
for _, r := range d.Relocs {
|
||||
if r.Kind != RelAddr {
|
||||
return nil, fmt.Errorf("GOOBJ emission: data symbol %q carries a non-data relocation", d.Name)
|
||||
}
|
||||
var rec [23]byte
|
||||
binary.LittleEndian.PutUint32(rec[0:], uint32(int32(r.Off)))
|
||||
rec[4] = r.Siz
|
||||
binary.LittleEndian.PutUint16(rec[5:], relocAddr)
|
||||
binary.LittleEndian.PutUint64(rec[7:], uint64(r.Addend))
|
||||
switch {
|
||||
case r.External && r.Name == goobjBuiltinMorestack:
|
||||
binary.LittleEndian.PutUint32(rec[15:], pkgIdxBuiltin)
|
||||
binary.LittleEndian.PutUint32(rec[19:], goobjBuiltinMorestackNoctxt)
|
||||
case r.External:
|
||||
pkg, name := splitQualified(r.Name)
|
||||
if pkg == "" {
|
||||
return nil, fmt.Errorf("GOOBJ emission: external symbol %q has no package prefix", r.Name)
|
||||
}
|
||||
pIdx, ok := extPkgIdx[pkg]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("GOOBJ emission: package %q not resolved", pkg)
|
||||
}
|
||||
sIdx, ok := extSymIdx[pkg+"·"+name]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("GOOBJ emission: symbol %s·%s not resolved", pkg, name)
|
||||
}
|
||||
binary.LittleEndian.PutUint32(rec[15:], uint32(pIdx))
|
||||
binary.LittleEndian.PutUint32(rec[19:], uint32(sIdx))
|
||||
default:
|
||||
if di, ok := defIdx[r.Name]; ok {
|
||||
binary.LittleEndian.PutUint32(rec[15:], pkgIdxSelf)
|
||||
binary.LittleEndian.PutUint32(rec[19:], uint32(di))
|
||||
break
|
||||
}
|
||||
// A DATA field may hold the address of a TEXT function of
|
||||
// the same file (the rt0 lib entry spelling), which is a
|
||||
// non-package definition.
|
||||
ni, isText := textNpIdx[r.Name]
|
||||
if !isText {
|
||||
return nil, fmt.Errorf("GOOBJ emission: reference to unknown symbol %q", r.Name)
|
||||
}
|
||||
binary.LittleEndian.PutUint32(rec[15:], pkgIdxNone)
|
||||
binary.LittleEndian.PutUint32(rec[19:], uint32(ni))
|
||||
}
|
||||
symRelocs[i] = append(symRelocs[i], rec[:]...)
|
||||
}
|
||||
}
|
||||
// The DWARF symbols' own relocations (the function address references).
|
||||
for _, ds := range dwarfRelocs {
|
||||
for _, r := range ds.relocs {
|
||||
|
||||
Reference in New Issue
Block a user