var opindex [(ALAST + 1) & obj.AMask]*Optab
-// isextern reports whether s describes an external symbol that must avoid pc-relative addressing.
+// useAbs reports whether s describes a symbol that must avoid pc-relative addressing.
// This happens on systems like Solaris that call .so functions instead of system calls.
// It does not seem to be necessary for any other systems. This is probably working
// around a Solaris-specific bug that should be fixed differently, but we don't know
// what that bug is. And this does fix it.
-func isextern(s *obj.LSym) bool {
- // All the Solaris dynamic imports from libc.so begin with "libc_".
- return strings.HasPrefix(s.Name, "libc_")
+func useAbs(ctxt *obj.Link, s *obj.LSym) bool {
+ if ctxt.Headtype == objabi.Hsolaris {
+ // All the Solaris dynamic imports from libc.so begin with "libc_".
+ return strings.HasPrefix(s.Name, "libc_")
+ }
+ return ctxt.Arch.Family == sys.I386 && !ctxt.Flag_shared
}
// single-instruction no-ops of various lengths.
case obj.NAME_EXTERN,
obj.NAME_STATIC:
- if a.Sym != nil && isextern(a.Sym) || (ctxt.Arch.Family == sys.I386 && !ctxt.Flag_shared) {
+ if a.Sym != nil && useAbs(ctxt, a.Sym) {
return Yi32
}
return Yiauto // use pc-relative addressing
if a.Name == obj.NAME_GOTREF {
r.Siz = 4
r.Type = objabi.R_GOTPCREL
- } else if isextern(s) || (ctxt.Arch.Family != sys.AMD64 && !ctxt.Flag_shared) {
+ } else if useAbs(ctxt, s) {
r.Siz = 4
r.Type = objabi.R_ADDR
} else {
case obj.NAME_EXTERN,
obj.NAME_GOTREF,
obj.NAME_STATIC:
- if !isextern(a.Sym) && ctxt.Arch.Family == sys.AMD64 {
+ if !useAbs(ctxt, a.Sym) && ctxt.Arch.Family == sys.AMD64 {
goto bad
}
if ctxt.Arch.Family == sys.I386 && ctxt.Flag_shared {
asmbuf.rexflag |= regrex[base]&Rxb | rex
if base == REG_NONE || (REG_CS <= base && base <= REG_GS) || base == REG_TLS {
- if (a.Sym == nil || !isextern(a.Sym)) && base == REG_NONE && (a.Name == obj.NAME_STATIC || a.Name == obj.NAME_EXTERN || a.Name == obj.NAME_GOTREF) || ctxt.Arch.Family != sys.AMD64 {
+ if (a.Sym == nil || !useAbs(ctxt, a.Sym)) && base == REG_NONE && (a.Name == obj.NAME_STATIC || a.Name == obj.NAME_EXTERN || a.Name == obj.NAME_GOTREF) || ctxt.Arch.Family != sys.AMD64 {
if a.Name == obj.NAME_GOTREF && (a.Offset != 0 || a.Index != 0 || a.Scale != 0) {
ctxt.Diag("%v has offset against gotref", p)
}