// FIXME: It should be forbidden to have R_ADDR from a
// symbol which isn't in .data. However, as .text has the
// same address once loaded, this is possible.
+ // TODO: .text (including rodata) to .data relocation
+ // doesn't work correctly, so we should really disallow it.
+ // See also aixStaticDataBase in symtab.go and in runtime.
if ldr.SymSect(s).Seg == &Segdata {
Xcoffadddynrel(target, ldr, syms, s, r, ri)
}
// except go:buildid which is generated late and not used by the program.
addRef("go:buildid")
}
+ if ctxt.IsAIX() {
+ // On AIX, an R_ADDR relocation from an RODATA symbol to a DATA symbol
+ // does not work. See data.go:relocsym, case R_ADDR.
+ // Here we record the unrelocated address in aixStaticDataBase (it is
+ // unrelocated as it is in RODATA) so we can compute the delta at
+ // run time.
+ sb := ldr.CreateSymForUpdate("runtime.aixStaticDataBase", 0)
+ sb.SetSize(0)
+ sb.AddAddr(ctxt.Arch, ldr.Lookup("runtime.data", 0))
+ sb.SetType(sym.SRODATA)
+ }
// text section information
slice(textsectionmapSym, uint64(nsections))
// To make sure the map isn't collected, we keep a second reference here.
var pinnedTypemaps []map[typeOff]*_type
+// aixStaticDataBase (used only on AIX) holds the unrelocated address
+// of the data section, set by the linker.
+//
+// On AIX, an R_ADDR relocation from an RODATA symbol to a DATA symbol
+// does not work, as the dynamic loader can change the address of the
+// data section, and it is not possible to apply a dynamic relocation
+// to RODATA. In order to get the correct address, we need to apply
+// the delta between unrelocated and relocated data section addresses.
+// aixStaticDataBase is the unrelocated address, and moduledata.data is
+// the relocated one.
+var aixStaticDataBase uintptr // linker symbol
+
var firstmoduledata moduledata // linker symbol
var lastmoduledatap *moduledata // linker symbol
// in read-only memory currently.
addr := unsafe.Pointer(t.GCData)
+ if GOOS == "aix" {
+ addr = add(addr, firstmoduledata.data-aixStaticDataBase)
+ }
+
for {
p := (*byte)(atomic.Loadp(addr))
switch p {