fix(goobj): external package and symbol indices and arm64 pair relocations
Assisted-by: GLM 5.3
This commit is contained in:
+24
-3
@@ -18,19 +18,40 @@ import (
|
||||
// reloc/aux/data index arrays, with the arm64 preamble, the MinLC of 4
|
||||
// for the pc-value deltas, and the arm64 relocation types for the ADRP
|
||||
// pairs and BL calls.
|
||||
//
|
||||
// The toolchain records one relocation per ADRP pair: a single R_ADDRARM64
|
||||
// or R_ARM64_PCREL_LDST64 of Siz 8 at the ADRP word, from which the linker
|
||||
// patches both instructions of the pair (cmd/internal/obj/arm64/asm7.go,
|
||||
// the ADRP cases: one AddRel with Off at the pair's pc and Siz 8). gasm's
|
||||
// assembler records the ADRP+ADD form as two word relocs, so the second
|
||||
// word's twin is dropped here before emission.
|
||||
func (img *Image) GOObjectAARCH64(pkgPath, srcPath string) ([]byte, error) {
|
||||
pre, err := toolchainObjectPreambleAARCH64()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return img.emitGOObject(pkgPath, srcPath, pre, 4, func(r Reloc) (uint16, uint8) {
|
||||
coalesced := *img
|
||||
coalesced.Funcs = append([]FuncLayout(nil), img.Funcs...)
|
||||
for i := range coalesced.Funcs {
|
||||
rs := coalesced.Funcs[i].Relocs
|
||||
var keep []Reloc
|
||||
for j := 0; j < len(rs); j++ {
|
||||
keep = append(keep, rs[j])
|
||||
if rs[j].Kind == RelArm64Addr && j+1 < len(rs) &&
|
||||
rs[j+1].Kind == RelArm64Addr && rs[j+1].Off == rs[j].Off+4 {
|
||||
j++ // the ADD word's twin: the Siz-8 pair reloc covers it
|
||||
}
|
||||
}
|
||||
coalesced.Funcs[i].Relocs = keep
|
||||
}
|
||||
return coalesced.emitGOObject(pkgPath, srcPath, pre, 4, func(r Reloc) (uint16, uint8) {
|
||||
switch r.Kind {
|
||||
case RelArm64Branch:
|
||||
return relocArm64Branch, 4
|
||||
case RelArm64LDST64:
|
||||
return relocArm64LDST64, 4
|
||||
return relocArm64LDST64, 8
|
||||
default:
|
||||
return relocArm64Addr, 4
|
||||
return relocArm64Addr, 8
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user