mirror of
https://github.com/golang/go
synced 2024-11-24 11:00:08 -07:00
cmd/link: make ppc64le __glink_PLTresolve position-independent
This code is only generated when linking cgo internally with fixed position code. This feature of the internal linker is only supported on ppc64le/linux targets. This moves ppc64le/linux a little closer to supporting PIE when internal linking. This is more similar to the implementation suggested in the power architecture elfv2 supplement, and works with both PIE and static code. Change-Id: I0b64e1c22b9e07b5151378d2ab19ee0e50405fc5 Reviewed-on: https://go-review.googlesource.com/c/go/+/357332 Run-TryBot: Paul Murphy <murp@ibm.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
parent
fde4cc2a31
commit
732db407d3
@ -1067,35 +1067,31 @@ func ensureglinkresolver(ctxt *ld.Link, ldr *loader.Loader) *loader.SymbolBuilde
|
|||||||
return glink
|
return glink
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is essentially the resolver from the ppc64 ELF ABI.
|
// This is essentially the resolver from the ppc64 ELFv2 ABI.
|
||||||
// At entry, r12 holds the address of the symbol resolver stub
|
// At entry, r12 holds the address of the symbol resolver stub
|
||||||
// for the target routine and the argument registers hold the
|
// for the target routine and the argument registers hold the
|
||||||
// arguments for the target routine.
|
// arguments for the target routine.
|
||||||
//
|
//
|
||||||
|
// PC-rel offsets are computed once the final codesize of the
|
||||||
|
// resolver is known.
|
||||||
|
//
|
||||||
// This stub is PIC, so first get the PC of label 1 into r11.
|
// This stub is PIC, so first get the PC of label 1 into r11.
|
||||||
// Other things will be relative to this.
|
|
||||||
glink.AddUint32(ctxt.Arch, 0x7c0802a6) // mflr r0
|
glink.AddUint32(ctxt.Arch, 0x7c0802a6) // mflr r0
|
||||||
glink.AddUint32(ctxt.Arch, 0x429f0005) // bcl 20,31,1f
|
glink.AddUint32(ctxt.Arch, 0x429f0005) // bcl 20,31,1f
|
||||||
glink.AddUint32(ctxt.Arch, 0x7d6802a6) // 1: mflr r11
|
glink.AddUint32(ctxt.Arch, 0x7d6802a6) // 1: mflr r11
|
||||||
glink.AddUint32(ctxt.Arch, 0x7c0803a6) // mtlf r0
|
glink.AddUint32(ctxt.Arch, 0x7c0803a6) // mtlr r0
|
||||||
|
|
||||||
// Compute the .plt array index from the entry point address.
|
// Compute the .plt array index from the entry point address
|
||||||
// Because this is PIC, everything is relative to label 1b (in
|
// into r0. This is computed relative to label 1 above.
|
||||||
// r11):
|
glink.AddUint32(ctxt.Arch, 0x38000000) // li r0,-(res_0-1b)
|
||||||
// r0 = ((r12 - r11) - (res_0 - r11)) / 4 = (r12 - res_0) / 4
|
|
||||||
glink.AddUint32(ctxt.Arch, 0x3800ffd0) // li r0,-(res_0-1b)=-48
|
|
||||||
glink.AddUint32(ctxt.Arch, 0x7c006214) // add r0,r0,r12
|
glink.AddUint32(ctxt.Arch, 0x7c006214) // add r0,r0,r12
|
||||||
glink.AddUint32(ctxt.Arch, 0x7c0b0050) // sub r0,r0,r11
|
glink.AddUint32(ctxt.Arch, 0x7c0b0050) // sub r0,r0,r11
|
||||||
glink.AddUint32(ctxt.Arch, 0x7800f082) // srdi r0,r0,2
|
glink.AddUint32(ctxt.Arch, 0x7800f082) // srdi r0,r0,2
|
||||||
|
|
||||||
// r11 = address of the first byte of the PLT
|
// Load the PC-rel offset of ".plt - 1b", and add it to 1b.
|
||||||
r, _ := glink.AddRel(objabi.R_ADDRPOWER)
|
// This is stored after this stub and before the resolvers.
|
||||||
r.SetSym(ctxt.PLT)
|
glink.AddUint32(ctxt.Arch, 0xe98b0000) // ld r12,res_0-1b-8(r11)
|
||||||
r.SetSiz(8)
|
glink.AddUint32(ctxt.Arch, 0x7d6b6214) // add r11,r11,r12
|
||||||
r.SetOff(int32(glink.Size()))
|
|
||||||
r.SetAdd(0)
|
|
||||||
glink.AddUint32(ctxt.Arch, 0x3d600000) // addis r11,0,.plt@ha
|
|
||||||
glink.AddUint32(ctxt.Arch, 0x396b0000) // addi r11,r11,.plt@l
|
|
||||||
|
|
||||||
// Load r12 = dynamic resolver address and r11 = DSO
|
// Load r12 = dynamic resolver address and r11 = DSO
|
||||||
// identifier from the first two doublewords of the PLT.
|
// identifier from the first two doublewords of the PLT.
|
||||||
@ -1106,6 +1102,19 @@ func ensureglinkresolver(ctxt *ld.Link, ldr *loader.Loader) *loader.SymbolBuilde
|
|||||||
glink.AddUint32(ctxt.Arch, 0x7d8903a6) // mtctr r12
|
glink.AddUint32(ctxt.Arch, 0x7d8903a6) // mtctr r12
|
||||||
glink.AddUint32(ctxt.Arch, 0x4e800420) // bctr
|
glink.AddUint32(ctxt.Arch, 0x4e800420) // bctr
|
||||||
|
|
||||||
|
// Store the PC-rel offset to the PLT
|
||||||
|
r, _ := glink.AddRel(objabi.R_PCREL)
|
||||||
|
r.SetSym(ctxt.PLT)
|
||||||
|
r.SetSiz(8)
|
||||||
|
r.SetOff(int32(glink.Size()))
|
||||||
|
r.SetAdd(glink.Size()) // Adjust the offset to be relative to label 1 above.
|
||||||
|
glink.AddUint64(ctxt.Arch, 0) // The offset to the PLT.
|
||||||
|
|
||||||
|
// Resolve PC-rel offsets above now the final size of the stub is known.
|
||||||
|
res0m1b := glink.Size() - 8 // res_0 - 1b
|
||||||
|
glink.SetUint32(ctxt.Arch, 16, 0x38000000|uint32(uint16(-res0m1b)))
|
||||||
|
glink.SetUint32(ctxt.Arch, 32, 0xe98b0000|uint32(uint16(res0m1b-8)))
|
||||||
|
|
||||||
// The symbol resolvers must immediately follow.
|
// The symbol resolvers must immediately follow.
|
||||||
// res_0:
|
// res_0:
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user