From 428c349552759dc1e11965d1d483a4749818ec11 Mon Sep 17 00:00:00 2001 From: David Crawshaw Date: Fri, 9 Sep 2016 06:20:44 -0400 Subject: [PATCH] cmd/link, cmd/internal/obj: give Headtype a type Separate out windows/windowsgui properly so we are not encoding some of the Headtype value in a separate headstring global. Remove one of the two copies of the variable from cmd/link. Remove duplicate string to headtype list. Change-Id: Ifa20fb9652a1dc95161e154aac11f15ad0f709d0 Reviewed-on: https://go-review.googlesource.com/28853 Run-TryBot: David Crawshaw TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/cmd/internal/obj/link.go | 67 ++++++++++++- src/cmd/internal/obj/sym.go | 39 +------- src/cmd/internal/obj/x86/asm6.go | 12 +-- src/cmd/internal/obj/x86/obj6.go | 8 +- src/cmd/link/internal/amd64/asm.go | 35 +++---- src/cmd/link/internal/amd64/obj.go | 13 +-- src/cmd/link/internal/arm/asm.go | 10 +- src/cmd/link/internal/arm/obj.go | 8 +- src/cmd/link/internal/arm64/asm.go | 14 +-- src/cmd/link/internal/arm64/obj.go | 10 +- src/cmd/link/internal/ld/data.go | 48 +++++----- src/cmd/link/internal/ld/dwarf.go | 6 +- src/cmd/link/internal/ld/elf.go | 32 +++---- src/cmd/link/internal/ld/go.go | 8 +- src/cmd/link/internal/ld/lib.go | 53 ++++------- src/cmd/link/internal/ld/link.go | 1 - src/cmd/link/internal/ld/main.go | 115 ++--------------------- src/cmd/link/internal/ld/pe.go | 2 +- src/cmd/link/internal/ld/sym.go | 140 +++++++++++++++++++--------- src/cmd/link/internal/ld/symtab.go | 2 +- src/cmd/link/internal/mips64/asm.go | 6 +- src/cmd/link/internal/mips64/obj.go | 8 +- src/cmd/link/internal/ppc64/asm.go | 6 +- src/cmd/link/internal/ppc64/obj.go | 8 +- src/cmd/link/internal/s390x/asm.go | 2 +- src/cmd/link/internal/s390x/obj.go | 4 +- src/cmd/link/internal/x86/asm.go | 22 ++--- src/cmd/link/internal/x86/obj.go | 13 +-- 28 files changed, 328 insertions(+), 364 deletions(-) diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go index eaf33651d8..e3de1091fe 100644 --- a/src/cmd/internal/obj/link.go +++ b/src/cmd/internal/obj/link.go @@ -626,7 +626,7 @@ const ( // to be linker input or for reading that input into the linker. type Link struct { Goarm int32 - Headtype int + Headtype HeadType Arch *LinkArch Debugasm int32 Debugvlog int32 @@ -725,9 +725,11 @@ type LinkArch struct { UnaryDst map[As]bool // Instruction takes one operand, a destination. } -/* executable header types */ +// HeadType is the executable header type. +type HeadType uint8 + const ( - Hunknown = 0 + iota + Hunknown HeadType = iota Hdarwin Hdragonfly Hfreebsd @@ -738,8 +740,67 @@ const ( Hplan9 Hsolaris Hwindows + Hwindowsgui ) +func (h *HeadType) Set(s string) error { + switch s { + case "darwin": + *h = Hdarwin + case "dragonfly": + *h = Hdragonfly + case "freebsd": + *h = Hfreebsd + case "linux", "android": + *h = Hlinux + case "nacl": + *h = Hnacl + case "netbsd": + *h = Hnetbsd + case "openbsd": + *h = Hopenbsd + case "plan9": + *h = Hplan9 + case "solaris": + *h = Hsolaris + case "windows": + *h = Hwindows + case "windowsgui": + *h = Hwindowsgui + default: + return fmt.Errorf("invalid headtype: %q", s) + } + return nil +} + +func (h *HeadType) String() string { + switch *h { + case Hdarwin: + return "darwin" + case Hdragonfly: + return "dragonfly" + case Hfreebsd: + return "freebsd" + case Hlinux: + return "linux" + case Hnacl: + return "nacl" + case Hnetbsd: + return "netbsd" + case Hopenbsd: + return "openbsd" + case Hplan9: + return "plan9" + case Hsolaris: + return "solaris" + case Hwindows: + return "windows" + case Hwindowsgui: + return "windowsgui" + } + return fmt.Sprintf("HeadType(%d)", *h) +} + // AsmBuf is a simple buffer to assemble variable-length x86 instructions into. type AsmBuf struct { buf [100]byte diff --git a/src/cmd/internal/obj/sym.go b/src/cmd/internal/obj/sym.go index d5f08f8cc0..8aa2436085 100644 --- a/src/cmd/internal/obj/sym.go +++ b/src/cmd/internal/obj/sym.go @@ -36,45 +36,8 @@ import ( "log" "os" "path/filepath" - "strconv" ) -var headers = []struct { - name string - val int -}{ - {"darwin", Hdarwin}, - {"dragonfly", Hdragonfly}, - {"freebsd", Hfreebsd}, - {"linux", Hlinux}, - {"android", Hlinux}, // must be after "linux" entry or else headstr(Hlinux) == "android" - {"nacl", Hnacl}, - {"netbsd", Hnetbsd}, - {"openbsd", Hopenbsd}, - {"plan9", Hplan9}, - {"solaris", Hsolaris}, - {"windows", Hwindows}, - {"windowsgui", Hwindows}, -} - -func headtype(name string) int { - for i := 0; i < len(headers); i++ { - if name == headers[i].name { - return headers[i].val - } - } - return -1 -} - -func Headstr(v int) string { - for i := 0; i < len(headers); i++ { - if v == headers[i].val { - return headers[i].name - } - } - return strconv.Itoa(v) -} - func Linknew(arch *LinkArch) *Link { ctxt := new(Link) ctxt.Hash = make(map[SymVer]*LSym) @@ -95,7 +58,7 @@ func Linknew(arch *LinkArch) *Link { ctxt.LineHist.GOROOT_FINAL = ctxt.Goroot_final ctxt.LineHist.Dir = ctxt.Pathname - ctxt.Headtype = headtype(Getgoos()) + ctxt.Headtype.Set(Getgoos()) if ctxt.Headtype < 0 { log.Fatalf("unknown goos %s", Getgoos()) } diff --git a/src/cmd/internal/obj/x86/asm6.go b/src/cmd/internal/obj/x86/asm6.go index e9d84650f2..13bee85b35 100644 --- a/src/cmd/internal/obj/x86/asm6.go +++ b/src/cmd/internal/obj/x86/asm6.go @@ -2188,7 +2188,7 @@ func prefixof(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int { if isAndroid { return 0x65 // GS } - log.Fatalf("unknown TLS base register for %s", obj.Headstr(ctxt.Headtype)) + log.Fatalf("unknown TLS base register for %s", ctxt.Headtype) case obj.Hdarwin, obj.Hdragonfly, @@ -2201,7 +2201,7 @@ func prefixof(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int { switch ctxt.Headtype { default: - log.Fatalf("unknown TLS base register for %s", obj.Headstr(ctxt.Headtype)) + log.Fatalf("unknown TLS base register for %s", ctxt.Headtype) case obj.Hlinux: if isAndroid { @@ -4016,7 +4016,7 @@ func doasm(ctxt *obj.Link, p *obj.Prog) { // are handled in prefixof above and should not be listed here. switch ctxt.Headtype { default: - log.Fatalf("unknown TLS base location for %s", obj.Headstr(ctxt.Headtype)) + log.Fatalf("unknown TLS base location for %s", ctxt.Headtype) case obj.Hlinux, obj.Hnacl: @@ -4074,7 +4074,7 @@ func doasm(ctxt *obj.Link, p *obj.Prog) { ctxt.AsmBuf.Put1(0x8B) asmand(ctxt, p, &pp.From, &p.To) - case obj.Hwindows: + case obj.Hwindows, obj.Hwindowsgui: // Windows TLS base is always 0x14(FS). pp.From = p.From @@ -4092,7 +4092,7 @@ func doasm(ctxt *obj.Link, p *obj.Prog) { switch ctxt.Headtype { default: - log.Fatalf("unknown TLS base location for %s", obj.Headstr(ctxt.Headtype)) + log.Fatalf("unknown TLS base location for %s", ctxt.Headtype) case obj.Hlinux: if !ctxt.Flag_shared { @@ -4146,7 +4146,7 @@ func doasm(ctxt *obj.Link, p *obj.Prog) { 0x8B) asmand(ctxt, p, &pp.From, &p.To) - case obj.Hwindows: + case obj.Hwindows, obj.Hwindowsgui: // Windows TLS base is always 0x28(GS). pp.From = p.From diff --git a/src/cmd/internal/obj/x86/obj6.go b/src/cmd/internal/obj/x86/obj6.go index 5cd06c093f..7738d79b1b 100644 --- a/src/cmd/internal/obj/x86/obj6.go +++ b/src/cmd/internal/obj/x86/obj6.go @@ -55,7 +55,8 @@ func CanUse1InsnTLS(ctxt *obj.Link) bool { case obj.Hlinux, obj.Hnacl, obj.Hplan9, - obj.Hwindows: + obj.Hwindows, + obj.Hwindowsgui: return false } @@ -63,8 +64,7 @@ func CanUse1InsnTLS(ctxt *obj.Link) bool { } switch ctxt.Headtype { - case obj.Hplan9, - obj.Hwindows: + case obj.Hplan9, obj.Hwindows, obj.Hwindowsgui: return false case obj.Hlinux: return !ctxt.Flag_shared @@ -181,7 +181,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { } // TODO: Remove. - if ctxt.Headtype == obj.Hwindows && p.Mode == 64 || ctxt.Headtype == obj.Hplan9 { + if (ctxt.Headtype == obj.Hwindows || ctxt.Headtype == obj.Hwindowsgui) && p.Mode == 64 || ctxt.Headtype == obj.Hplan9 { if p.From.Scale == 1 && p.From.Index == REG_TLS { p.From.Scale = 2 } diff --git a/src/cmd/link/internal/amd64/asm.go b/src/cmd/link/internal/amd64/asm.go index 69a3f50d61..639aae9fe7 100644 --- a/src/cmd/link/internal/amd64/asm.go +++ b/src/cmd/link/internal/amd64/asm.go @@ -227,7 +227,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) { switch r.Type { case obj.R_CALL, obj.R_PCREL: - if ld.HEADTYPE == obj.Hwindows { + if ld.Headtype == obj.Hwindows || ld.Headtype == obj.Hwindowsgui { // nothing to do, the relocation will be laid out in pereloc1 return } else { @@ -240,7 +240,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) { case obj.R_ADDR: if s.Type == obj.STEXT && ld.Iself { - if ld.HEADTYPE == obj.Hsolaris { + if ld.Headtype == obj.Hsolaris { addpltsym(ctxt, targ) r.Sym = ld.Linklookup(ctxt, ".plt", 0) r.Add += int64(targ.Plt) @@ -273,7 +273,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) { return } - if ld.HEADTYPE == obj.Hdarwin && s.Size == int64(ld.SysArch.PtrSize) && r.Off == 0 { + if ld.Headtype == obj.Hdarwin && s.Size == int64(ld.SysArch.PtrSize) && r.Off == 0 { // Mach-O relocations are a royal pain to lay out. // They use a compact stateful bytecode representation // that is too much bother to deal with. @@ -298,7 +298,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) { return } - if ld.HEADTYPE == obj.Hwindows { + if ld.Headtype == obj.Hwindows || ld.Headtype == obj.Hwindowsgui { // nothing to do, the relocation will be laid out in pereloc1 return } @@ -548,7 +548,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) { ld.Adduint64(ctxt, rela, 0) s.Plt = int32(plt.Size - 16) - } else if ld.HEADTYPE == obj.Hdarwin { + } else if ld.Headtype == obj.Hdarwin { // To do lazy symbol lookup right, we're supposed // to tell the dynamic loader which library each // symbol comes from and format the link info @@ -590,7 +590,7 @@ func addgotsym(ctxt *ld.Link, s *ld.Symbol) { ld.Addaddrplus(ctxt, rela, got, int64(s.Got)) ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_X86_64_GLOB_DAT)) ld.Adduint64(ctxt, rela, 0) - } else if ld.HEADTYPE == obj.Hdarwin { + } else if ld.Headtype == obj.Hdarwin { ld.Adduint32(ctxt, ld.Linklookup(ctxt, ".linkedit.got", 0), uint32(s.Dynid)) } else { ctxt.Diag("addgotsym: unsupported binary format") @@ -639,13 +639,13 @@ func asmb(ctxt *ld.Link) { ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen)) machlink := int64(0) - if ld.HEADTYPE == obj.Hdarwin { + if ld.Headtype == obj.Hdarwin { machlink = ld.Domacholink(ctxt) } - switch ld.HEADTYPE { + switch ld.Headtype { default: - ctxt.Diag("unknown header type %d", ld.HEADTYPE) + ctxt.Diag("unknown header type %d", ld.Headtype) fallthrough case obj.Hplan9: @@ -663,7 +663,8 @@ func asmb(ctxt *ld.Link) { ld.Flag8 = true /* 64-bit addresses */ case obj.Hnacl, - obj.Hwindows: + obj.Hwindows, + obj.Hwindowsgui: break } @@ -675,7 +676,7 @@ func asmb(ctxt *ld.Link) { if ctxt.Debugvlog != 0 { ctxt.Logf("%5.2f sym\n", obj.Cputime()) } - switch ld.HEADTYPE { + switch ld.Headtype { default: case obj.Hplan9: *ld.FlagS = true @@ -694,13 +695,14 @@ func asmb(ctxt *ld.Link) { symo = int64(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen) symo = ld.Rnd(symo, int64(*ld.FlagRound)) - case obj.Hwindows: + case obj.Hwindows, + obj.Hwindowsgui: symo = int64(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen) symo = ld.Rnd(symo, ld.PEFILEALIGN) } ld.Cseek(symo) - switch ld.HEADTYPE { + switch ld.Headtype { default: if ld.Iself { ld.Cseek(symo) @@ -731,7 +733,7 @@ func asmb(ctxt *ld.Link) { ld.Cflush() } - case obj.Hwindows: + case obj.Hwindows, obj.Hwindowsgui: if ctxt.Debugvlog != 0 { ctxt.Logf("%5.2f dwarf\n", obj.Cputime()) } @@ -747,7 +749,7 @@ func asmb(ctxt *ld.Link) { ctxt.Logf("%5.2f headr\n", obj.Cputime()) } ld.Cseek(0) - switch ld.HEADTYPE { + switch ld.Headtype { default: case obj.Hplan9: /* plan9 */ magic := int32(4*26*26 + 7) @@ -776,7 +778,8 @@ func asmb(ctxt *ld.Link) { obj.Hnacl: ld.Asmbelf(ctxt, symo) - case obj.Hwindows: + case obj.Hwindows, + obj.Hwindowsgui: ld.Asmbpe(ctxt) } diff --git a/src/cmd/link/internal/amd64/obj.go b/src/cmd/link/internal/amd64/obj.go index 8a3bb1361e..384de89841 100644 --- a/src/cmd/link/internal/amd64/obj.go +++ b/src/cmd/link/internal/amd64/obj.go @@ -93,13 +93,13 @@ func archinit(ctxt *ld.Link) { ld.Linkmode = ld.LinkExternal } - switch ld.HEADTYPE { + switch ld.Headtype { default: if ld.Linkmode == ld.LinkAuto { ld.Linkmode = ld.LinkInternal } if ld.Linkmode == ld.LinkExternal && obj.Getgoextlinkenabled() != "1" { - log.Fatalf("cannot use -linkmode=external with -H %s", ld.Headstr(int(ld.HEADTYPE))) + log.Fatalf("cannot use -linkmode=external with -H %s", ld.Headtype) } case obj.Hdarwin, @@ -110,13 +110,14 @@ func archinit(ctxt *ld.Link) { obj.Hnetbsd, obj.Hopenbsd, obj.Hsolaris, - obj.Hwindows: + obj.Hwindows, + obj.Hwindowsgui: break } - switch ld.HEADTYPE { + switch ld.Headtype { default: - ld.Exitf("unknown -H option: %v", ld.HEADTYPE) + ld.Exitf("unknown -H option: %v", ld.Headtype) case obj.Hplan9: /* plan 9 */ ld.HEADR = 32 + 8 @@ -179,7 +180,7 @@ func archinit(ctxt *ld.Link) { *ld.FlagRound = 0x10000 } - case obj.Hwindows: /* PE executable */ + case obj.Hwindows, obj.Hwindowsgui: /* PE executable */ ld.Peinit(ctxt) ld.HEADR = ld.PEFILEHEADR diff --git a/src/cmd/link/internal/arm/asm.go b/src/cmd/link/internal/arm/asm.go index 8a2aa99f4e..881b559e68 100644 --- a/src/cmd/link/internal/arm/asm.go +++ b/src/cmd/link/internal/arm/asm.go @@ -439,7 +439,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int { // the section load address. // we need to compensate that by removing the instruction's address // from addend. - if ld.HEADTYPE == obj.Hdarwin { + if ld.Headtype == obj.Hdarwin { r.Xadd -= ld.Symaddr(ctxt, s) + int64(r.Off) } @@ -618,7 +618,7 @@ func asmb(ctxt *ld.Link) { ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen)) machlink := uint32(0) - if ld.HEADTYPE == obj.Hdarwin { + if ld.Headtype == obj.Hdarwin { machlink = uint32(ld.Domacholink(ctxt)) } @@ -632,7 +632,7 @@ func asmb(ctxt *ld.Link) { if ctxt.Debugvlog != 0 { ctxt.Logf("%5.2f sym\n", obj.Cputime()) } - switch ld.HEADTYPE { + switch ld.Headtype { default: if ld.Iself { symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen) @@ -647,7 +647,7 @@ func asmb(ctxt *ld.Link) { } ld.Cseek(int64(symo)) - switch ld.HEADTYPE { + switch ld.Headtype { default: if ld.Iself { if ctxt.Debugvlog != 0 { @@ -688,7 +688,7 @@ func asmb(ctxt *ld.Link) { ctxt.Logf("%5.2f header\n", obj.Cputime()) } ld.Cseek(0) - switch ld.HEADTYPE { + switch ld.Headtype { default: case obj.Hplan9: /* plan 9 */ ld.Lputb(0x647) /* magic */ diff --git a/src/cmd/link/internal/arm/obj.go b/src/cmd/link/internal/arm/obj.go index 64c88934f1..8e2802ff2d 100644 --- a/src/cmd/link/internal/arm/obj.go +++ b/src/cmd/link/internal/arm/obj.go @@ -89,13 +89,13 @@ func archinit(ctxt *ld.Link) { ld.Linkmode = ld.LinkExternal } - switch ld.HEADTYPE { + switch ld.Headtype { default: if ld.Linkmode == ld.LinkAuto { ld.Linkmode = ld.LinkInternal } if ld.Linkmode == ld.LinkExternal && obj.Getgoextlinkenabled() != "1" { - log.Fatalf("cannot use -linkmode=external with -H %s", ld.Headstr(int(ld.HEADTYPE))) + log.Fatalf("cannot use -linkmode=external with -H %s", ld.Headtype) } case obj.Hlinux, @@ -105,9 +105,9 @@ func archinit(ctxt *ld.Link) { break } - switch ld.HEADTYPE { + switch ld.Headtype { default: - ld.Exitf("unknown -H option: %v", ld.HEADTYPE) + ld.Exitf("unknown -H option: %v", ld.Headtype) case obj.Hplan9: /* plan 9 */ ld.HEADR = 32 diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go index fa3050b74b..70a6cfd1fa 100644 --- a/src/cmd/link/internal/arm64/asm.go +++ b/src/cmd/link/internal/arm64/asm.go @@ -284,7 +284,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int { // the BR26 relocation should be fully resolved at link time. // That is the reason why the next if block is disabled. When the bug in ld64 // is fixed, we can enable this block and also enable duff's device in cmd/7g. - if false && ld.HEADTYPE == obj.Hdarwin { + if false && ld.Headtype == obj.Hdarwin { var o0, o1 uint32 if ctxt.Arch.ByteOrder == binary.BigEndian { @@ -361,8 +361,8 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int { case obj.R_ARM64_TLS_LE: r.Done = 0 - if ld.HEADTYPE != obj.Hlinux { - ctxt.Diag("TLS reloc on unsupported OS %s", ld.Headstr(int(ld.HEADTYPE))) + if ld.Headtype != obj.Hlinux { + ctxt.Diag("TLS reloc on unsupported OS %s", ld.Headtype) } // The TCB is two pointers. This is not documented anywhere, but is // de facto part of the ABI. @@ -427,7 +427,7 @@ func asmb(ctxt *ld.Link) { ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen)) machlink := uint32(0) - if ld.HEADTYPE == obj.Hdarwin { + if ld.Headtype == obj.Hdarwin { machlink = uint32(ld.Domacholink(ctxt)) } @@ -441,7 +441,7 @@ func asmb(ctxt *ld.Link) { if ctxt.Debugvlog != 0 { ctxt.Logf("%5.2f sym\n", obj.Cputime()) } - switch ld.HEADTYPE { + switch ld.Headtype { default: if ld.Iself { symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen) @@ -456,7 +456,7 @@ func asmb(ctxt *ld.Link) { } ld.Cseek(int64(symo)) - switch ld.HEADTYPE { + switch ld.Headtype { default: if ld.Iself { if ctxt.Debugvlog != 0 { @@ -497,7 +497,7 @@ func asmb(ctxt *ld.Link) { ctxt.Logf("%5.2f header\n", obj.Cputime()) } ld.Cseek(0) - switch ld.HEADTYPE { + switch ld.Headtype { default: case obj.Hplan9: /* plan 9 */ ld.Thearch.Lput(0x647) /* magic */ diff --git a/src/cmd/link/internal/arm64/obj.go b/src/cmd/link/internal/arm64/obj.go index 18147a2923..a20ad5a65f 100644 --- a/src/cmd/link/internal/arm64/obj.go +++ b/src/cmd/link/internal/arm64/obj.go @@ -87,17 +87,17 @@ func archinit(ctxt *ld.Link) { } // Darwin/arm64 only supports external linking - if ld.HEADTYPE == obj.Hdarwin { + if ld.Headtype == obj.Hdarwin { ld.Linkmode = ld.LinkExternal } - switch ld.HEADTYPE { + switch ld.Headtype { default: if ld.Linkmode == ld.LinkAuto { ld.Linkmode = ld.LinkInternal } if ld.Linkmode == ld.LinkExternal && obj.Getgoextlinkenabled() != "1" { - log.Fatalf("cannot use -linkmode=external with -H %s", ld.Headstr(int(ld.HEADTYPE))) + log.Fatalf("cannot use -linkmode=external with -H %s", ld.Headtype) } case obj.Hlinux, obj.Hdarwin: break @@ -107,9 +107,9 @@ func archinit(ctxt *ld.Link) { ld.Linkmode = ld.LinkExternal } - switch ld.HEADTYPE { + switch ld.Headtype { default: - ld.Exitf("unknown -H option: %v", ld.HEADTYPE) + ld.Exitf("unknown -H option: %v", ld.Headtype) case obj.Hplan9: /* plan 9 */ ld.HEADR = 32 diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index ba36210c61..da2ca358f7 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -360,7 +360,7 @@ func relocsym(ctxt *Link, s *Symbol) { // We need to be able to reference dynimport symbols when linking against // shared libraries, and Solaris needs it always - if HEADTYPE != obj.Hsolaris && r.Sym != nil && r.Sym.Type == obj.SDYNIMPORT && !ctxt.DynlinkingGo() { + if Headtype != obj.Hsolaris && r.Sym != nil && r.Sym.Type == obj.SDYNIMPORT && !ctxt.DynlinkingGo() { if !(SysArch.Family == sys.PPC64 && Linkmode == LinkExternal && r.Sym.Name == ".TOC.") { ctxt.Diag("unhandled relocation for %s (type %d rtype %d)", r.Sym.Name, r.Sym.Type, r.Type) } @@ -401,7 +401,7 @@ func relocsym(ctxt *Link, s *Symbol) { case obj.R_TLS_LE: isAndroidX86 := goos == "android" && (SysArch.InFamily(sys.AMD64, sys.I386)) - if Linkmode == LinkExternal && Iself && HEADTYPE != obj.Hopenbsd && !isAndroidX86 { + if Linkmode == LinkExternal && Iself && Headtype != obj.Hopenbsd && !isAndroidX86 { r.Done = 0 if r.Sym == nil { r.Sym = ctxt.Tlsg @@ -424,18 +424,18 @@ func relocsym(ctxt *Link, s *Symbol) { // related to the fact that our own TLS storage happens // to take up 8 bytes. o = 8 + r.Sym.Value - } else if Iself || ctxt.Headtype == obj.Hplan9 || ctxt.Headtype == obj.Hdarwin || isAndroidX86 { + } else if Iself || Headtype == obj.Hplan9 || Headtype == obj.Hdarwin || isAndroidX86 { o = int64(ctxt.Tlsoffset) + r.Add - } else if ctxt.Headtype == obj.Hwindows { + } else if Headtype == obj.Hwindows || Headtype == obj.Hwindowsgui { o = r.Add } else { - log.Fatalf("unexpected R_TLS_LE relocation for %s", Headstr(ctxt.Headtype)) + log.Fatalf("unexpected R_TLS_LE relocation for %s", Headtype) } case obj.R_TLS_IE: isAndroidX86 := goos == "android" && (SysArch.InFamily(sys.AMD64, sys.I386)) - if Linkmode == LinkExternal && Iself && HEADTYPE != obj.Hopenbsd && !isAndroidX86 { + if Linkmode == LinkExternal && Iself && Headtype != obj.Hopenbsd && !isAndroidX86 { r.Done = 0 if r.Sym == nil { r.Sym = ctxt.Tlsg @@ -473,7 +473,7 @@ func relocsym(ctxt *Link, s *Symbol) { if SysArch.Family == sys.AMD64 { o = 0 } - } else if HEADTYPE == obj.Hdarwin { + } else if Headtype == obj.Hdarwin { // ld64 for arm64 has a bug where if the address pointed to by o exists in the // symbol table (dynid >= 0), or is inside a symbol that exists in the symbol // table, then it will add o twice into the relocated value. @@ -487,10 +487,10 @@ func relocsym(ctxt *Link, s *Symbol) { o += Symaddr(ctxt, rs) } } - } else if HEADTYPE == obj.Hwindows { + } else if Headtype == obj.Hwindows || Headtype == obj.Hwindowsgui { // nothing to do } else { - ctxt.Diag("unhandled pcrel relocation for %s", headstring) + ctxt.Diag("unhandled pcrel relocation for %s", Headtype) } break @@ -555,7 +555,7 @@ func relocsym(ctxt *Link, s *Symbol) { if SysArch.Family == sys.AMD64 { o = 0 } - } else if HEADTYPE == obj.Hdarwin { + } else if Headtype == obj.Hdarwin { if r.Type == obj.R_CALL { if rs.Type != obj.SHOSTOBJ { o += int64(uint64(Symaddr(ctxt, rs)) - rs.Sect.Vaddr) @@ -567,7 +567,7 @@ func relocsym(ctxt *Link, s *Symbol) { } else { o += int64(r.Siz) } - } else if HEADTYPE == obj.Hwindows && SysArch.Family == sys.AMD64 { // only amd64 needs PCREL + } else if (Headtype == obj.Hwindows || Headtype == obj.Hwindowsgui) && SysArch.Family == sys.AMD64 { // only amd64 needs PCREL // PE/COFF's PC32 relocation uses the address after the relocated // bytes as the base. Compensate by skewing the addend. o += int64(r.Siz) @@ -575,7 +575,7 @@ func relocsym(ctxt *Link, s *Symbol) { // relocated address, compensate that. o -= int64(s.Sect.Vaddr - PEBASE) } else { - ctxt.Diag("unhandled pcrel relocation for %s", headstring) + ctxt.Diag("unhandled pcrel relocation for %s", Headtype) } break @@ -657,7 +657,7 @@ func (ctxt *Link) reloc() { } func dynrelocsym(ctxt *Link, s *Symbol) { - if HEADTYPE == obj.Hwindows && Linkmode != LinkExternal { + if (Headtype == obj.Hwindows || Headtype == obj.Hwindowsgui) && Linkmode != LinkExternal { rel := Linklookup(ctxt, ".rel", 0) if s == rel { return @@ -713,7 +713,7 @@ func dynrelocsym(ctxt *Link, s *Symbol) { func dynreloc(ctxt *Link, data *[obj.SXREF][]*Symbol) { // -d suppresses dynamic loader format, so we may as well not // compute these sections or mark their symbols as reachable. - if *FlagD && HEADTYPE != obj.Hwindows { + if *FlagD && Headtype != obj.Hwindows && Headtype != obj.Hwindowsgui { return } if ctxt.Debugvlog != 0 { @@ -1201,7 +1201,7 @@ func (ctxt *Link) dodata() { // symbol, which is itself data. // // On darwin, we need the symbol table numbers for dynreloc. - if HEADTYPE == obj.Hdarwin { + if Headtype == obj.Hdarwin { machosymorder(ctxt) } dynreloc(ctxt, &data) @@ -1423,7 +1423,7 @@ func (ctxt *Link) dodata() { if len(data[obj.STLSBSS]) > 0 { var sect *Section - if Iself && (Linkmode == LinkExternal || !*FlagD) && HEADTYPE != obj.Hopenbsd { + if Iself && (Linkmode == LinkExternal || !*FlagD) && Headtype != obj.Hopenbsd { sect = addsection(&Segdata, ".tbss", 06) sect.Align = int32(SysArch.PtrSize) sect.Vaddr = 0 @@ -1740,7 +1740,7 @@ func (ctxt *Link) dodata() { } func dodataSect(ctxt *Link, symn int, syms []*Symbol) (result []*Symbol, maxAlign int32) { - if HEADTYPE == obj.Hdarwin { + if Headtype == obj.Hdarwin { // Some symbols may no longer belong in syms // due to movement in machosymorder. newSyms := make([]*Symbol, 0, len(syms)) @@ -1862,7 +1862,7 @@ func (ctxt *Link) textaddress() { sect.Align = int32(Funcalign) Linklookup(ctxt, "runtime.text", 0).Sect = sect Linklookup(ctxt, "runtime.etext", 0).Sect = sect - if HEADTYPE == obj.Hwindows { + if Headtype == obj.Hwindows || Headtype == obj.Hwindowsgui { Linklookup(ctxt, ".text", 0).Sect = sect } va := uint64(*FlagTextAddr) @@ -1908,7 +1908,7 @@ func (ctxt *Link) address() { Segtext.Length = va - uint64(*FlagTextAddr) Segtext.Filelen = Segtext.Length - if HEADTYPE == obj.Hnacl { + if Headtype == obj.Hnacl { va += 32 // room for the "halt sled" } @@ -1936,10 +1936,10 @@ func (ctxt *Link) address() { Segdata.Vaddr = va Segdata.Fileoff = va - Segtext.Vaddr + Segtext.Fileoff Segdata.Filelen = 0 - if HEADTYPE == obj.Hwindows { + if Headtype == obj.Hwindows || Headtype == obj.Hwindowsgui { Segdata.Fileoff = Segtext.Fileoff + uint64(Rnd(int64(Segtext.Length), PEFILEALIGN)) } - if HEADTYPE == obj.Hplan9 { + if Headtype == obj.Hplan9 { Segdata.Fileoff = Segtext.Fileoff + Segtext.Filelen } var data *Section @@ -1979,7 +1979,7 @@ func (ctxt *Link) address() { Segdwarf.Vaddr = va Segdwarf.Fileoff = Segdata.Fileoff + uint64(Rnd(int64(Segdata.Filelen), int64(*FlagRound))) Segdwarf.Filelen = 0 - if HEADTYPE == obj.Hwindows { + if Headtype == obj.Hwindows || Headtype == obj.Hwindowsgui { Segdwarf.Fileoff = Segdata.Fileoff + uint64(Rnd(int64(Segdata.Filelen), int64(PEFILEALIGN))) } for s := Segdwarf.Sect; s != nil; s = s.Next { @@ -1989,7 +1989,7 @@ func (ctxt *Link) address() { } s.Vaddr = va va += uint64(vlen) - if HEADTYPE == obj.Hwindows { + if Headtype == obj.Hwindows || Headtype == obj.Hwindowsgui { va = uint64(Rnd(int64(va), PEFILEALIGN)) } Segdwarf.Length = va - Segdwarf.Vaddr @@ -2050,7 +2050,7 @@ func (ctxt *Link) address() { ctxt.xdefine("runtime.text", obj.STEXT, int64(text.Vaddr)) ctxt.xdefine("runtime.etext", obj.STEXT, int64(text.Vaddr+text.Length)) - if HEADTYPE == obj.Hwindows { + if Headtype == obj.Hwindows || Headtype == obj.Hwindowsgui { ctxt.xdefine(".text", obj.STEXT, int64(text.Vaddr)) } ctxt.xdefine("runtime.rodata", obj.SRODATA, int64(rodata.Vaddr)) diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go index e8229fe7f9..1d7f26b60c 100644 --- a/src/cmd/link/internal/ld/dwarf.go +++ b/src/cmd/link/internal/ld/dwarf.go @@ -1401,15 +1401,15 @@ func dwarfgeneratedebugsyms(ctxt *Link) { if *FlagW { // disable dwarf return } - if *FlagS && HEADTYPE != obj.Hdarwin { + if *FlagS && Headtype != obj.Hdarwin { return } - if HEADTYPE == obj.Hplan9 { + if Headtype == obj.Hplan9 { return } if Linkmode == LinkExternal { - if !Iself && HEADTYPE != obj.Hdarwin { + if !Iself && Headtype != obj.Hdarwin { return } } diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go index 04d2193b4a..3275c10d78 100644 --- a/src/cmd/link/internal/ld/elf.go +++ b/src/cmd/link/internal/ld/elf.go @@ -947,7 +947,7 @@ func Elfinit(ctxt *Link) { // 32-bit architectures case sys.ARM: // we use EABI on both linux/arm and freebsd/arm. - if HEADTYPE == obj.Hlinux || HEADTYPE == obj.Hfreebsd { + if Headtype == obj.Hlinux || Headtype == obj.Hfreebsd { // We set a value here that makes no indication of which // float ABI the object uses, because this is information // used by the dynamic linker to compare executables and @@ -1836,15 +1836,15 @@ func (ctxt *Link) doelf() { // for dynamic internal linker or external linking, so that various // binutils could correctly calculate PT_TLS size. // see https://golang.org/issue/5200. - if HEADTYPE != obj.Hopenbsd { + if Headtype != obj.Hopenbsd { if !*FlagD || Linkmode == LinkExternal { Addstring(ctxt, shstrtab, ".tbss") } } - if HEADTYPE == obj.Hnetbsd { + if Headtype == obj.Hnetbsd { Addstring(ctxt, shstrtab, ".note.netbsd.ident") } - if HEADTYPE == obj.Hopenbsd { + if Headtype == obj.Hopenbsd { Addstring(ctxt, shstrtab, ".note.openbsd.ident") } if len(buildinfo) > 0 { @@ -2189,7 +2189,7 @@ func Asmbelf(ctxt *Link, symo int64) { * segment boundaries downwards to include it. * Except on NaCl where it must not be loaded. */ - if HEADTYPE != obj.Hnacl { + if Headtype != obj.Hnacl { o := int64(Segtext.Vaddr - pph.vaddr) Segtext.Vaddr -= uint64(o) Segtext.Length += uint64(o) @@ -2206,7 +2206,7 @@ func Asmbelf(ctxt *Link, symo int64) { sh.flags = SHF_ALLOC sh.addralign = 1 if interpreter == "" { - switch HEADTYPE { + switch Headtype { case obj.Hlinux: interpreter = Thearch.Linuxdynld @@ -2236,9 +2236,9 @@ func Asmbelf(ctxt *Link, symo int64) { } pnote = nil - if HEADTYPE == obj.Hnetbsd || HEADTYPE == obj.Hopenbsd { + if Headtype == obj.Hnetbsd || Headtype == obj.Hopenbsd { var sh *ElfShdr - switch HEADTYPE { + switch Headtype { case obj.Hnetbsd: sh = elfshname(ctxt, ".note.netbsd.ident") resoff -= int64(elfnetbsdsig(sh, uint64(startva), uint64(resoff))) @@ -2434,7 +2434,7 @@ func Asmbelf(ctxt *Link, symo int64) { // Do not emit PT_TLS for OpenBSD since ld.so(1) does // not currently support it. This is handled // appropriately in runtime/cgo. - if HEADTYPE != obj.Hopenbsd { + if Headtype != obj.Hopenbsd { tlssize := uint64(0) for sect := Segdata.Sect; sect != nil; sect = sect.Next { if sect.Name == ".tbss" { @@ -2451,7 +2451,7 @@ func Asmbelf(ctxt *Link, symo int64) { } } - if HEADTYPE == obj.Hlinux { + if Headtype == obj.Hlinux { ph := newElfPhdr(ctxt) ph.type_ = PT_GNU_STACK ph.flags = PF_W + PF_R @@ -2538,13 +2538,13 @@ elfobj: eh.ident[EI_MAG1] = 'E' eh.ident[EI_MAG2] = 'L' eh.ident[EI_MAG3] = 'F' - if HEADTYPE == obj.Hfreebsd { + if Headtype == obj.Hfreebsd { eh.ident[EI_OSABI] = ELFOSABI_FREEBSD - } else if HEADTYPE == obj.Hnetbsd { + } else if Headtype == obj.Hnetbsd { eh.ident[EI_OSABI] = ELFOSABI_NETBSD - } else if HEADTYPE == obj.Hopenbsd { + } else if Headtype == obj.Hopenbsd { eh.ident[EI_OSABI] = ELFOSABI_OPENBSD - } else if HEADTYPE == obj.Hdragonfly { + } else if Headtype == obj.Hdragonfly { eh.ident[EI_OSABI] = ELFOSABI_NONE } if elf64 { @@ -2585,10 +2585,10 @@ elfobj: a += int64(elfwriteinterp(ctxt)) } if Linkmode != LinkExternal { - if HEADTYPE == obj.Hnetbsd { + if Headtype == obj.Hnetbsd { a += int64(elfwritenetbsdsig(ctxt)) } - if HEADTYPE == obj.Hopenbsd { + if Headtype == obj.Hopenbsd { a += int64(elfwriteopenbsdsig(ctxt)) } if len(buildinfo) > 0 { diff --git a/src/cmd/link/internal/ld/go.go b/src/cmd/link/internal/ld/go.go index ffae53eda3..02f70f1a45 100644 --- a/src/cmd/link/internal/ld/go.go +++ b/src/cmd/link/internal/ld/go.go @@ -174,7 +174,7 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) { // to force a link of foo.so. havedynamic = 1 - if HEADTYPE == obj.Hdarwin { + if Headtype == obj.Hdarwin { Machoadddynlib(lib) } else { dynlib = append(dynlib, lib) @@ -322,9 +322,9 @@ func Adddynsym(ctxt *Link, s *Symbol) { if Iself { Elfadddynsym(ctxt, s) - } else if HEADTYPE == obj.Hdarwin { + } else if Headtype == obj.Hdarwin { ctxt.Diag("adddynsym: missed symbol %s (%s)", s.Name, s.Extname) - } else if HEADTYPE == obj.Hwindows { + } else if Headtype == obj.Hwindows { // already taken care of } else { ctxt.Diag("adddynsym: unsupported binary format") @@ -363,7 +363,7 @@ func fieldtrack(ctxt *Link) { } func (ctxt *Link) addexport() { - if HEADTYPE == obj.Hdarwin { + if Headtype == obj.Hdarwin { return } diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 0df49a7271..54f169ec2a 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -183,7 +183,7 @@ var ( debug_s bool // backup old value of debug['s'] HEADR int32 - HEADTYPE int32 + Headtype obj.HeadType nerrors int Linkmode int @@ -206,10 +206,6 @@ const ( Pkgdef ) -var ( - headstring string -) - // TODO(dfc) outBuf duplicates bio.Writer type outBuf struct { w *bufio.Writer @@ -465,7 +461,7 @@ func (ctxt *Link) loadlib() { // dependency problems when compiling natively (external linking requires // runtime/cgo, runtime/cgo requires cmd/cgo, but cmd/cgo needs to be // compiled using external linking.) - if SysArch.InFamily(sys.ARM, sys.ARM64) && HEADTYPE == obj.Hdarwin && iscgo { + if SysArch.InFamily(sys.ARM, sys.ARM64) && Headtype == obj.Hdarwin && iscgo { Linkmode = LinkExternal } @@ -605,7 +601,7 @@ func (ctxt *Link) loadlib() { if *flagLibGCC != "none" { hostArchive(ctxt, *flagLibGCC) } - if HEADTYPE == obj.Hwindows { + if Headtype == obj.Hwindows || Headtype == obj.Hwindowsgui { if p := ctxt.findLibPath("libmingwex.a"); p != "none" { hostArchive(ctxt, p) } @@ -639,7 +635,7 @@ func (ctxt *Link) loadlib() { // statically linked binaries. switch Buildmode { case BuildmodeExe, BuildmodePIE: - if havedynamic == 0 && HEADTYPE != obj.Hdarwin && HEADTYPE != obj.Hsolaris { + if havedynamic == 0 && Headtype != obj.Hdarwin && Headtype != obj.Hsolaris { *FlagD = true } } @@ -805,7 +801,7 @@ func ldhostobj(ld func(*Link, *bio.Reader, string, int64, string), f *bio.Reader // force external linking for any libraries that link in code that // uses errno. This can be removed if the Go linker ever supports // these relocation types. - if HEADTYPE == obj.Hdragonfly { + if Headtype == obj.Hdragonfly { if pkg == "net" || pkg == "os/user" { isinternal = false } @@ -980,23 +976,20 @@ func (l *Link) hostlink() { argv = append(argv, "-s") } - if HEADTYPE == obj.Hdarwin { + switch Headtype { + case obj.Hdarwin: argv = append(argv, "-Wl,-no_pie,-headerpad,1144") - } - if HEADTYPE == obj.Hopenbsd { + case obj.Hopenbsd: argv = append(argv, "-Wl,-nopie") - } - if HEADTYPE == obj.Hwindows { - if headstring == "windowsgui" { - argv = append(argv, "-mwindows") - } else { - argv = append(argv, "-mconsole") - } + case obj.Hwindows: + argv = append(argv, "-mconsole") + case obj.Hwindowsgui: + argv = append(argv, "-mwindows") } switch Buildmode { case BuildmodeExe: - if HEADTYPE == obj.Hdarwin { + if Headtype == obj.Hdarwin { argv = append(argv, "-Wl,-pagezero_size,4000000") } case BuildmodePIE: @@ -1005,7 +998,7 @@ func (l *Link) hostlink() { } argv = append(argv, "-pie") case BuildmodeCShared: - if HEADTYPE == obj.Hdarwin { + if Headtype == obj.Hdarwin { argv = append(argv, "-dynamiclib", "-Wl,-read_only_relocs,suppress") } else { // ELF. @@ -1170,7 +1163,7 @@ func (l *Link) hostlink() { } } } - if HEADTYPE == obj.Hwindows { + if Headtype == obj.Hwindows || Headtype == obj.Hwindowsgui { // libmingw32 and libmingwex have some inter-dependencies, // so must use linker groups. argv = append(argv, "-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group") @@ -1191,7 +1184,7 @@ func (l *Link) hostlink() { l.Logf("%s", out) } - if !*FlagS && !debug_s && HEADTYPE == obj.Hdarwin { + if !*FlagS && !debug_s && Headtype == obj.Hdarwin { // Skip combining dwarf on arm. if !SysArch.InFamily(sys.ARM, sys.ARM64) { dsym := filepath.Join(*flagTmpdir, "go.dwarf") @@ -1828,16 +1821,6 @@ func usage() { Exit(2) } -func setheadtype(s string) { - h := headtype(s) - if h < 0 { - Exitf("unknown header type -H %s", s) - } - - headstring = s - HEADTYPE = int32(headtype(s)) -} - func doversion() { Exitf("version %s", obj.Getgoversion()) } @@ -1905,7 +1888,7 @@ func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, int, int64, int64, i put(ctxt, nil, s.Name, 'f', s.Value, 0, int(s.Version), nil) case obj.SHOSTOBJ: - if HEADTYPE == obj.Hwindows || Iself { + if Headtype == obj.Hwindows || Headtype == obj.Hwindowsgui || Iself { put(ctxt, s, s.Name, 'U', s.Value, 0, int(s.Version), nil) } @@ -1916,7 +1899,7 @@ func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, int, int64, int64, i put(ctxt, s, s.Extname, 'U', 0, 0, int(s.Version), nil) case obj.STLSBSS: - if Linkmode == LinkExternal && HEADTYPE != obj.Hopenbsd { + if Linkmode == LinkExternal && Headtype != obj.Hopenbsd { put(ctxt, s, s.Name, 't', Symaddr(ctxt, s), s.Size, int(s.Version), s.Gotype) } } diff --git a/src/cmd/link/internal/ld/link.go b/src/cmd/link/internal/ld/link.go index 07ef86edf8..836d7748a7 100644 --- a/src/cmd/link/internal/ld/link.go +++ b/src/cmd/link/internal/ld/link.go @@ -161,7 +161,6 @@ type Shlib struct { type Link struct { Goarm int32 - Headtype int Arch *sys.Arch Debugvlog int Bso *bufio.Writer diff --git a/src/cmd/link/internal/ld/main.go b/src/cmd/link/internal/ld/main.go index d1bd159330..c169944d1d 100644 --- a/src/cmd/link/internal/ld/main.go +++ b/src/cmd/link/internal/ld/main.go @@ -35,7 +35,6 @@ import ( "cmd/internal/obj" "cmd/internal/sys" "flag" - "fmt" "log" "os" "runtime" @@ -49,6 +48,7 @@ var ( func init() { flag.Var(&Buildmode, "buildmode", "set build `mode`") + flag.Var(&Headtype, "H", "set header `type`") flag.Var(&rpath, "r", "set the ELF dynamic linker search `path` to dir1:dir2:...") } @@ -101,10 +101,6 @@ func Main() { ctxt := linknew(SysArch) ctxt.Bso = bufio.NewWriter(os.Stdout) - nerrors = 0 - HEADTYPE = -1 - Linkmode = LinkAuto - // For testing behavior of go command when tools crash silently. // Undocumented, not in standard flag parser to avoid // exposing in usage message. @@ -120,7 +116,6 @@ func Main() { } obj.Flagfn1("B", "add an ELF NT_GNU_BUILD_ID `note` when using ELF", addbuildinfo) obj.Flagfn1("L", "add specified `directory` to library path", func(a string) { Lflag(ctxt, a) }) - obj.Flagfn1("H", "set header `type`", setheadtype) obj.Flagfn0("V", "print version and exit", doversion) obj.Flagfn1("X", "add string value `definition` of the form importpath.name=value", func(s string) { addstrdata1(ctxt, s) }) obj.Flagcount("v", "print link trace", &ctxt.Debugvlog) @@ -139,7 +134,7 @@ func Main() { if *flagOutfile == "" { *flagOutfile = "a.out" - if HEADTYPE == obj.Hwindows { + if Headtype == obj.Hwindows || Headtype == obj.Hwindowsgui { *flagOutfile += ".exe" } } @@ -148,14 +143,11 @@ func Main() { libinit(ctxt) // creates outfile - if HEADTYPE == -1 { - HEADTYPE = int32(headtype(goos)) - } - ctxt.Headtype = int(HEADTYPE) - if headstring == "" { - headstring = Headstr(int(HEADTYPE)) + if Headtype == obj.Hunknown { + Headtype.Set(obj.Getgoos()) } + ctxt.computeTLSOffset() Thearch.Archinit(ctxt) if *FlagLinkshared && !Iself { @@ -163,7 +155,7 @@ func Main() { } if ctxt.Debugvlog != 0 { - ctxt.Logf("HEADER = -H%d -T0x%x -D0x%x -R0x%x\n", HEADTYPE, uint64(*FlagTextAddr), uint64(*FlagDataAddr), uint32(*FlagRound)) + ctxt.Logf("HEADER = -H%d -T0x%x -D0x%x -R0x%x\n", Headtype, uint64(*FlagTextAddr), uint64(*FlagDataAddr), uint32(*FlagRound)) } if Buildmode == BuildmodeShared { @@ -191,11 +183,11 @@ func Main() { ctxt.callgraph() ctxt.doelf() - if HEADTYPE == obj.Hdarwin { + if Headtype == obj.Hdarwin { ctxt.domacho() } ctxt.dostkcheck() - if HEADTYPE == obj.Hwindows { + if Headtype == obj.Hwindows || Headtype == obj.Hwindowsgui { ctxt.dope() } ctxt.addexport() @@ -223,97 +215,6 @@ func Main() { errorexit() } -// A BuildMode indicates the sort of object we are building: -// "exe": build a main package and everything it imports into an executable. -// "c-shared": build a main package, plus all packages that it imports, into a -// single C shared library. The only callable symbols will be those functions -// marked as exported. -// "shared": combine all packages passed on the command line, and their -// dependencies, into a single shared library that will be used when -// building with the -linkshared option. -type BuildMode uint8 - -const ( - BuildmodeUnset BuildMode = iota - BuildmodeExe - BuildmodePIE - BuildmodeCArchive - BuildmodeCShared - BuildmodeShared -) - -func (mode *BuildMode) Set(s string) error { - goos := obj.Getgoos() - goarch := obj.Getgoarch() - badmode := func() error { - return fmt.Errorf("buildmode %s not supported on %s/%s", s, goos, goarch) - } - switch s { - default: - return fmt.Errorf("invalid buildmode: %q", s) - case "exe": - *mode = BuildmodeExe - case "pie": - switch goos { - case "android", "linux": - default: - return badmode() - } - *mode = BuildmodePIE - case "c-archive": - switch goos { - case "darwin", "linux": - case "windows": - switch goarch { - case "amd64", "386": - default: - return badmode() - } - default: - return badmode() - } - *mode = BuildmodeCArchive - case "c-shared": - switch goarch { - case "386", "amd64", "arm", "arm64": - default: - return badmode() - } - *mode = BuildmodeCShared - case "shared": - switch goos { - case "linux": - switch goarch { - case "386", "amd64", "arm", "arm64", "ppc64le", "s390x": - default: - return badmode() - } - default: - return badmode() - } - *mode = BuildmodeShared - } - return nil -} - -func (mode *BuildMode) String() string { - switch *mode { - case BuildmodeUnset: - return "" // avoid showing a default in usage message - case BuildmodeExe: - return "exe" - case BuildmodePIE: - return "pie" - case BuildmodeCArchive: - return "c-archive" - case BuildmodeCShared: - return "c-shared" - case BuildmodeShared: - return "shared" - } - return fmt.Sprintf("BuildMode(%d)", uint8(*mode)) -} - type Rpath struct { set bool val string diff --git a/src/cmd/link/internal/ld/pe.go b/src/cmd/link/internal/ld/pe.go index 1492c9136c..591a5f47d0 100644 --- a/src/cmd/link/internal/ld/pe.go +++ b/src/cmd/link/internal/ld/pe.go @@ -1244,7 +1244,7 @@ func Asmbpe(ctxt *Link) { oh.SizeOfImage = uint32(nextsectoff) oh64.SizeOfHeaders = uint32(PEFILEHEADR) oh.SizeOfHeaders = uint32(PEFILEHEADR) - if headstring == "windowsgui" { + if Headtype == obj.Hwindowsgui { oh64.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI oh.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI } else { diff --git a/src/cmd/link/internal/ld/sym.go b/src/cmd/link/internal/ld/sym.go index 8efa7f15d4..bf27707718 100644 --- a/src/cmd/link/internal/ld/sym.go +++ b/src/cmd/link/internal/ld/sym.go @@ -34,28 +34,10 @@ package ld import ( "cmd/internal/obj" "cmd/internal/sys" + "fmt" "log" - "strconv" ) -var headers = []struct { - name string - val int -}{ - {"darwin", obj.Hdarwin}, - {"dragonfly", obj.Hdragonfly}, - {"freebsd", obj.Hfreebsd}, - {"linux", obj.Hlinux}, - {"android", obj.Hlinux}, // must be after "linux" entry or else headstr(Hlinux) == "android" - {"nacl", obj.Hnacl}, - {"netbsd", obj.Hnetbsd}, - {"openbsd", obj.Hopenbsd}, - {"plan9", obj.Hplan9}, - {"solaris", obj.Hsolaris}, - {"windows", obj.Hwindows}, - {"windowsgui", obj.Hwindows}, -} - func linknew(arch *sys.Arch) *Link { ctxt := &Link{ Hash: []map[string]*Symbol{ @@ -73,18 +55,21 @@ func linknew(arch *sys.Arch) *Link { log.Fatalf("invalid goarch %s (want %s)", p, arch.Name) } - ctxt.Headtype = headtype(obj.Getgoos()) - if ctxt.Headtype < 0 { - log.Fatalf("unknown goos %s", obj.Getgoos()) + // On arm, record goarm. + if ctxt.Arch.Family == sys.ARM { + ctxt.Goarm = obj.Getgoarm() } - // Record thread-local storage offset. - // TODO(rsc): Move tlsoffset back into the linker. - switch ctxt.Headtype { + return ctxt +} + +// computeTLSOffset records the thread-local storage offset. +func (ctxt *Link) computeTLSOffset() { + switch Headtype { default: - log.Fatalf("unknown thread-local storage offset for %s", Headstr(ctxt.Headtype)) + log.Fatalf("unknown thread-local storage offset for %s", Headtype) - case obj.Hplan9, obj.Hwindows: + case obj.Hplan9, obj.Hwindows, obj.Hwindowsgui: break /* @@ -152,12 +137,6 @@ func linknew(arch *sys.Arch) *Link { } } - // On arm, record goarm. - if ctxt.Arch.Family == sys.ARM { - ctxt.Goarm = obj.Getgoarm() - } - - return ctxt } func linknewsym(ctxt *Link, name string, v int) *Symbol { @@ -195,20 +174,93 @@ func Linkrlookup(ctxt *Link, name string, v int) *Symbol { return ctxt.Hash[v][name] } -func Headstr(v int) string { - for i := 0; i < len(headers); i++ { - if v == headers[i].val { - return headers[i].name +// A BuildMode indicates the sort of object we are building: +// "exe": build a main package and everything it imports into an executable. +// "c-shared": build a main package, plus all packages that it imports, into a +// single C shared library. The only callable symbols will be those functions +// marked as exported. +// "shared": combine all packages passed on the command line, and their +// dependencies, into a single shared library that will be used when +// building with the -linkshared option. +type BuildMode uint8 + +const ( + BuildmodeUnset BuildMode = iota + BuildmodeExe + BuildmodePIE + BuildmodeCArchive + BuildmodeCShared + BuildmodeShared +) + +func (mode *BuildMode) Set(s string) error { + goos := obj.Getgoos() + goarch := obj.Getgoarch() + badmode := func() error { + return fmt.Errorf("buildmode %s not supported on %s/%s", s, goos, goarch) + } + switch s { + default: + return fmt.Errorf("invalid buildmode: %q", s) + case "exe": + *mode = BuildmodeExe + case "pie": + switch goos { + case "android", "linux": + default: + return badmode() + } + *mode = BuildmodePIE + case "c-archive": + switch goos { + case "darwin", "linux": + case "windows": + switch goarch { + case "amd64", "386": + default: + return badmode() + } + default: + return badmode() } + *mode = BuildmodeCArchive + case "c-shared": + switch goarch { + case "386", "amd64", "arm", "arm64": + default: + return badmode() + } + *mode = BuildmodeCShared + case "shared": + switch goos { + case "linux": + switch goarch { + case "386", "amd64", "arm", "arm64", "ppc64le", "s390x": + default: + return badmode() + } + default: + return badmode() + } + *mode = BuildmodeShared } - return strconv.Itoa(v) + return nil } -func headtype(name string) int { - for i := 0; i < len(headers); i++ { - if name == headers[i].name { - return headers[i].val - } +func (mode *BuildMode) String() string { + switch *mode { + case BuildmodeUnset: + return "" // avoid showing a default in usage message + case BuildmodeExe: + return "exe" + case BuildmodePIE: + return "pie" + case BuildmodeCArchive: + return "c-archive" + case BuildmodeCShared: + return "c-shared" + case BuildmodeShared: + return "shared" } - return -1 + return fmt.Sprintf("BuildMode(%d)", uint8(*mode)) } diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go index 4c969687b6..484f98a3f8 100644 --- a/src/cmd/link/internal/ld/symtab.go +++ b/src/cmd/link/internal/ld/symtab.go @@ -226,7 +226,7 @@ func putplan9sym(ctxt *Link, x *Symbol, s string, t int, addr int64, size int64, 'Z', 'm': l := 4 - if HEADTYPE == obj.Hplan9 && SysArch.Family == sys.AMD64 && !Flag8 { + if Headtype == obj.Hplan9 && SysArch.Family == sys.AMD64 && !Flag8 { Lputb(uint32(addr >> 32)) l = 8 } diff --git a/src/cmd/link/internal/mips64/asm.go b/src/cmd/link/internal/mips64/asm.go index 5ff4125f4f..1c7751dc16 100644 --- a/src/cmd/link/internal/mips64/asm.go +++ b/src/cmd/link/internal/mips64/asm.go @@ -228,7 +228,7 @@ func asmb(ctxt *ld.Link) { if ctxt.Debugvlog != 0 { ctxt.Logf("%5.2f sym\n", obj.Cputime()) } - switch ld.HEADTYPE { + switch ld.Headtype { default: if ld.Iself { symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen) @@ -240,7 +240,7 @@ func asmb(ctxt *ld.Link) { } ld.Cseek(int64(symo)) - switch ld.HEADTYPE { + switch ld.Headtype { default: if ld.Iself { if ctxt.Debugvlog != 0 { @@ -276,7 +276,7 @@ func asmb(ctxt *ld.Link) { ctxt.Logf("%5.2f header\n", obj.Cputime()) } ld.Cseek(0) - switch ld.HEADTYPE { + switch ld.Headtype { default: case obj.Hplan9: /* plan 9 */ magic := uint32(4*18*18 + 7) diff --git a/src/cmd/link/internal/mips64/obj.go b/src/cmd/link/internal/mips64/obj.go index 523db6c9a6..583a78a98f 100644 --- a/src/cmd/link/internal/mips64/obj.go +++ b/src/cmd/link/internal/mips64/obj.go @@ -99,22 +99,22 @@ func archinit(ctxt *ld.Link) { ld.Linkmode = ld.LinkInternal } - switch ld.HEADTYPE { + switch ld.Headtype { default: if ld.Linkmode == ld.LinkAuto { ld.Linkmode = ld.LinkInternal } if ld.Linkmode == ld.LinkExternal && obj.Getgoextlinkenabled() != "1" { - log.Fatalf("cannot use -linkmode=external with -H %s", ld.Headstr(int(ld.HEADTYPE))) + log.Fatalf("cannot use -linkmode=external with -H %s", ld.Headtype) } case obj.Hlinux: break } - switch ld.HEADTYPE { + switch ld.Headtype { default: - ld.Exitf("unknown -H option: %v", ld.HEADTYPE) + ld.Exitf("unknown -H option: %v", ld.Headtype) case obj.Hplan9: /* plan 9 */ ld.HEADR = 32 diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go index 34ac6b46e0..9cbd34b981 100644 --- a/src/cmd/link/internal/ppc64/asm.go +++ b/src/cmd/link/internal/ppc64/asm.go @@ -849,7 +849,7 @@ func asmb(ctxt *ld.Link) { if ctxt.Debugvlog != 0 { ctxt.Logf("%5.2f sym\n", obj.Cputime()) } - switch ld.HEADTYPE { + switch ld.Headtype { default: if ld.Iself { symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen) @@ -861,7 +861,7 @@ func asmb(ctxt *ld.Link) { } ld.Cseek(int64(symo)) - switch ld.HEADTYPE { + switch ld.Headtype { default: if ld.Iself { if ctxt.Debugvlog != 0 { @@ -897,7 +897,7 @@ func asmb(ctxt *ld.Link) { ctxt.Logf("%5.2f header\n", obj.Cputime()) } ld.Cseek(0) - switch ld.HEADTYPE { + switch ld.Headtype { default: case obj.Hplan9: /* plan 9 */ ld.Thearch.Lput(0x647) /* magic */ diff --git a/src/cmd/link/internal/ppc64/obj.go b/src/cmd/link/internal/ppc64/obj.go index d17bc6ce58..8ebc0da446 100644 --- a/src/cmd/link/internal/ppc64/obj.go +++ b/src/cmd/link/internal/ppc64/obj.go @@ -114,22 +114,22 @@ func archinit(ctxt *ld.Link) { toc.Type = obj.SDYNIMPORT } - switch ld.HEADTYPE { + switch ld.Headtype { default: if ld.Linkmode == ld.LinkAuto { ld.Linkmode = ld.LinkInternal } if ld.Linkmode == ld.LinkExternal && obj.Getgoextlinkenabled() != "1" { - log.Fatalf("cannot use -linkmode=external with -H %s", ld.Headstr(int(ld.HEADTYPE))) + log.Fatalf("cannot use -linkmode=external with -H %s", ld.Headtype) } case obj.Hlinux: break } - switch ld.HEADTYPE { + switch ld.Headtype { default: - ld.Exitf("unknown -H option: %v", ld.HEADTYPE) + ld.Exitf("unknown -H option: %v", ld.Headtype) case obj.Hplan9: /* plan 9 */ ld.HEADR = 32 diff --git a/src/cmd/link/internal/s390x/asm.go b/src/cmd/link/internal/s390x/asm.go index cebcc75e35..47e042d4fa 100644 --- a/src/cmd/link/internal/s390x/asm.go +++ b/src/cmd/link/internal/s390x/asm.go @@ -571,7 +571,7 @@ func asmb(ctxt *ld.Link) { ctxt.Logf("%5.2f header\n", obj.Cputime()) } ld.Cseek(0) - switch ld.HEADTYPE { + switch ld.Headtype { default: ctxt.Diag("unsupported operating system") case obj.Hlinux: diff --git a/src/cmd/link/internal/s390x/obj.go b/src/cmd/link/internal/s390x/obj.go index 09b9710da9..4554c52e02 100644 --- a/src/cmd/link/internal/s390x/obj.go +++ b/src/cmd/link/internal/s390x/obj.go @@ -90,9 +90,9 @@ func archinit(ctxt *ld.Link) { ld.Linkmode = ld.LinkExternal } - switch ld.HEADTYPE { + switch ld.Headtype { default: - ld.Exitf("unknown -H option: %v", ld.HEADTYPE) + ld.Exitf("unknown -H option: %v", ld.Headtype) case obj.Hlinux: // s390x ELF ld.Elfinit(ctxt) diff --git a/src/cmd/link/internal/x86/asm.go b/src/cmd/link/internal/x86/asm.go index cc55c2101a..c80d9629e1 100644 --- a/src/cmd/link/internal/x86/asm.go +++ b/src/cmd/link/internal/x86/asm.go @@ -308,7 +308,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) { return } - if ld.HEADTYPE == obj.Hdarwin && s.Size == int64(ld.SysArch.PtrSize) && r.Off == 0 { + if ld.Headtype == obj.Hdarwin && s.Size == int64(ld.SysArch.PtrSize) && r.Off == 0 { // Mach-O relocations are a royal pain to lay out. // They use a compact stateful bytecode representation // that is too much bother to deal with. @@ -333,7 +333,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) { return } - if ld.HEADTYPE == obj.Hwindows && s.Size == int64(ld.SysArch.PtrSize) { + if (ld.Headtype == obj.Hwindows || ld.Headtype == obj.Hwindowsgui) && s.Size == int64(ld.SysArch.PtrSize) { // nothing to do, the relocation will be laid out in pereloc1 return } @@ -582,7 +582,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) { ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_386_JMP_SLOT)) s.Plt = int32(plt.Size - 16) - } else if ld.HEADTYPE == obj.Hdarwin { + } else if ld.Headtype == obj.Hdarwin { // Same laziness as in 6l. plt := ld.Linklookup(ctxt, ".plt", 0) @@ -616,7 +616,7 @@ func addgotsym(ctxt *ld.Link, s *ld.Symbol) { rel := ld.Linklookup(ctxt, ".rel", 0) ld.Addaddrplus(ctxt, rel, got, int64(s.Got)) ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_386_GLOB_DAT)) - } else if ld.HEADTYPE == obj.Hdarwin { + } else if ld.Headtype == obj.Hdarwin { ld.Adduint32(ctxt, ld.Linklookup(ctxt, ".linkedit.got", 0), uint32(s.Dynid)) } else { ctxt.Diag("addgotsym: unsupported binary format") @@ -661,7 +661,7 @@ func asmb(ctxt *ld.Link) { ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen)) machlink := uint32(0) - if ld.HEADTYPE == obj.Hdarwin { + if ld.Headtype == obj.Hdarwin { machlink = uint32(ld.Domacholink(ctxt)) } @@ -674,7 +674,7 @@ func asmb(ctxt *ld.Link) { if ctxt.Debugvlog != 0 { ctxt.Logf("%5.2f sym\n", obj.Cputime()) } - switch ld.HEADTYPE { + switch ld.Headtype { default: if ld.Iself { symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen) @@ -687,13 +687,13 @@ func asmb(ctxt *ld.Link) { case obj.Hdarwin: symo = uint32(ld.Segdwarf.Fileoff + uint64(ld.Rnd(int64(ld.Segdwarf.Filelen), int64(*ld.FlagRound))) + uint64(machlink)) - case obj.Hwindows: + case obj.Hwindows, obj.Hwindowsgui: symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen) symo = uint32(ld.Rnd(int64(symo), ld.PEFILEALIGN)) } ld.Cseek(int64(symo)) - switch ld.HEADTYPE { + switch ld.Headtype { default: if ld.Iself { if ctxt.Debugvlog != 0 { @@ -722,7 +722,7 @@ func asmb(ctxt *ld.Link) { ld.Cflush() } - case obj.Hwindows: + case obj.Hwindows, obj.Hwindowsgui: if ctxt.Debugvlog != 0 { ctxt.Logf("%5.2f dwarf\n", obj.Cputime()) } @@ -738,7 +738,7 @@ func asmb(ctxt *ld.Link) { ctxt.Logf("%5.2f headr\n", obj.Cputime()) } ld.Cseek(0) - switch ld.HEADTYPE { + switch ld.Headtype { default: case obj.Hplan9: /* plan9 */ magic := int32(4*11*11 + 7) @@ -762,7 +762,7 @@ func asmb(ctxt *ld.Link) { obj.Hnacl: ld.Asmbelf(ctxt, int64(symo)) - case obj.Hwindows: + case obj.Hwindows, obj.Hwindowsgui: ld.Asmbpe(ctxt) } diff --git a/src/cmd/link/internal/x86/obj.go b/src/cmd/link/internal/x86/obj.go index 48335d82f7..d19774795b 100644 --- a/src/cmd/link/internal/x86/obj.go +++ b/src/cmd/link/internal/x86/obj.go @@ -92,13 +92,13 @@ func archinit(ctxt *ld.Link) { got.Attr |= ld.AttrReachable } - switch ld.HEADTYPE { + switch ld.Headtype { default: if ld.Linkmode == ld.LinkAuto { ld.Linkmode = ld.LinkInternal } if ld.Linkmode == ld.LinkExternal && obj.Getgoextlinkenabled() != "1" { - log.Fatalf("cannot use -linkmode=external with -H %s", ld.Headstr(int(ld.HEADTYPE))) + log.Fatalf("cannot use -linkmode=external with -H %s", ld.Headtype) } case obj.Hdarwin, @@ -106,13 +106,14 @@ func archinit(ctxt *ld.Link) { obj.Hlinux, obj.Hnetbsd, obj.Hopenbsd, - obj.Hwindows: + obj.Hwindows, + obj.Hwindowsgui: break } - switch ld.HEADTYPE { + switch ld.Headtype { default: - ld.Exitf("unknown -H option: %v", ld.HEADTYPE) + ld.Exitf("unknown -H option: %v", ld.Headtype) case obj.Hplan9: /* plan 9 */ ld.HEADR = 32 @@ -172,7 +173,7 @@ func archinit(ctxt *ld.Link) { *ld.FlagRound = 0x10000 } - case obj.Hwindows: /* PE executable */ + case obj.Hwindows, obj.Hwindowsgui: /* PE executable */ ld.Peinit(ctxt) ld.HEADR = ld.PEFILEHEADR -- 2.48.1