func main() { log.SetFlags(0) log.SetPrefix("asm: ") GOARCH := obj.Getgoarch() architecture := arch.Set(GOARCH) if architecture == nil { log.Fatalf("asm: unrecognized architecture %s", GOARCH) } flags.Parse() // Create object file, write header. fd, err := os.Create(*flags.OutputFile) if err != nil { log.Fatal(err) } ctxt := obj.Linknew(architecture.LinkArch) if *flags.PrintOut { ctxt.Debugasm = 1 } ctxt.LineHist.TrimPathPrefix = *flags.TrimPath ctxt.Flag_dynlink = *flags.Dynlink if *flags.Shared || *flags.Dynlink { ctxt.Flag_shared = 1 } ctxt.Bso = obj.Binitw(os.Stdout) defer ctxt.Bso.Flush() output := obj.Binitw(fd) fmt.Fprintf(output, "go object %s %s %s\n", obj.Getgoos(), obj.Getgoarch(), obj.Getgoversion()) fmt.Fprintf(output, "!\n") lexer := lex.NewLexer(flag.Arg(0), ctxt) parser := asm.NewParser(ctxt, architecture, lexer) diag := false ctxt.DiagFunc = func(format string, args ...interface{}) { diag = true log.Printf(format, args...) } pList := obj.Linknewplist(ctxt) var ok bool pList.Firstpc, ok = parser.Parse() if ok { // reports errors to parser.Errorf obj.Writeobjdirect(ctxt, output) } if !ok || diag { log.Printf("asm: assembly of %s failed", flag.Arg(0)) os.Remove(*flags.OutputFile) os.Exit(1) } output.Flush() }
func linkarchinit() { ld.Thestring = obj.Getgoarch() ld.Thelinkarch = &ld.Linkarm64 ld.Thearch.Thechar = thechar ld.Thearch.Ptrsize = ld.Thelinkarch.Ptrsize ld.Thearch.Intsize = ld.Thelinkarch.Ptrsize ld.Thearch.Regsize = ld.Thelinkarch.Regsize ld.Thearch.Funcalign = FuncAlign ld.Thearch.Maxalign = MaxAlign ld.Thearch.Minlc = MINLC ld.Thearch.Dwarfregsp = DWARFREGSP ld.Thearch.Dwarfreglr = DWARFREGLR ld.Thearch.Adddynrel = adddynrel ld.Thearch.Archinit = archinit ld.Thearch.Archreloc = archreloc ld.Thearch.Archrelocvariant = archrelocvariant ld.Thearch.Asmb = asmb ld.Thearch.Elfreloc1 = elfreloc1 ld.Thearch.Elfsetupplt = elfsetupplt ld.Thearch.Gentext = gentext ld.Thearch.Machoreloc1 = machoreloc1 ld.Thearch.Lput = ld.Lputl ld.Thearch.Wput = ld.Wputl ld.Thearch.Vput = ld.Vputl ld.Thearch.Linuxdynld = "/lib/ld-linux-aarch64.so.1" ld.Thearch.Freebsddynld = "XXX" ld.Thearch.Openbsddynld = "XXX" ld.Thearch.Netbsddynld = "XXX" ld.Thearch.Dragonflydynld = "XXX" ld.Thearch.Solarisdynld = "XXX" }
func linkarchinit() { if obj.Getgoarch() == "amd64p32" { thelinkarch = &x86.Linkamd64p32 gc.Thearch.Thelinkarch = thelinkarch thestring = "amd64p32" gc.Thearch.Thestring = "amd64p32" } }
func main() { switch obj.Getgoarch() { default: fmt.Fprintf(os.Stderr, "link: unknown architecture %q\n", obj.Getgoarch()) os.Exit(2) case "386": x86.Main() case "amd64", "amd64p32": amd64.Main() case "arm": arm.Main() case "arm64": arm64.Main() case "mips64", "mips64le": mips64.Main() case "ppc64", "ppc64le": ppc64.Main() } }
func linkarchinit() { thestring = obj.Getgoarch() gc.Thearch.Thestring = thestring if thestring == "mips64le" { thelinkarch = &mips.Linkmips64le } else { thelinkarch = &mips.Linkmips64 } gc.Thearch.Thelinkarch = thelinkarch }
func linkarchinit() { thestring = obj.Getgoarch() gc.Thearch.Thestring = thestring if thestring == "ppc64le" { thelinkarch = &ppc64.Linkppc64le } else { thelinkarch = &ppc64.Linkppc64 } gc.Thearch.Thelinkarch = thelinkarch }
func main() { // disable timestamps for reproducible output log.SetFlags(0) log.SetPrefix("compile: ") switch obj.Getgoarch() { default: fmt.Fprintf(os.Stderr, "compile: unknown architecture %q\n", obj.Getgoarch()) os.Exit(2) case "386": x86.Main() case "amd64", "amd64p32": amd64.Main() case "arm": arm.Main() case "arm64": arm64.Main() case "mips64", "mips64le": mips64.Main() case "ppc64", "ppc64le": ppc64.Main() } }
func linkarchinit() { ld.Thestring = obj.Getgoarch() if ld.Thestring == "ppc64le" { ld.Thelinkarch = &ld.Linkppc64le } else { ld.Thelinkarch = &ld.Linkppc64 } ld.Thearch.Thechar = thechar ld.Thearch.Ptrsize = ld.Thelinkarch.Ptrsize ld.Thearch.Intsize = ld.Thelinkarch.Ptrsize ld.Thearch.Regsize = ld.Thelinkarch.Regsize ld.Thearch.Funcalign = FuncAlign ld.Thearch.Maxalign = MaxAlign ld.Thearch.Minlc = MINLC ld.Thearch.Dwarfregsp = DWARFREGSP ld.Thearch.Dwarfreglr = DWARFREGLR ld.Thearch.Adddynrel = adddynrel ld.Thearch.Archinit = archinit ld.Thearch.Archreloc = archreloc ld.Thearch.Archrelocvariant = archrelocvariant ld.Thearch.Asmb = asmb ld.Thearch.Elfreloc1 = elfreloc1 ld.Thearch.Elfsetupplt = elfsetupplt ld.Thearch.Gentext = gentext ld.Thearch.Machoreloc1 = machoreloc1 if ld.Thelinkarch == &ld.Linkppc64le { ld.Thearch.Lput = ld.Lputl ld.Thearch.Wput = ld.Wputl ld.Thearch.Vput = ld.Vputl } else { ld.Thearch.Lput = ld.Lputb ld.Thearch.Wput = ld.Wputb ld.Thearch.Vput = ld.Vputb } // TODO(austin): ABI v1 uses /usr/lib/ld.so.1 ld.Thearch.Linuxdynld = "/lib64/ld64.so.1" ld.Thearch.Freebsddynld = "XXX" ld.Thearch.Openbsddynld = "XXX" ld.Thearch.Netbsddynld = "XXX" ld.Thearch.Dragonflydynld = "XXX" ld.Thearch.Solarisdynld = "XXX" }
func betypeinit() { gc.Widthptr = 8 gc.Widthint = 8 gc.Widthreg = 8 if obj.Getgoarch() == "amd64p32" { gc.Widthptr = 4 gc.Widthint = 4 addptr = x86.AADDL movptr = x86.AMOVL leaptr = x86.ALEAL cmpptr = x86.ACMPL typedefs[0].Sameas = gc.TINT32 typedefs[1].Sameas = gc.TUINT32 typedefs[2].Sameas = gc.TUINT32 } if gc.Ctxt.Flag_dynlink { gc.Thearch.ReservedRegs = append(gc.Thearch.ReservedRegs, x86.REG_R15) } }
func linkarchinit() { ld.Thestring = "amd64" ld.Thelinkarch = &ld.Linkamd64 if obj.Getgoarch() == "amd64p32" { ld.Thelinkarch = &ld.Linkamd64p32 } ld.Thearch.Thechar = thechar ld.Thearch.Ptrsize = ld.Thelinkarch.Ptrsize ld.Thearch.Intsize = ld.Thelinkarch.Ptrsize ld.Thearch.Regsize = ld.Thelinkarch.Regsize ld.Thearch.Funcalign = FuncAlign ld.Thearch.Maxalign = MaxAlign ld.Thearch.Minlc = MINLC ld.Thearch.Dwarfregsp = DWARFREGSP ld.Thearch.Dwarfreglr = DWARFREGLR ld.Thearch.Adddynrel = adddynrel ld.Thearch.Archinit = archinit ld.Thearch.Archreloc = archreloc ld.Thearch.Archrelocvariant = archrelocvariant ld.Thearch.Asmb = asmb ld.Thearch.Elfreloc1 = elfreloc1 ld.Thearch.Elfsetupplt = elfsetupplt ld.Thearch.Gentext = gentext ld.Thearch.Machoreloc1 = machoreloc1 ld.Thearch.PEreloc1 = pereloc1 ld.Thearch.Lput = ld.Lputl ld.Thearch.Wput = ld.Wputl ld.Thearch.Vput = ld.Vputl ld.Thearch.Linuxdynld = "/lib64/ld-linux-x86-64.so.2" ld.Thearch.Freebsddynld = "/libexec/ld-elf.so.1" ld.Thearch.Openbsddynld = "/usr/libexec/ld.so" ld.Thearch.Netbsddynld = "/libexec/ld.elf_so" ld.Thearch.Dragonflydynld = "/usr/libexec/ld-elf.so.2" ld.Thearch.Solarisdynld = "/lib/amd64/ld.so.1" }
func linknew(arch *LinkArch) *Link { ctxt := new(Link) ctxt.Hash = make(map[symVer]*LSym) ctxt.Arch = arch ctxt.Version = obj.HistVersion ctxt.Goroot = obj.Getgoroot() p := obj.Getgoarch() if p != arch.Name { log.Fatalf("invalid goarch %s (want %s)", p, arch.Name) } var buf string buf, _ = os.Getwd() if buf == "" { buf = "/???" } buf = filepath.ToSlash(buf) ctxt.Headtype = headtype(obj.Getgoos()) if ctxt.Headtype < 0 { log.Fatalf("unknown goos %s", obj.Getgoos()) } // Record thread-local storage offset. // TODO(rsc): Move tlsoffset back into the linker. switch ctxt.Headtype { default: log.Fatalf("unknown thread-local storage offset for %s", Headstr(ctxt.Headtype)) case obj.Hplan9, obj.Hwindows: break /* * ELF uses TLS offset negative from FS. * Translate 0(FS) and 8(FS) into -16(FS) and -8(FS). * Known to low-level assembly in package runtime and runtime/cgo. */ case obj.Hlinux, obj.Hfreebsd, obj.Hnetbsd, obj.Hopenbsd, obj.Hdragonfly, obj.Hsolaris: if obj.Getgoos() == "android" { switch ctxt.Arch.Thechar { case '6': // Android/amd64 constant - offset from 0(FS) to our TLS slot. // Explained in src/runtime/cgo/gcc_android_*.c ctxt.Tlsoffset = 0x1d0 case '8': // Android/386 constant - offset from 0(GS) to our TLS slot. ctxt.Tlsoffset = 0xf8 default: ctxt.Tlsoffset = -1 * ctxt.Arch.Ptrsize } } else { ctxt.Tlsoffset = -1 * ctxt.Arch.Ptrsize } case obj.Hnacl: switch ctxt.Arch.Thechar { default: log.Fatalf("unknown thread-local storage offset for nacl/%s", ctxt.Arch.Name) case '5': ctxt.Tlsoffset = 0 case '6': ctxt.Tlsoffset = 0 case '8': ctxt.Tlsoffset = -8 } /* * OS X system constants - offset from 0(GS) to our TLS. * Explained in src/runtime/cgo/gcc_darwin_*.c. */ case obj.Hdarwin: switch ctxt.Arch.Thechar { default: log.Fatalf("unknown thread-local storage offset for darwin/%s", ctxt.Arch.Name) case '5': ctxt.Tlsoffset = 0 // dummy value, not needed case '6': ctxt.Tlsoffset = 0x8a0 case '7': ctxt.Tlsoffset = 0 // dummy value, not needed case '8': ctxt.Tlsoffset = 0x468 } } // On arm, record goarm. if ctxt.Arch.Thechar == '5' { ctxt.Goarm = obj.Getgoarm() } return ctxt }
func dumpobj() { var err error bout, err = obj.Bopenw(outfile) if err != nil { Flusherrors() fmt.Printf("can't create %s: %v\n", outfile, err) errorexit() } startobj := int64(0) var arhdr [ArhdrSize]byte if writearchive != 0 { obj.Bwritestring(bout, "!<arch>\n") arhdr = [ArhdrSize]byte{} bout.Write(arhdr[:]) startobj = obj.Boffset(bout) } fmt.Fprintf(bout, "go object %s %s %s %s\n", obj.Getgoos(), obj.Getgoarch(), obj.Getgoversion(), obj.Expstring()) dumpexport() if writearchive != 0 { bout.Flush() size := obj.Boffset(bout) - startobj if size&1 != 0 { obj.Bputc(bout, 0) } obj.Bseek(bout, startobj-ArhdrSize, 0) formathdr(arhdr[:], "__.PKGDEF", size) bout.Write(arhdr[:]) bout.Flush() obj.Bseek(bout, startobj+size+(size&1), 0) arhdr = [ArhdrSize]byte{} bout.Write(arhdr[:]) startobj = obj.Boffset(bout) fmt.Fprintf(bout, "go object %s %s %s %s\n", obj.Getgoos(), obj.Getgoarch(), obj.Getgoversion(), obj.Expstring()) } if pragcgobuf != "" { if writearchive != 0 { // write empty export section; must be before cgo section fmt.Fprintf(bout, "\n$$\n\n$$\n\n") } fmt.Fprintf(bout, "\n$$ // cgo\n") fmt.Fprintf(bout, "%s\n$$\n\n", pragcgobuf) } fmt.Fprintf(bout, "\n!\n") externs := len(externdcl) dumpglobls() dumptypestructs() // Dump extra globals. tmp := externdcl if externdcl != nil { externdcl = externdcl[externs:] } dumpglobls() externdcl = tmp dumpdata() obj.Writeobjdirect(Ctxt, bout) if writearchive != 0 { bout.Flush() size := obj.Boffset(bout) - startobj if size&1 != 0 { obj.Bputc(bout, 0) } obj.Bseek(bout, startobj-ArhdrSize, 0) formathdr(arhdr[:], "_go_.o", size) bout.Write(arhdr[:]) } obj.Bterm(bout) }