OutputFile = flag.String("o", "", "output file; default foo.6 for /a/b/c/foo.s on amd64")
PrintOut = flag.Bool("S", false, "print assembly and machine code")
TrimPath = flag.String("trimpath", "", "remove prefix from recorded source file paths")
+ Shared = flag.Bool("shared", false, "generate code that can be linked into a shared library")
)
var (
obj.Flagcount("wb", "enable write barrier", &use_writebarrier)
obj.Flagcount("x", "debug lexer", &Debug['x'])
obj.Flagcount("y", "debug declarations in canned imports (with -d)", &Debug['y'])
+ var flag_shared int
if Thearch.Thechar == '6' {
obj.Flagcount("largemodel", "generate code that assumes a large memory model", &flag_largemodel)
+ obj.Flagcount("shared", "generate code that can be linked into a shared library", &flag_shared)
}
obj.Flagstr("cpuprofile", "file: write cpu profile to file", &cpuprofile)
obj.Flagstr("memprofile", "file: write memory profile to file", &memprofile)
obj.Flagparse(usage)
+ Ctxt.Flag_shared = int32(flag_shared)
Ctxt.Debugasm = int32(Debug['S'])
Ctxt.Debugvlog = int32(Debug['v'])
case REG_GS:
return 0x65
- // NOTE: Systems listed here should be only systems that
+ // NOTE: Systems listed here should be only systems that
// support direct TLS references like 8(TLS) implemented as
// direct references from FS or GS. Systems that require
// the initial-exec model, where you load the TLS base into
default:
log.Fatalf("unknown TLS base register for %s", obj.Headstr(ctxt.Headtype))
+ case obj.Hlinux:
+ if ctxt.Flag_shared != 0 {
+ log.Fatalf("unknown TLS base register for linux with -shared")
+ } else {
+ return 0x64 // FS
+ }
+
case obj.Hdragonfly,
obj.Hfreebsd,
- obj.Hlinux,
obj.Hnetbsd,
obj.Hopenbsd,
obj.Hsolaris:
case REG_ES:
return 0x26
+ case REG_TLS:
+ if ctxt.Flag_shared != 0 {
+ // When building for inclusion into a shared library, an instruction of the form
+ // MOV 0(CX)(TLS*1), AX
+ // becomes
+ // mov %fs:(%rcx), %rax
+ // which assumes that the correct TLS offset has been loaded into %rcx (today
+ // there is only one TLS variable -- g -- so this is OK). When not building for
+ // a shared library the instruction does not require a prefix.
+ if a.Offset != 0 {
+ log.Fatalf("cannot handle non-0 offsets to TLS")
+ }
+ return 0x64
+ }
+
case REG_FS:
return 0x64
}
if REG_AX <= base && base <= REG_R15 {
- if a.Index == REG_TLS {
+ if a.Index == REG_TLS && ctxt.Flag_shared == 0 {
rel = obj.Reloc{}
rel.Type = obj.R_TLS_IE
rel.Siz = 4
}
}
- // NOTE: The systems listed here are the ones that use the "TLS initial exec" model,
+ // NOTE: The systems listed here are the ones that use the "TLS initial exec" model,
// where you load the TLS base register into a register and then index off that
// register to access the actual TLS variables. Systems that allow direct TLS access
// are handled in prefixof above and should not be listed here.