From: David Crawshaw Date: Wed, 4 Oct 2017 21:54:04 +0000 (-0400) Subject: cmd/link: put symbol data types in new package X-Git-Tag: go1.10beta1~869 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=475d92ba4d5a88b1bba44f80dcd6a2dfc96b948e;p=gostls13.git cmd/link: put symbol data types in new package For #22095 Change-Id: I07c288208d94dabae164c2ca0a067402a8e5c2e6 Reviewed-on: https://go-review.googlesource.com/68331 Run-TryBot: David Crawshaw TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- diff --git a/src/cmd/dist/buildtool.go b/src/cmd/dist/buildtool.go index 94f64be96f..421ab46a27 100644 --- a/src/cmd/dist/buildtool.go +++ b/src/cmd/dist/buildtool.go @@ -70,6 +70,7 @@ var bootstrapDirs = []string{ "cmd/link/internal/mips64", "cmd/link/internal/ppc64", "cmd/link/internal/s390x", + "cmd/link/internal/sym", "cmd/link/internal/x86", "debug/pe", "math/big", diff --git a/src/cmd/link/internal/amd64/asm.go b/src/cmd/link/internal/amd64/asm.go index 2af650aa2b..81e4cce988 100644 --- a/src/cmd/link/internal/amd64/asm.go +++ b/src/cmd/link/internal/amd64/asm.go @@ -34,6 +34,7 @@ import ( "cmd/internal/objabi" "cmd/internal/sys" "cmd/link/internal/ld" + "cmd/link/internal/sym" "debug/elf" "log" ) @@ -42,8 +43,8 @@ func PADDR(x uint32) uint32 { return x &^ 0x80000000 } -func Addcall(ctxt *ld.Link, s *ld.Symbol, t *ld.Symbol) int64 { - s.Attr |= ld.AttrReachable +func Addcall(ctxt *ld.Link, s *sym.Symbol, t *sym.Symbol) int64 { + s.Attr |= sym.AttrReachable i := s.Size s.Size += 4 s.Grow(s.Size) @@ -60,16 +61,16 @@ func gentext(ctxt *ld.Link) { return } addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0) - if addmoduledata.Type == ld.STEXT && ld.Buildmode != ld.BuildmodePlugin { + if addmoduledata.Type == sym.STEXT && ld.Buildmode != ld.BuildmodePlugin { // we're linking a module containing the runtime -> no need for // an init function return } - addmoduledata.Attr |= ld.AttrReachable + addmoduledata.Attr |= sym.AttrReachable initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0) - initfunc.Type = ld.STEXT - initfunc.Attr |= ld.AttrLocal - initfunc.Attr |= ld.AttrReachable + initfunc.Type = sym.STEXT + initfunc.Attr |= sym.AttrLocal + initfunc.Attr |= sym.AttrReachable o := func(op ...uint8) { for _, op1 := range op { initfunc.AddUint8(op1) @@ -91,28 +92,28 @@ func gentext(ctxt *ld.Link) { } ctxt.Textp = append(ctxt.Textp, initfunc) initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0) - initarray_entry.Attr |= ld.AttrReachable - initarray_entry.Attr |= ld.AttrLocal - initarray_entry.Type = ld.SINITARR + initarray_entry.Attr |= sym.AttrReachable + initarray_entry.Attr |= sym.AttrLocal + initarray_entry.Type = sym.SINITARR initarray_entry.AddAddr(ctxt.Arch, initfunc) } -func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { +func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { targ := r.Sym switch r.Type { default: if r.Type >= 256 { - ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, ld.RelocName(ctxt.Arch, r.Type)) + ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type)) return false } // Handle relocations found in ELF object files. case 256 + ld.R_X86_64_PC32: - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { ld.Errorf(s, "unexpected R_X86_64_PC32 relocation for dynamic symbol %s", targ.Name) } - if targ.Type == 0 || targ.Type == ld.SXREF { + if targ.Type == 0 || targ.Type == sym.SXREF { ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name) } r.Type = objabi.R_PCREL @@ -120,10 +121,10 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { return true case 256 + ld.R_X86_64_PC64: - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { ld.Errorf(s, "unexpected R_X86_64_PC64 relocation for dynamic symbol %s", targ.Name) } - if targ.Type == 0 || targ.Type == ld.SXREF { + if targ.Type == 0 || targ.Type == sym.SXREF { ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name) } r.Type = objabi.R_PCREL @@ -133,7 +134,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { case 256 + ld.R_X86_64_PLT32: r.Type = objabi.R_PCREL r.Add += 4 - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { addpltsym(ctxt, targ) r.Sym = ctxt.Syms.Lookup(".plt", 0) r.Add += int64(targ.Plt) @@ -142,7 +143,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { return true case 256 + ld.R_X86_64_GOTPCREL, 256 + ld.R_X86_64_GOTPCRELX, 256 + ld.R_X86_64_REX_GOTPCRELX: - if targ.Type != ld.SDYNIMPORT { + if targ.Type != sym.SDYNIMPORT { // have symbol if r.Off >= 2 && s.P[r.Off-2] == 0x8b { // turn MOVQ of GOT entry into LEAQ of symbol itself @@ -165,7 +166,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { return true case 256 + ld.R_X86_64_64: - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { ld.Errorf(s, "unexpected R_X86_64_64 relocation for dynamic symbol %s", targ.Name) } r.Type = objabi.R_ADDR @@ -178,13 +179,13 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { // TODO: What is the difference between all these? r.Type = objabi.R_ADDR - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { ld.Errorf(s, "unexpected reloc for dynamic symbol %s", targ.Name) } return true case 512 + ld.MACHO_X86_64_RELOC_BRANCH*2 + 1: - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { addpltsym(ctxt, targ) r.Sym = ctxt.Syms.Lookup(".plt", 0) r.Add = int64(targ.Plt) @@ -201,13 +202,13 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { 512 + ld.MACHO_X86_64_RELOC_SIGNED_4*2 + 1: r.Type = objabi.R_PCREL - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { ld.Errorf(s, "unexpected pc-relative reloc for dynamic symbol %s", targ.Name) } return true case 512 + ld.MACHO_X86_64_RELOC_GOT_LOAD*2 + 1: - if targ.Type != ld.SDYNIMPORT { + if targ.Type != sym.SDYNIMPORT { // have symbol // turn MOVQ of GOT entry into LEAQ of symbol itself if r.Off < 2 || s.P[r.Off-2] != 0x8b { @@ -223,7 +224,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { // fall through case 512 + ld.MACHO_X86_64_RELOC_GOT*2 + 1: - if targ.Type != ld.SDYNIMPORT { + if targ.Type != sym.SDYNIMPORT { ld.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", targ.Name) } addgotsym(ctxt, targ) @@ -236,7 +237,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { switch r.Type { case objabi.R_CALL, objabi.R_PCREL: - if targ.Type != ld.SDYNIMPORT { + if targ.Type != sym.SDYNIMPORT { // nothing to do, the relocation will be laid out in reloc return true } @@ -247,7 +248,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { return true case objabi.R_ADDR: - if s.Type == ld.STEXT && ld.Iself { + if s.Type == sym.STEXT && ld.Iself { if ld.Headtype == objabi.Hsolaris { addpltsym(ctxt, targ) r.Sym = ctxt.Syms.Lookup(".plt", 0) @@ -308,7 +309,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { // linking, in which case the relocation will be // prepared in the 'reloc' phase and passed to the // external linker in the 'asmb' phase. - if s.Type != ld.SDATA && s.Type != ld.SRODATA { + if s.Type != sym.SDATA && s.Type != sym.SRODATA { break } } @@ -345,7 +346,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { ld.Adddynsym(ctxt, targ) got := ctxt.Syms.Lookup(".got", 0) - s.Type = got.Type | ld.SSUB + s.Type = got.Type | sym.SSUB s.Outer = got s.Sub = got.Sub got.Sub = s @@ -360,7 +361,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { return false } -func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool { +func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ctxt.Out.Write64(uint64(sectoff)) elfsym := r.Xsym.ElfsymForReloc() @@ -389,7 +390,7 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool { } case objabi.R_CALL: if r.Siz == 4 { - if r.Xsym.Type == ld.SDYNIMPORT { + if r.Xsym.Type == sym.SDYNIMPORT { if ctxt.DynlinkingGo() { ctxt.Out.Write64(ld.R_X86_64_PLT32 | uint64(elfsym)<<32) } else { @@ -403,7 +404,7 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool { } case objabi.R_PCREL: if r.Siz == 4 { - if r.Xsym.Type == ld.SDYNIMPORT && r.Xsym.ElfType == elf.STT_FUNC { + if r.Xsym.Type == sym.SDYNIMPORT && r.Xsym.ElfType == elf.STT_FUNC { ctxt.Out.Write64(ld.R_X86_64_PLT32 | uint64(elfsym)<<32) } else { ctxt.Out.Write64(ld.R_X86_64_PC32 | uint64(elfsym)<<32) @@ -423,14 +424,14 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool { return true } -func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool { +func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { var v uint32 rs := r.Xsym - if rs.Type == ld.SHOSTOBJ || r.Type == objabi.R_PCREL || r.Type == objabi.R_GOTPCREL { + if rs.Type == sym.SHOSTOBJ || r.Type == objabi.R_PCREL || r.Type == objabi.R_GOTPCREL { if rs.Dynid < 0 { - ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type) + ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type) return false } @@ -439,7 +440,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect } else { v = uint32(rs.Sect.Extnum) if v == 0 { - ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type) + ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type) return false } } @@ -486,13 +487,13 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect return true } -func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool { +func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { var v uint32 rs := r.Xsym if rs.Dynid < 0 { - ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type) + ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type) return false } @@ -523,11 +524,11 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff return true } -func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { +func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool { return false } -func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 { +func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { log.Fatalf("unexpected relocation variant") return t } @@ -559,7 +560,7 @@ func elfsetupplt(ctxt *ld.Link) { } } -func addpltsym(ctxt *ld.Link, s *ld.Symbol) { +func addpltsym(ctxt *ld.Link, s *sym.Symbol) { if s.Plt >= 0 { return } @@ -627,7 +628,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) { } } -func addgotsym(ctxt *ld.Link, s *ld.Symbol) { +func addgotsym(ctxt *ld.Link, s *sym.Symbol) { if s.Got >= 0 { return } @@ -838,7 +839,7 @@ func asmb(ctxt *ld.Link) { ctxt.Out.Flush() } -func tlsIEtoLE(s *ld.Symbol, off, size int) { +func tlsIEtoLE(s *sym.Symbol, off, size int) { // Transform the PC-relative instruction into a constant load. // That is, // diff --git a/src/cmd/link/internal/arm/asm.go b/src/cmd/link/internal/arm/asm.go index 58478ddaf3..1c6ce4709f 100644 --- a/src/cmd/link/internal/arm/asm.go +++ b/src/cmd/link/internal/arm/asm.go @@ -34,6 +34,7 @@ import ( "cmd/internal/objabi" "cmd/internal/sys" "cmd/link/internal/ld" + "cmd/link/internal/sym" "fmt" "log" ) @@ -64,16 +65,16 @@ func gentext(ctxt *ld.Link) { return } addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0) - if addmoduledata.Type == ld.STEXT && ld.Buildmode != ld.BuildmodePlugin { + if addmoduledata.Type == sym.STEXT && ld.Buildmode != ld.BuildmodePlugin { // we're linking a module containing the runtime -> no need for // an init function return } - addmoduledata.Attr |= ld.AttrReachable + addmoduledata.Attr |= sym.AttrReachable initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0) - initfunc.Type = ld.STEXT - initfunc.Attr |= ld.AttrLocal - initfunc.Attr |= ld.AttrReachable + initfunc.Type = sym.STEXT + initfunc.Attr |= sym.AttrLocal + initfunc.Attr |= sym.AttrReachable o := func(op uint32) { initfunc.AddUint32(ctxt.Arch, op) } @@ -101,9 +102,9 @@ func gentext(ctxt *ld.Link) { } ctxt.Textp = append(ctxt.Textp, initfunc) initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0) - initarray_entry.Attr |= ld.AttrReachable - initarray_entry.Attr |= ld.AttrLocal - initarray_entry.Type = ld.SINITARR + initarray_entry.Attr |= sym.AttrReachable + initarray_entry.Attr |= sym.AttrLocal + initarray_entry.Type = sym.SINITARR initarray_entry.AddAddr(ctxt.Arch, initfunc) } @@ -113,13 +114,13 @@ func braddoff(a int32, b int32) int32 { return int32((uint32(a))&0xff000000 | 0x00ffffff&uint32(a+b)) } -func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { +func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { targ := r.Sym switch r.Type { default: if r.Type >= 256 { - ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, ld.RelocName(ctxt.Arch, r.Type)) + ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type)) return false } @@ -127,7 +128,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { case 256 + ld.R_ARM_PLT32: r.Type = objabi.R_CALLARM - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { addpltsym(ctxt, targ) r.Sym = ctxt.Syms.Lookup(".plt", 0) r.Add = int64(braddoff(int32(r.Add), targ.Plt/4)) @@ -140,7 +141,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { return false case 256 + ld.R_ARM_GOT32: // R_ARM_GOT_BREL - if targ.Type != ld.SDYNIMPORT { + if targ.Type != sym.SDYNIMPORT { addgotsyminternal(ctxt, targ) } else { addgotsym(ctxt, targ) @@ -152,7 +153,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { return true case 256 + ld.R_ARM_GOT_PREL: // GOT(nil) + A - nil - if targ.Type != ld.SDYNIMPORT { + if targ.Type != sym.SDYNIMPORT { addgotsyminternal(ctxt, targ) } else { addgotsym(ctxt, targ) @@ -177,7 +178,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { case 256 + ld.R_ARM_CALL: r.Type = objabi.R_CALLARM - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { addpltsym(ctxt, targ) r.Sym = ctxt.Syms.Lookup(".plt", 0) r.Add = int64(braddoff(int32(r.Add), targ.Plt/4)) @@ -192,7 +193,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { return true case 256 + ld.R_ARM_ABS32: - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { ld.Errorf(s, "unexpected R_ARM_ABS32 relocation for dynamic symbol %s", targ.Name) } r.Type = objabi.R_ADDR @@ -211,7 +212,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { case 256 + ld.R_ARM_PC24, 256 + ld.R_ARM_JUMP24: r.Type = objabi.R_CALLARM - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { addpltsym(ctxt, targ) r.Sym = ctxt.Syms.Lookup(".plt", 0) r.Add = int64(braddoff(int32(r.Add), targ.Plt/4)) @@ -221,7 +222,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { } // Handle references to ELF symbols from our own object files. - if targ.Type != ld.SDYNIMPORT { + if targ.Type != sym.SDYNIMPORT { return true } @@ -233,7 +234,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { return true case objabi.R_ADDR: - if s.Type != ld.SDATA { + if s.Type != sym.SDATA { break } if ld.Iself { @@ -250,7 +251,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { return false } -func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool { +func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ctxt.Out.Write32(uint32(sectoff)) elfsym := r.Xsym.ElfsymForReloc() @@ -321,13 +322,13 @@ func elfsetupplt(ctxt *ld.Link) { } } -func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool { +func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { var v uint32 rs := r.Xsym if r.Type == objabi.R_PCREL { - if rs.Type == ld.SHOSTOBJ { + if rs.Type == sym.SHOSTOBJ { ld.Errorf(s, "pc-relative relocation of external symbol is not supported") return false } @@ -356,9 +357,9 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect return true } - if rs.Type == ld.SHOSTOBJ || r.Type == objabi.R_CALLARM { + if rs.Type == sym.SHOSTOBJ || r.Type == objabi.R_CALLARM { if rs.Dynid < 0 { - ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type) + ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type) return false } @@ -367,7 +368,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect } else { v = uint32(rs.Sect.Extnum) if v == 0 { - ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type) + ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type) return false } } @@ -422,7 +423,7 @@ func immrot(v uint32) uint32 { } // Convert the direct jump relocation r to refer to a trampoline if the target is too far -func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) { +func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) { switch r.Type { case objabi.R_CALLARM: // r.Add is the instruction @@ -433,11 +434,11 @@ func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) { // look up existing trampolines first. if we found one within the range // of direct call, we can reuse it. otherwise create a new one. offset := (signext24(r.Add&0xffffff) + 2) * 4 - var tramp *ld.Symbol + var tramp *sym.Symbol for i := 0; ; i++ { name := r.Sym.Name + fmt.Sprintf("%+d-tramp%d", offset, i) tramp = ctxt.Syms.Lookup(name, int(r.Sym.Version)) - if tramp.Type == ld.SDYNIMPORT { + if tramp.Type == sym.SDYNIMPORT { // don't reuse trampoline defined in other module continue } @@ -475,12 +476,12 @@ func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) { r.Done = false } default: - ld.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type, ld.RelocName(ctxt.Arch, r.Type)) + ld.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type)) } } // generate a trampoline to target+offset -func gentramp(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) { +func gentramp(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) { tramp.Size = 12 // 3 instructions tramp.P = make([]byte, tramp.Size) t := ld.Symaddr(target) + int64(offset) @@ -502,7 +503,7 @@ func gentramp(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) { } // generate a trampoline to target+offset in position independent code -func gentramppic(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) { +func gentramppic(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) { tramp.Size = 16 // 4 instructions tramp.P = make([]byte, tramp.Size) o1 := uint32(0xe5900000 | 11<<12 | 15<<16 | 4) // MOVW 4(R15), R11 // R15 is actual pc + 8 @@ -523,7 +524,7 @@ func gentramppic(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) { } // generate a trampoline to target+offset in dynlink mode (using GOT) -func gentrampdyn(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) { +func gentrampdyn(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) { tramp.Size = 20 // 5 instructions o1 := uint32(0xe5900000 | 11<<12 | 15<<16 | 8) // MOVW 8(R15), R11 // R15 is actual pc + 8 o2 := uint32(0xe0800000 | 11<<12 | 15<<16 | 11) // ADD R15, R11, R11 @@ -562,7 +563,7 @@ func gentrampdyn(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) { } } -func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { +func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool { if ld.Linkmode == ld.LinkExternal { switch r.Type { case objabi.R_CALLARM: @@ -578,7 +579,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { rs = rs.Outer } - if rs.Type != ld.SHOSTOBJ && rs.Type != ld.SDYNIMPORT && rs.Sect == nil { + if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil { ld.Errorf(s, "missing section for %s", rs.Name) } r.Xsym = rs @@ -642,27 +643,27 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { return false } -func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 { +func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { log.Fatalf("unexpected relocation variant") return t } -func addpltreloc(ctxt *ld.Link, plt *ld.Symbol, got *ld.Symbol, sym *ld.Symbol, typ objabi.RelocType) *ld.Reloc { +func addpltreloc(ctxt *ld.Link, plt *sym.Symbol, got *sym.Symbol, s *sym.Symbol, typ objabi.RelocType) *sym.Reloc { r := plt.AddRel() r.Sym = got r.Off = int32(plt.Size) r.Siz = 4 r.Type = typ - r.Add = int64(sym.Got) - 8 + r.Add = int64(s.Got) - 8 - plt.Attr |= ld.AttrReachable + plt.Attr |= sym.AttrReachable plt.Size += 4 plt.Grow(plt.Size) return r } -func addpltsym(ctxt *ld.Link, s *ld.Symbol) { +func addpltsym(ctxt *ld.Link, s *sym.Symbol) { if s.Plt >= 0 { return } @@ -701,7 +702,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) { } } -func addgotsyminternal(ctxt *ld.Link, s *ld.Symbol) { +func addgotsyminternal(ctxt *ld.Link, s *sym.Symbol) { if s.Got >= 0 { return } @@ -717,7 +718,7 @@ func addgotsyminternal(ctxt *ld.Link, s *ld.Symbol) { } } -func addgotsym(ctxt *ld.Link, s *ld.Symbol) { +func addgotsym(ctxt *ld.Link, s *sym.Symbol) { if s.Got >= 0 { return } diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go index 2d910f006c..64899b46c3 100644 --- a/src/cmd/link/internal/arm64/asm.go +++ b/src/cmd/link/internal/arm64/asm.go @@ -34,6 +34,7 @@ import ( "cmd/internal/objabi" "cmd/internal/sys" "cmd/link/internal/ld" + "cmd/link/internal/sym" "encoding/binary" "fmt" "log" @@ -44,16 +45,16 @@ func gentext(ctxt *ld.Link) { return } addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0) - if addmoduledata.Type == ld.STEXT { + if addmoduledata.Type == sym.STEXT { // we're linking a module containing the runtime -> no need for // an init function return } - addmoduledata.Attr |= ld.AttrReachable + addmoduledata.Attr |= sym.AttrReachable initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0) - initfunc.Type = ld.STEXT - initfunc.Attr |= ld.AttrLocal - initfunc.Attr |= ld.AttrReachable + initfunc.Type = sym.STEXT + initfunc.Attr |= sym.AttrLocal + initfunc.Attr |= sym.AttrReachable o := func(op uint32) { initfunc.AddUint32(ctxt.Arch, op) } @@ -81,18 +82,18 @@ func gentext(ctxt *ld.Link) { ctxt.Textp = append(ctxt.Textp, initfunc) initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0) - initarray_entry.Attr |= ld.AttrReachable - initarray_entry.Attr |= ld.AttrLocal - initarray_entry.Type = ld.SINITARR + initarray_entry.Attr |= sym.AttrReachable + initarray_entry.Attr |= sym.AttrLocal + initarray_entry.Type = sym.SINITARR initarray_entry.AddAddr(ctxt.Arch, initfunc) } -func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { +func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { log.Fatalf("adddynrel not implemented") return false } -func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool { +func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ctxt.Out.Write64(uint64(sectoff)) elfsym := r.Xsym.ElfsymForReloc() @@ -143,7 +144,7 @@ func elfsetupplt(ctxt *ld.Link) { return } -func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool { +func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { var v uint32 rs := r.Xsym @@ -151,9 +152,9 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect // ld64 has a bug handling MACHO_ARM64_RELOC_UNSIGNED with !extern relocation. // see cmd/internal/ld/data.go for details. The workaround is that don't use !extern // UNSIGNED relocation at all. - if rs.Type == ld.SHOSTOBJ || r.Type == objabi.R_CALLARM64 || r.Type == objabi.R_ADDRARM64 || r.Type == objabi.R_ADDR { + if rs.Type == sym.SHOSTOBJ || r.Type == objabi.R_CALLARM64 || r.Type == objabi.R_ADDRARM64 || r.Type == objabi.R_ADDR { if rs.Dynid < 0 { - ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type) + ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type) return false } @@ -162,7 +163,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect } else { v = uint32(rs.Sect.Extnum) if v == 0 { - ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type) + ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type) return false } } @@ -215,7 +216,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect return true } -func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { +func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool { if ld.Linkmode == ld.LinkExternal { switch r.Type { default: @@ -237,7 +238,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { // (https://sourceware.org/bugzilla/show_bug.cgi?id=18270). So // we convert the adrp; ld64 + R_ARM64_GOTPCREL into adrp; // add + R_ADDRARM64. - if !(r.Sym.Version != 0 || (r.Sym.Type&ld.SHIDDEN != 0) || r.Sym.Attr.Local()) && r.Sym.Type == ld.STEXT && ctxt.DynlinkingGo() { + if !(r.Sym.Version != 0 || (r.Sym.Type&sym.SHIDDEN != 0) || r.Sym.Attr.Local()) && r.Sym.Type == sym.STEXT && ctxt.DynlinkingGo() { if o2&0xffc00000 != 0xf9400000 { ld.Errorf(s, "R_ARM64_GOTPCREL against unexpected instruction %x", o2) } @@ -261,7 +262,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { rs = rs.Outer } - if rs.Type != ld.SHOSTOBJ && rs.Type != ld.SDYNIMPORT && rs.Sect == nil { + if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil { ld.Errorf(s, "missing section for %s", rs.Name) } r.Xsym = rs @@ -367,7 +368,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { return false } -func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 { +func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { log.Fatalf("unexpected relocation variant") return -1 } diff --git a/src/cmd/link/internal/ld/ar.go b/src/cmd/link/internal/ld/ar.go index c8115a67d7..31374d0635 100644 --- a/src/cmd/link/internal/ld/ar.go +++ b/src/cmd/link/internal/ld/ar.go @@ -33,6 +33,7 @@ package ld import ( "cmd/internal/bio" "cmd/internal/objabi" + "cmd/link/internal/sym" "encoding/binary" "fmt" "io" @@ -105,7 +106,7 @@ func hostArchive(ctxt *Link, name string) { var load []uint64 for _, s := range ctxt.Syms.Allsym { for _, r := range s.R { - if r.Sym != nil && r.Sym.Type&SMASK == SXREF { + if r.Sym != nil && r.Sym.Type&sym.SMASK == sym.SXREF { if off := armap[r.Sym.Name]; off != 0 && !loaded[off] { load = append(load, off) loaded[off] = true diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index 2642c030e7..8bb6aa6040 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -35,6 +35,7 @@ import ( "cmd/internal/gcprog" "cmd/internal/objabi" "cmd/internal/sys" + "cmd/link/internal/sym" "fmt" "log" "os" @@ -45,11 +46,11 @@ import ( ) /* - * divide-and-conquer list-link (by Sub) sort of Symbol* by Value. + * divide-and-conquer list-link (by Sub) sort of sym.Symbol* by Value. * Used for sub-symbols when loading host objects (see e.g. ldelf.go). */ -func listsort(l *Symbol) *Symbol { +func listsort(l *sym.Symbol) *sym.Symbol { if l == nil || l.Sub == nil { return l } @@ -134,7 +135,7 @@ func isRuntimeDepPkg(pkg string) bool { // Estimate the max size needed to hold any new trampolines created for this function. This // is used to determine when the section can be split if it becomes too large, to ensure that // the trampolines are in the same section as the function that uses them. -func maxSizeTrampolinesPPC64(s *Symbol, isTramp bool) uint64 { +func maxSizeTrampolinesPPC64(s *sym.Symbol, isTramp bool) uint64 { // If Thearch.Trampoline is nil, then trampoline support is not available on this arch. // A trampoline does not need any dependent trampolines. if Thearch.Trampoline == nil || isTramp { @@ -156,7 +157,7 @@ func maxSizeTrampolinesPPC64(s *Symbol, isTramp bool) uint64 { // ARM, PPC64 & PPC64LE support trampoline insertion for internal and external linking // On PPC64 & PPC64LE the text sections might be split but will still insert trampolines // where necessary. -func trampoline(ctxt *Link, s *Symbol) { +func trampoline(ctxt *Link, s *sym.Symbol) { if Thearch.Trampoline == nil { return // no need or no support of trampolines on this arch } @@ -166,7 +167,7 @@ func trampoline(ctxt *Link, s *Symbol) { if !r.Type.IsDirectJump() { continue } - if Symaddr(r.Sym) == 0 && r.Sym.Type != SDYNIMPORT { + if Symaddr(r.Sym) == 0 && r.Sym.Type != sym.SDYNIMPORT { if r.Sym.File != s.File { if !isRuntimeDepPkg(s.File) || !isRuntimeDepPkg(r.Sym.File) { Errorf(s, "unresolved inter-package jump to %s(%s)", r.Sym, r.Sym.File) @@ -183,7 +184,7 @@ func trampoline(ctxt *Link, s *Symbol) { } // resolve relocations in s. -func relocsym(ctxt *Link, s *Symbol) { +func relocsym(ctxt *Link, s *sym.Symbol) { for ri := int32(0); ri < int32(len(s.R)); ri++ { r := &s.R[ri] r.Done = true @@ -198,12 +199,12 @@ func relocsym(ctxt *Link, s *Symbol) { continue } - if r.Sym != nil && (r.Sym.Type&(SMASK|SHIDDEN) == 0 || r.Sym.Type&SMASK == SXREF) { + if r.Sym != nil && (r.Sym.Type&(sym.SMASK|sym.SHIDDEN) == 0 || r.Sym.Type&sym.SMASK == sym.SXREF) { // When putting the runtime but not main into a shared library // these symbols are undefined and that's OK. if Buildmode == BuildmodeShared { if r.Sym.Name == "main.main" || r.Sym.Name == "main.init" { - r.Sym.Type = SDYNIMPORT + r.Sym.Type = sym.SDYNIMPORT } else if strings.HasPrefix(r.Sym.Name, "go.info.") { // Skip go.info symbols. They are only needed to communicate // DWARF info between the compiler and linker. @@ -224,12 +225,12 @@ 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 != objabi.Hsolaris && r.Sym != nil && r.Sym.Type == SDYNIMPORT && !ctxt.DynlinkingGo() { + if Headtype != objabi.Hsolaris && r.Sym != nil && r.Sym.Type == sym.SDYNIMPORT && !ctxt.DynlinkingGo() { if !(ctxt.Arch.Family == sys.PPC64 && Linkmode == LinkExternal && r.Sym.Name == ".TOC.") { - Errorf(s, "unhandled relocation for %s (type %d (%s) rtype %d (%s))", r.Sym.Name, r.Sym.Type, r.Sym.Type, r.Type, RelocName(ctxt.Arch, r.Type)) + Errorf(s, "unhandled relocation for %s (type %d (%s) rtype %d (%s))", r.Sym.Name, r.Sym.Type, r.Sym.Type, r.Type, sym.RelocName(ctxt.Arch, r.Type)) } } - if r.Sym != nil && r.Sym.Type != STLSBSS && r.Type != objabi.R_WEAKADDROFF && !r.Sym.Attr.Reachable() { + if r.Sym != nil && r.Sym.Type != sym.STLSBSS && r.Type != objabi.R_WEAKADDROFF && !r.Sym.Attr.Reachable() { Errorf(s, "unreachable sym in relocation: %s", r.Sym.Name) } @@ -238,9 +239,9 @@ func relocsym(ctxt *Link, s *Symbol) { switch r.Type { case objabi.R_PCRELDBL: r.Type = objabi.R_PCREL - r.Variant = RV_390_DBL + r.Variant = sym.RV_390_DBL case objabi.R_CALL: - r.Variant = RV_390_DBL + r.Variant = sym.RV_390_DBL } } @@ -260,7 +261,7 @@ func relocsym(ctxt *Link, s *Symbol) { o = int64(ctxt.Arch.ByteOrder.Uint64(s.P[off:])) } if !Thearch.Archreloc(ctxt, r, s, &o) { - Errorf(s, "unknown reloc to %v: %d (%s)", r.Sym.Name, r.Type, RelocName(ctxt.Arch, r.Type)) + Errorf(s, "unknown reloc to %v: %d (%s)", r.Sym.Name, r.Type, sym.RelocName(ctxt.Arch, r.Type)) } case objabi.R_TLS_LE: isAndroidX86 := objabi.GOOS == "android" && (ctxt.Arch.InFamily(sys.AMD64, sys.I386)) @@ -326,7 +327,7 @@ func relocsym(ctxt *Link, s *Symbol) { log.Fatalf("cannot handle R_TLS_IE (sym %s) when linking internally", s.Name) } case objabi.R_ADDR: - if Linkmode == LinkExternal && r.Sym.Type != SCONST { + if Linkmode == LinkExternal && r.Sym.Type != sym.SCONST { r.Done = false // set up addend for eventual relocation via outer symbol. @@ -338,7 +339,7 @@ func relocsym(ctxt *Link, s *Symbol) { rs = rs.Outer } - if rs.Type != SHOSTOBJ && rs.Type != SDYNIMPORT && rs.Sect == nil { + if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil { Errorf(s, "missing section for relocation target %s", rs.Name) } r.Xsym = rs @@ -354,7 +355,7 @@ func relocsym(ctxt *Link, s *Symbol) { // table, then it will add o twice into the relocated value. // The workaround is that on arm64 don't ever add symaddr to o and always use // extern relocation by requiring rs->dynid >= 0. - if rs.Type != SHOSTOBJ { + if rs.Type != sym.SHOSTOBJ { if ctxt.Arch.Family == sys.ARM64 && rs.Dynid < 0 { Errorf(s, "R_ADDR reloc to %s+%d is not supported on darwin/arm64", rs.Name, o) } @@ -425,7 +426,7 @@ func relocsym(ctxt *Link, s *Symbol) { // r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call. case objabi.R_GOTPCREL: - if ctxt.DynlinkingGo() && Headtype == objabi.Hdarwin && r.Sym != nil && r.Sym.Type != SCONST { + if ctxt.DynlinkingGo() && Headtype == objabi.Hdarwin && r.Sym != nil && r.Sym.Type != sym.SCONST { r.Done = false r.Xadd = r.Add r.Xadd -= int64(r.Siz) // relative to address after the relocated chunk @@ -437,7 +438,7 @@ func relocsym(ctxt *Link, s *Symbol) { } fallthrough case objabi.R_CALL, objabi.R_PCREL: - if Linkmode == LinkExternal && r.Sym != nil && r.Sym.Type != SCONST && (r.Sym.Sect != s.Sect || r.Type == objabi.R_GOTPCREL) { + if Linkmode == LinkExternal && r.Sym != nil && r.Sym.Type != sym.SCONST && (r.Sym.Sect != s.Sect || r.Type == objabi.R_GOTPCREL) { r.Done = false // set up addend for eventual relocation via outer symbol. @@ -450,7 +451,7 @@ func relocsym(ctxt *Link, s *Symbol) { } r.Xadd -= int64(r.Siz) // relative to address after the relocated chunk - if rs.Type != SHOSTOBJ && rs.Type != SDYNIMPORT && rs.Sect == nil { + if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil { Errorf(s, "missing section for relocation target %s", rs.Name) } r.Xsym = rs @@ -462,7 +463,7 @@ func relocsym(ctxt *Link, s *Symbol) { } } else if Headtype == objabi.Hdarwin { if r.Type == objabi.R_CALL { - if rs.Type != SHOSTOBJ { + if rs.Type != sym.SHOSTOBJ { o += int64(uint64(Symaddr(rs)) - rs.Sect.Vaddr) } o -= int64(r.Off) // relative to section offset, not symbol @@ -493,7 +494,7 @@ func relocsym(ctxt *Link, s *Symbol) { o = r.Sym.Size + r.Add } - if r.Variant != RV_NONE { + if r.Variant != sym.RV_NONE { o = Thearch.Archrelocvariant(ctxt, r, s, o) } @@ -502,7 +503,7 @@ func relocsym(ctxt *Link, s *Symbol) { if r.Sym != nil { nam = r.Sym.Name } - fmt.Printf("relocate %s %#x (%#x+%#x, size %d) => %s %#x +%#x [type %d (%s)/%d, %x]\n", s.Name, s.Value+int64(off), s.Value, r.Off, r.Siz, nam, Symaddr(r.Sym), r.Add, r.Type, RelocName(ctxt.Arch, r.Type), r.Variant, o) + fmt.Printf("relocate %s %#x (%#x+%#x, size %d) => %s %#x +%#x [type %d (%s)/%d, %x]\n", s.Name, s.Value+int64(off), s.Value, r.Off, r.Siz, nam, Symaddr(r.Sym), r.Add, r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Variant, o) } switch siz { default: @@ -545,15 +546,15 @@ func (ctxt *Link) reloc() { for _, s := range ctxt.Textp { relocsym(ctxt, s) } - for _, sym := range datap { - relocsym(ctxt, sym) + for _, s := range datap { + relocsym(ctxt, s) } for _, s := range dwarfp { relocsym(ctxt, s) } } -func windynrelocsym(ctxt *Link, s *Symbol) { +func windynrelocsym(ctxt *Link, s *sym.Symbol) { rel := ctxt.Syms.Lookup(".rel", 0) if s == rel { return @@ -596,7 +597,7 @@ func windynrelocsym(ctxt *Link, s *Symbol) { } } -func dynrelocsym(ctxt *Link, s *Symbol) { +func dynrelocsym(ctxt *Link, s *sym.Symbol) { if Headtype == objabi.Hwindows { if Linkmode == LinkInternal { windynrelocsym(ctxt, s) @@ -613,18 +614,18 @@ func dynrelocsym(ctxt *Link, s *Symbol) { Thearch.Adddynrel(ctxt, s, r) continue } - if r.Sym != nil && r.Sym.Type == SDYNIMPORT || r.Type >= 256 { + if r.Sym != nil && r.Sym.Type == sym.SDYNIMPORT || r.Type >= 256 { if r.Sym != nil && !r.Sym.Attr.Reachable() { Errorf(s, "dynamic relocation to unreachable symbol %s", r.Sym.Name) } if !Thearch.Adddynrel(ctxt, s, r) { - Errorf(s, "unsupported dynamic relocation for symbol %s (type=%d (%s) stype=%d (%s))", r.Sym.Name, r.Type, RelocName(ctxt.Arch, r.Type), r.Sym.Type, r.Sym.Type) + Errorf(s, "unsupported dynamic relocation for symbol %s (type=%d (%s) stype=%d (%s))", r.Sym.Name, r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Sym.Type, r.Sym.Type) } } } } -func dynreloc(ctxt *Link, data *[SXREF][]*Symbol) { +func dynreloc(ctxt *Link, data *[sym.SXREF][]*sym.Symbol) { // -d suppresses dynamic loader format, so we may as well not // compute these sections or mark their symbols as reachable. if *FlagD && Headtype != objabi.Hwindows { @@ -638,8 +639,8 @@ func dynreloc(ctxt *Link, data *[SXREF][]*Symbol) { dynrelocsym(ctxt, s) } for _, syms := range data { - for _, sym := range syms { - dynrelocsym(ctxt, sym) + for _, s := range syms { + dynrelocsym(ctxt, s) } } if Iself { @@ -663,11 +664,11 @@ func CodeblkPad(ctxt *Link, addr int64, size int64, pad []byte) { } syms := ctxt.Textp - for i, sym := range syms { - if !sym.Attr.Reachable() { + for i, s := range syms { + if !s.Attr.Reachable() { continue } - if sym.Value >= addr { + if s.Value >= addr { syms = syms[i:] break } @@ -675,24 +676,24 @@ func CodeblkPad(ctxt *Link, addr int64, size int64, pad []byte) { eaddr := addr + size var q []byte - for _, sym := range syms { - if !sym.Attr.Reachable() { + for _, s := range syms { + if !s.Attr.Reachable() { continue } - if sym.Value >= eaddr { + if s.Value >= eaddr { break } - if addr < sym.Value { + if addr < s.Value { ctxt.Logf("%-20s %.8x|", "_", uint64(addr)) - for ; addr < sym.Value; addr++ { + for ; addr < s.Value; addr++ { ctxt.Logf(" %.2x", 0) } ctxt.Logf("\n") } - ctxt.Logf("%.6x\t%-20s\n", uint64(addr), sym.Name) - q = sym.P + ctxt.Logf("%.6x\t%-20s\n", uint64(addr), s.Name) + q = s.P for len(q) >= 16 { ctxt.Logf("%.6x\t% x\n", uint64(addr), q[:16]) @@ -714,9 +715,9 @@ func CodeblkPad(ctxt *Link, addr int64, size int64, pad []byte) { } } -func blk(ctxt *Link, syms []*Symbol, addr, size int64, pad []byte) { +func blk(ctxt *Link, syms []*sym.Symbol, addr, size int64, pad []byte) { for i, s := range syms { - if s.Type&SSUB == 0 && s.Value >= addr { + if s.Type&sym.SSUB == 0 && s.Value >= addr { syms = syms[i:] break } @@ -724,7 +725,7 @@ func blk(ctxt *Link, syms []*Symbol, addr, size int64, pad []byte) { eaddr := addr + size for _, s := range syms { - if s.Type&SSUB != 0 { + if s.Type&sym.SSUB != 0 { continue } if s.Value >= eaddr { @@ -840,7 +841,7 @@ func Dwarfblk(ctxt *Link, addr int64, size int64) { var zeros [512]byte -var strdata []*Symbol +var strdata []*sym.Symbol func addstrdata1(ctxt *Link, arg string) { eq := strings.IndexByte(arg, '=') @@ -860,11 +861,11 @@ func addstrdata(ctxt *Link, name string, value string) { sp := ctxt.Syms.Lookup(p, 0) Addstring(sp, value) - sp.Type = SRODATA + sp.Type = sym.SRODATA s := ctxt.Syms.Lookup(name, 0) s.Size = 0 - s.Attr |= AttrDuplicateOK + s.Attr |= sym.AttrDuplicateOK reachable := s.Attr.Reachable() s.AddAddr(ctxt.Arch, sp) s.AddUint(ctxt.Arch, uint64(len(value))) @@ -872,16 +873,16 @@ func addstrdata(ctxt *Link, name string, value string) { // addstring, addaddr, etc., mark the symbols as reachable. // In this case that is not necessarily true, so stick to what // we know before entering this function. - s.Attr.Set(AttrReachable, reachable) + s.Attr.Set(sym.AttrReachable, reachable) strdata = append(strdata, s) - sp.Attr.Set(AttrReachable, reachable) + sp.Attr.Set(sym.AttrReachable, reachable) } func (ctxt *Link) checkstrdata() { for _, s := range strdata { - if s.Type == STEXT { + if s.Type == sym.STEXT { Errorf(s, "cannot use -X with text symbol") } else if s.Gotype != nil && s.Gotype.Name != "type.string" { Errorf(s, "cannot use -X with non-string symbol") @@ -889,11 +890,11 @@ func (ctxt *Link) checkstrdata() { } } -func Addstring(s *Symbol, str string) int64 { +func Addstring(s *sym.Symbol, str string) int64 { if s.Type == 0 { - s.Type = SNOPTRDATA + s.Type = sym.SNOPTRDATA } - s.Attr |= AttrReachable + s.Attr |= sym.AttrReachable r := s.Size if s.Name == ".shstrtab" { elfsetstring(s, str, int(r)) @@ -906,26 +907,26 @@ func Addstring(s *Symbol, str string) int64 { // addgostring adds str, as a Go string value, to s. symname is the name of the // symbol used to define the string data and must be unique per linked object. -func addgostring(ctxt *Link, s *Symbol, symname, str string) { - sym := ctxt.Syms.Lookup(symname, 0) - if sym.Type != Sxxx { +func addgostring(ctxt *Link, s *sym.Symbol, symname, str string) { + sdata := ctxt.Syms.Lookup(symname, 0) + if sdata.Type != sym.Sxxx { Errorf(s, "duplicate symname in addgostring: %s", symname) } - sym.Attr |= AttrReachable - sym.Attr |= AttrLocal - sym.Type = SRODATA - sym.Size = int64(len(str)) - sym.P = []byte(str) - s.AddAddr(ctxt.Arch, sym) + sdata.Attr |= sym.AttrReachable + sdata.Attr |= sym.AttrLocal + sdata.Type = sym.SRODATA + sdata.Size = int64(len(str)) + sdata.P = []byte(str) + s.AddAddr(ctxt.Arch, sdata) s.AddUint(ctxt.Arch, uint64(len(str))) } -func addinitarrdata(ctxt *Link, s *Symbol) { +func addinitarrdata(ctxt *Link, s *sym.Symbol) { p := s.Name + ".ptr" sp := ctxt.Syms.Lookup(p, 0) - sp.Type = SINITARR + sp.Type = sym.SINITARR sp.Size = 0 - sp.Attr |= AttrDuplicateOK + sp.Attr |= sym.AttrDuplicateOK sp.AddAddr(ctxt.Arch, s) } @@ -943,7 +944,7 @@ func dosymtype(ctxt *Link) { } // symalign returns the required alignment for the given symbol s. -func symalign(s *Symbol) int32 { +func symalign(s *sym.Symbol) int32 { min := int32(Thearch.Minalign) if s.Align >= min { return s.Align @@ -962,7 +963,7 @@ func symalign(s *Symbol) int32 { return align } -func aligndatsize(datsize int64, s *Symbol) int64 { +func aligndatsize(datsize int64, s *sym.Symbol) int64 { return Rnd(datsize, int64(symalign(s))) } @@ -970,7 +971,7 @@ const debugGCProg = false type GCProg struct { ctxt *Link - sym *Symbol + sym *sym.Symbol w gcprog.Writer } @@ -998,9 +999,9 @@ func (p *GCProg) End(size int64) { } } -func (p *GCProg) AddSym(s *Symbol) { +func (p *GCProg) AddSym(s *sym.Symbol) { typ := s.Gotype - // Things without pointers should be in SNOPTRDATA or SNOPTRBSS; + // Things without pointers should be in sym.SNOPTRDATA or sym.SNOPTRBSS; // everything we see should have pointers and should therefore have a type. if typ == nil { switch s.Name { @@ -1038,12 +1039,12 @@ func (p *GCProg) AddSym(s *Symbol) { p.w.Append(prog[4:], nptr) } -// dataSortKey is used to sort a slice of data symbol *Symbol pointers. +// dataSortKey is used to sort a slice of data symbol *sym.Symbol pointers. // The sort keys are kept inline to improve cache behavior while sorting. type dataSortKey struct { size int64 name string - sym *Symbol + sym *sym.Symbol } type bySizeAndName []dataSortKey @@ -1060,7 +1061,7 @@ func (d bySizeAndName) Less(i, j int) bool { const cutoff int64 = 2e9 // 2 GB (or so; looks better in errors than 2^31) -func checkdatsize(ctxt *Link, datsize int64, symn SymKind) { +func checkdatsize(ctxt *Link, datsize int64, symn sym.SymKind) { if datsize > cutoff { Errorf(nil, "too much data in section %v (over %d bytes)", symn, cutoff) } @@ -1068,7 +1069,7 @@ func checkdatsize(ctxt *Link, datsize int64, symn SymKind) { // datap is a collection of reachable data symbols in address order. // Generated by dodata. -var datap []*Symbol +var datap []*sym.Symbol func (ctxt *Link) dodata() { if ctxt.Debugvlog != 0 { @@ -1095,33 +1096,33 @@ func (ctxt *Link) dodata() { // as normal symbols, and give them a little size. bss := ctxt.Syms.Lookup("runtime.bss", 0) bss.Size = 8 - bss.Attr.Set(AttrSpecial, false) + bss.Attr.Set(sym.AttrSpecial, false) - ctxt.Syms.Lookup("runtime.ebss", 0).Attr.Set(AttrSpecial, false) + ctxt.Syms.Lookup("runtime.ebss", 0).Attr.Set(sym.AttrSpecial, false) data := ctxt.Syms.Lookup("runtime.data", 0) data.Size = 8 - data.Attr.Set(AttrSpecial, false) + data.Attr.Set(sym.AttrSpecial, false) - ctxt.Syms.Lookup("runtime.edata", 0).Attr.Set(AttrSpecial, false) + ctxt.Syms.Lookup("runtime.edata", 0).Attr.Set(sym.AttrSpecial, false) types := ctxt.Syms.Lookup("runtime.types", 0) - types.Type = STYPE + types.Type = sym.STYPE types.Size = 8 - types.Attr.Set(AttrSpecial, false) + types.Attr.Set(sym.AttrSpecial, false) etypes := ctxt.Syms.Lookup("runtime.etypes", 0) - etypes.Type = SFUNCTAB - etypes.Attr.Set(AttrSpecial, false) + etypes.Type = sym.SFUNCTAB + etypes.Attr.Set(sym.AttrSpecial, false) } // Collect data symbols by type into data. - var data [SXREF][]*Symbol + var data [sym.SXREF][]*sym.Symbol for _, s := range ctxt.Syms.Allsym { if !s.Attr.Reachable() || s.Attr.Special() { continue } - if s.Type <= STEXT || s.Type >= SXREF { + if s.Type <= sym.STEXT || s.Type >= sym.SXREF { continue } data[s.Type] = append(data[s.Type], s) @@ -1142,16 +1143,16 @@ func (ctxt *Link) dodata() { // "read only" data with relocations needs to go in its own section // when building a shared library. We do this by boosting objects of // type SXXX with relocations to type SXXXRELRO. - for _, symnro := range readOnly { - symnrelro := relROMap[symnro] + for _, symnro := range sym.ReadOnly { + symnrelro := sym.RelROMap[symnro] - ro := []*Symbol{} + ro := []*sym.Symbol{} relro := data[symnrelro] for _, s := range data[symnro] { isRelro := len(s.R) > 0 switch s.Type { - case STYPE, STYPERELRO, SGOFUNCRELRO: + case sym.STYPE, sym.STYPERELRO, sym.SGOFUNCRELRO: // Symbols are not sorted yet, so it is possible // that an Outer symbol has been changed to a // relro Type before it reaches here. @@ -1185,10 +1186,10 @@ func (ctxt *Link) dodata() { } // Sort symbols. - var dataMaxAlign [SXREF]int32 + var dataMaxAlign [sym.SXREF]int32 var wg sync.WaitGroup for symn := range data { - symn := SymKind(symn) + symn := sym.SymKind(symn) wg.Add(1) go func() { data[symn], dataMaxAlign[symn] = dodataSect(ctxt, symn, data[symn]) @@ -1204,11 +1205,11 @@ func (ctxt *Link) dodata() { datsize := int64(0) // Writable data sections that do not need any specialized handling. - writable := []SymKind{ - SELFSECT, - SMACHO, - SMACHOGOT, - SWINDOWS, + writable := []sym.SymKind{ + sym.SELFSECT, + sym.SMACHO, + sym.SMACHOGOT, + sym.SWINDOWS, } for _, symn := range writable { for _, s := range data[symn] { @@ -1217,7 +1218,7 @@ func (ctxt *Link) dodata() { datsize = Rnd(datsize, int64(sect.Align)) sect.Vaddr = uint64(datsize) s.Sect = sect - s.Type = SDATA + s.Type = sym.SDATA s.Value = int64(uint64(datsize) - sect.Vaddr) datsize += s.Size sect.Length = uint64(datsize) - sect.Vaddr @@ -1226,16 +1227,16 @@ func (ctxt *Link) dodata() { } // .got (and .toc on ppc64) - if len(data[SELFGOT]) > 0 { + if len(data[sym.SELFGOT]) > 0 { sect := addsection(ctxt.Arch, &Segdata, ".got", 06) - sect.Align = dataMaxAlign[SELFGOT] + sect.Align = dataMaxAlign[sym.SELFGOT] datsize = Rnd(datsize, int64(sect.Align)) sect.Vaddr = uint64(datsize) - var toc *Symbol - for _, s := range data[SELFGOT] { + var toc *sym.Symbol + for _, s := range data[sym.SELFGOT] { datsize = aligndatsize(datsize, s) s.Sect = sect - s.Type = SDATA + s.Type = sym.SDATA s.Value = int64(uint64(datsize) - sect.Vaddr) // Resolve .TOC. symbol for this object file (ppc64) @@ -1251,25 +1252,25 @@ func (ctxt *Link) dodata() { datsize += s.Size } - checkdatsize(ctxt, datsize, SELFGOT) + checkdatsize(ctxt, datsize, sym.SELFGOT) sect.Length = uint64(datsize) - sect.Vaddr } /* pointer-free data */ sect := addsection(ctxt.Arch, &Segdata, ".noptrdata", 06) - sect.Align = dataMaxAlign[SNOPTRDATA] + sect.Align = dataMaxAlign[sym.SNOPTRDATA] datsize = Rnd(datsize, int64(sect.Align)) sect.Vaddr = uint64(datsize) ctxt.Syms.Lookup("runtime.noptrdata", 0).Sect = sect ctxt.Syms.Lookup("runtime.enoptrdata", 0).Sect = sect - for _, s := range data[SNOPTRDATA] { + for _, s := range data[sym.SNOPTRDATA] { datsize = aligndatsize(datsize, s) s.Sect = sect - s.Type = SDATA + s.Type = sym.SDATA s.Value = int64(uint64(datsize) - sect.Vaddr) datsize += s.Size } - checkdatsize(ctxt, datsize, SNOPTRDATA) + checkdatsize(ctxt, datsize, sym.SNOPTRDATA) sect.Length = uint64(datsize) - sect.Vaddr hasinitarr := *FlagLinkshared @@ -1281,68 +1282,68 @@ func (ctxt *Link) dodata() { } if hasinitarr { sect := addsection(ctxt.Arch, &Segdata, ".init_array", 06) - sect.Align = dataMaxAlign[SINITARR] + sect.Align = dataMaxAlign[sym.SINITARR] datsize = Rnd(datsize, int64(sect.Align)) sect.Vaddr = uint64(datsize) - for _, s := range data[SINITARR] { + for _, s := range data[sym.SINITARR] { datsize = aligndatsize(datsize, s) s.Sect = sect s.Value = int64(uint64(datsize) - sect.Vaddr) datsize += s.Size } sect.Length = uint64(datsize) - sect.Vaddr - checkdatsize(ctxt, datsize, SINITARR) + checkdatsize(ctxt, datsize, sym.SINITARR) } /* data */ sect = addsection(ctxt.Arch, &Segdata, ".data", 06) - sect.Align = dataMaxAlign[SDATA] + sect.Align = dataMaxAlign[sym.SDATA] datsize = Rnd(datsize, int64(sect.Align)) sect.Vaddr = uint64(datsize) ctxt.Syms.Lookup("runtime.data", 0).Sect = sect ctxt.Syms.Lookup("runtime.edata", 0).Sect = sect var gc GCProg gc.Init(ctxt, "runtime.gcdata") - for _, s := range data[SDATA] { + for _, s := range data[sym.SDATA] { s.Sect = sect - s.Type = SDATA + s.Type = sym.SDATA datsize = aligndatsize(datsize, s) s.Value = int64(uint64(datsize) - sect.Vaddr) gc.AddSym(s) datsize += s.Size } - checkdatsize(ctxt, datsize, SDATA) + checkdatsize(ctxt, datsize, sym.SDATA) sect.Length = uint64(datsize) - sect.Vaddr gc.End(int64(sect.Length)) /* bss */ sect = addsection(ctxt.Arch, &Segdata, ".bss", 06) - sect.Align = dataMaxAlign[SBSS] + sect.Align = dataMaxAlign[sym.SBSS] datsize = Rnd(datsize, int64(sect.Align)) sect.Vaddr = uint64(datsize) ctxt.Syms.Lookup("runtime.bss", 0).Sect = sect ctxt.Syms.Lookup("runtime.ebss", 0).Sect = sect gc = GCProg{} gc.Init(ctxt, "runtime.gcbss") - for _, s := range data[SBSS] { + for _, s := range data[sym.SBSS] { s.Sect = sect datsize = aligndatsize(datsize, s) s.Value = int64(uint64(datsize) - sect.Vaddr) gc.AddSym(s) datsize += s.Size } - checkdatsize(ctxt, datsize, SBSS) + checkdatsize(ctxt, datsize, sym.SBSS) sect.Length = uint64(datsize) - sect.Vaddr gc.End(int64(sect.Length)) /* pointer-free bss */ sect = addsection(ctxt.Arch, &Segdata, ".noptrbss", 06) - sect.Align = dataMaxAlign[SNOPTRBSS] + sect.Align = dataMaxAlign[sym.SNOPTRBSS] datsize = Rnd(datsize, int64(sect.Align)) sect.Vaddr = uint64(datsize) ctxt.Syms.Lookup("runtime.noptrbss", 0).Sect = sect ctxt.Syms.Lookup("runtime.enoptrbss", 0).Sect = sect - for _, s := range data[SNOPTRBSS] { + for _, s := range data[sym.SNOPTRBSS] { datsize = aligndatsize(datsize, s) s.Sect = sect s.Value = int64(uint64(datsize) - sect.Vaddr) @@ -1351,10 +1352,10 @@ func (ctxt *Link) dodata() { sect.Length = uint64(datsize) - sect.Vaddr ctxt.Syms.Lookup("runtime.end", 0).Sect = sect - checkdatsize(ctxt, datsize, SNOPTRBSS) + checkdatsize(ctxt, datsize, sym.SNOPTRBSS) - if len(data[STLSBSS]) > 0 { - var sect *Section + if len(data[sym.STLSBSS]) > 0 { + var sect *sym.Section if Iself && (Linkmode == LinkExternal || !*FlagD) { sect = addsection(ctxt.Arch, &Segdata, ".tbss", 06) sect.Align = int32(ctxt.Arch.PtrSize) @@ -1362,13 +1363,13 @@ func (ctxt *Link) dodata() { } datsize = 0 - for _, s := range data[STLSBSS] { + for _, s := range data[sym.STLSBSS] { datsize = aligndatsize(datsize, s) s.Sect = sect s.Value = datsize datsize += s.Size } - checkdatsize(ctxt, datsize, STLSBSS) + checkdatsize(ctxt, datsize, sym.STLSBSS) if sect != nil { sect.Length = uint64(datsize) @@ -1385,7 +1386,7 @@ func (ctxt *Link) dodata() { * since it's not our decision; that code expects the sections in * segtext. */ - var segro *Segment + var segro *sym.Segment if Iself && Linkmode == LinkInternal { segro = &Segrodata } else { @@ -1395,20 +1396,20 @@ func (ctxt *Link) dodata() { datsize = 0 /* read-only executable ELF, Mach-O sections */ - if len(data[STEXT]) != 0 { - Errorf(nil, "dodata found an STEXT symbol: %s", data[STEXT][0].Name) + if len(data[sym.STEXT]) != 0 { + Errorf(nil, "dodata found an sym.STEXT symbol: %s", data[sym.STEXT][0].Name) } - for _, s := range data[SELFRXSECT] { + for _, s := range data[sym.SELFRXSECT] { sect := addsection(ctxt.Arch, &Segtext, s.Name, 04) sect.Align = symalign(s) datsize = Rnd(datsize, int64(sect.Align)) sect.Vaddr = uint64(datsize) s.Sect = sect - s.Type = SRODATA + s.Type = sym.SRODATA s.Value = int64(uint64(datsize) - sect.Vaddr) datsize += s.Size sect.Length = uint64(datsize) - sect.Vaddr - checkdatsize(ctxt, datsize, SELFRXSECT) + checkdatsize(ctxt, datsize, sym.SELFRXSECT) } /* read-only data */ @@ -1421,18 +1422,18 @@ func (ctxt *Link) dodata() { ctxt.Syms.Lookup("runtime.types", 0).Sect = sect ctxt.Syms.Lookup("runtime.etypes", 0).Sect = sect } - for _, symn := range readOnly { + for _, symn := range sym.ReadOnly { align := dataMaxAlign[symn] if sect.Align < align { sect.Align = align } } datsize = Rnd(datsize, int64(sect.Align)) - for _, symn := range readOnly { + for _, symn := range sym.ReadOnly { for _, s := range data[symn] { datsize = aligndatsize(datsize, s) s.Sect = sect - s.Type = SRODATA + s.Type = sym.SRODATA s.Value = int64(uint64(datsize) - sect.Vaddr) datsize += s.Size } @@ -1441,31 +1442,31 @@ func (ctxt *Link) dodata() { sect.Length = uint64(datsize) - sect.Vaddr /* read-only ELF, Mach-O sections */ - for _, s := range data[SELFROSECT] { + for _, s := range data[sym.SELFROSECT] { sect = addsection(ctxt.Arch, segro, s.Name, 04) sect.Align = symalign(s) datsize = Rnd(datsize, int64(sect.Align)) sect.Vaddr = uint64(datsize) s.Sect = sect - s.Type = SRODATA + s.Type = sym.SRODATA s.Value = int64(uint64(datsize) - sect.Vaddr) datsize += s.Size sect.Length = uint64(datsize) - sect.Vaddr } - checkdatsize(ctxt, datsize, SELFROSECT) + checkdatsize(ctxt, datsize, sym.SELFROSECT) - for _, s := range data[SMACHOPLT] { + for _, s := range data[sym.SMACHOPLT] { sect = addsection(ctxt.Arch, segro, s.Name, 04) sect.Align = symalign(s) datsize = Rnd(datsize, int64(sect.Align)) sect.Vaddr = uint64(datsize) s.Sect = sect - s.Type = SRODATA + s.Type = sym.SRODATA s.Value = int64(uint64(datsize) - sect.Vaddr) datsize += s.Size sect.Length = uint64(datsize) - sect.Vaddr } - checkdatsize(ctxt, datsize, SMACHOPLT) + checkdatsize(ctxt, datsize, sym.SMACHOPLT) // There is some data that are conceptually read-only but are written to by // relocations. On GNU systems, we can arrange for the dynamic linker to @@ -1477,12 +1478,12 @@ func (ctxt *Link) dodata() { // situation. // TODO(mwhudson): It would make sense to do this more widely, but it makes // the system linker segfault on darwin. - addrelrosection := func(suffix string) *Section { + addrelrosection := func(suffix string) *sym.Section { return addsection(ctxt.Arch, segro, suffix, 04) } if UseRelro() { - addrelrosection = func(suffix string) *Section { + addrelrosection = func(suffix string) *sym.Section { seg := &Segrelrodata if Linkmode == LinkExternal { // Using a separate segment with an external @@ -1501,23 +1502,23 @@ func (ctxt *Link) dodata() { sect.Vaddr = 0 ctxt.Syms.Lookup("runtime.types", 0).Sect = sect ctxt.Syms.Lookup("runtime.etypes", 0).Sect = sect - for _, symnro := range readOnly { - symn := relROMap[symnro] + for _, symnro := range sym.ReadOnly { + symn := sym.RelROMap[symnro] align := dataMaxAlign[symn] if sect.Align < align { sect.Align = align } } datsize = Rnd(datsize, int64(sect.Align)) - for _, symnro := range readOnly { - symn := relROMap[symnro] + for _, symnro := range sym.ReadOnly { + symn := sym.RelROMap[symnro] for _, s := range data[symn] { datsize = aligndatsize(datsize, s) if s.Outer != nil && s.Outer.Sect != nil && s.Outer.Sect != sect { Errorf(s, "s.Outer (%s) in different section from s, %s != %s", s.Outer.Name, s.Outer.Sect.Name, sect.Name) } s.Sect = sect - s.Type = SRODATA + s.Type = sym.SRODATA s.Value = int64(uint64(datsize) - sect.Vaddr) datsize += s.Size } @@ -1529,65 +1530,65 @@ func (ctxt *Link) dodata() { /* typelink */ sect = addrelrosection(".typelink") - sect.Align = dataMaxAlign[STYPELINK] + sect.Align = dataMaxAlign[sym.STYPELINK] datsize = Rnd(datsize, int64(sect.Align)) sect.Vaddr = uint64(datsize) typelink := ctxt.Syms.Lookup("runtime.typelink", 0) typelink.Sect = sect - typelink.Type = SRODATA + typelink.Type = sym.SRODATA datsize += typelink.Size - checkdatsize(ctxt, datsize, STYPELINK) + checkdatsize(ctxt, datsize, sym.STYPELINK) sect.Length = uint64(datsize) - sect.Vaddr /* itablink */ sect = addrelrosection(".itablink") - sect.Align = dataMaxAlign[SITABLINK] + sect.Align = dataMaxAlign[sym.SITABLINK] datsize = Rnd(datsize, int64(sect.Align)) sect.Vaddr = uint64(datsize) ctxt.Syms.Lookup("runtime.itablink", 0).Sect = sect ctxt.Syms.Lookup("runtime.eitablink", 0).Sect = sect - for _, s := range data[SITABLINK] { + for _, s := range data[sym.SITABLINK] { datsize = aligndatsize(datsize, s) s.Sect = sect - s.Type = SRODATA + s.Type = sym.SRODATA s.Value = int64(uint64(datsize) - sect.Vaddr) datsize += s.Size } - checkdatsize(ctxt, datsize, SITABLINK) + checkdatsize(ctxt, datsize, sym.SITABLINK) sect.Length = uint64(datsize) - sect.Vaddr /* gosymtab */ sect = addrelrosection(".gosymtab") - sect.Align = dataMaxAlign[SSYMTAB] + sect.Align = dataMaxAlign[sym.SSYMTAB] datsize = Rnd(datsize, int64(sect.Align)) sect.Vaddr = uint64(datsize) ctxt.Syms.Lookup("runtime.symtab", 0).Sect = sect ctxt.Syms.Lookup("runtime.esymtab", 0).Sect = sect - for _, s := range data[SSYMTAB] { + for _, s := range data[sym.SSYMTAB] { datsize = aligndatsize(datsize, s) s.Sect = sect - s.Type = SRODATA + s.Type = sym.SRODATA s.Value = int64(uint64(datsize) - sect.Vaddr) datsize += s.Size } - checkdatsize(ctxt, datsize, SSYMTAB) + checkdatsize(ctxt, datsize, sym.SSYMTAB) sect.Length = uint64(datsize) - sect.Vaddr /* gopclntab */ sect = addrelrosection(".gopclntab") - sect.Align = dataMaxAlign[SPCLNTAB] + sect.Align = dataMaxAlign[sym.SPCLNTAB] datsize = Rnd(datsize, int64(sect.Align)) sect.Vaddr = uint64(datsize) ctxt.Syms.Lookup("runtime.pclntab", 0).Sect = sect ctxt.Syms.Lookup("runtime.epclntab", 0).Sect = sect - for _, s := range data[SPCLNTAB] { + for _, s := range data[sym.SPCLNTAB] { datsize = aligndatsize(datsize, s) s.Sect = sect - s.Type = SRODATA + s.Type = sym.SRODATA s.Value = int64(uint64(datsize) - sect.Vaddr) datsize += s.Size } - checkdatsize(ctxt, datsize, SRODATA) + checkdatsize(ctxt, datsize, sym.SRODATA) sect.Length = uint64(datsize) - sect.Vaddr // 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits. @@ -1595,7 +1596,7 @@ func (ctxt *Link) dodata() { Errorf(nil, "read-only data segment too large: %d", datsize) } - for symn := SELFRXSECT; symn < SXREF; symn++ { + for symn := sym.SELFRXSECT; symn < sym.SXREF; symn++ { datap = append(datap, data[symn]...) } @@ -1604,7 +1605,7 @@ func (ctxt *Link) dodata() { var i int for ; i < len(dwarfp); i++ { s := dwarfp[i] - if s.Type != SDWARFSECT { + if s.Type != sym.SDWARFSECT { break } @@ -1613,22 +1614,22 @@ func (ctxt *Link) dodata() { datsize = Rnd(datsize, int64(sect.Align)) sect.Vaddr = uint64(datsize) s.Sect = sect - s.Type = SRODATA + s.Type = sym.SRODATA s.Value = int64(uint64(datsize) - sect.Vaddr) datsize += s.Size sect.Length = uint64(datsize) - sect.Vaddr } - checkdatsize(ctxt, datsize, SDWARFSECT) + checkdatsize(ctxt, datsize, sym.SDWARFSECT) for i < len(dwarfp) { curType := dwarfp[i].Type - var sect *Section + var sect *sym.Section switch curType { - case SDWARFINFO: + case sym.SDWARFINFO: sect = addsection(ctxt.Arch, &Segdwarf, ".debug_info", 04) - case SDWARFRANGE: + case sym.SDWARFRANGE: sect = addsection(ctxt.Arch, &Segdwarf, ".debug_ranges", 04) - case SDWARFLOC: + case sym.SDWARFLOC: sect = addsection(ctxt.Arch, &Segdwarf, ".debug_loc", 04) default: Errorf(dwarfp[i], "unknown DWARF section %v", curType) @@ -1643,9 +1644,9 @@ func (ctxt *Link) dodata() { break } s.Sect = sect - s.Type = SRODATA + s.Type = sym.SRODATA s.Value = int64(uint64(datsize) - sect.Vaddr) - s.Attr |= AttrLocal + s.Attr |= sym.AttrLocal datsize += s.Size } sect.Length = uint64(datsize) - sect.Vaddr @@ -1677,11 +1678,11 @@ func (ctxt *Link) dodata() { } } -func dodataSect(ctxt *Link, symn SymKind, syms []*Symbol) (result []*Symbol, maxAlign int32) { +func dodataSect(ctxt *Link, symn sym.SymKind, syms []*sym.Symbol) (result []*sym.Symbol, maxAlign int32) { if Headtype == objabi.Hdarwin { // Some symbols may no longer belong in syms // due to movement in machosymorder. - newSyms := make([]*Symbol, 0, len(syms)) + newSyms := make([]*sym.Symbol, 0, len(syms)) for _, s := range syms { if s.Type == symn { newSyms = append(newSyms, s) @@ -1690,13 +1691,13 @@ func dodataSect(ctxt *Link, symn SymKind, syms []*Symbol) (result []*Symbol, max syms = newSyms } - var head, tail *Symbol + var head, tail *sym.Symbol symsSort := make([]dataSortKey, 0, len(syms)) for _, s := range syms { if s.Attr.OnList() { log.Fatalf("symbol %s listed multiple times", s.Name) } - s.Attr |= AttrOnList + s.Attr |= sym.AttrOnList switch { case s.Size < int64(len(s.P)): Errorf(s, "initialize bounds (%d < %d)", s.Size, len(s.P)) @@ -1727,9 +1728,9 @@ func dodataSect(ctxt *Link, symn SymKind, syms []*Symbol) (result []*Symbol, max } switch s.Type { - case SELFGOT: + case sym.SELFGOT: // For ppc64, we want to interleave the .got and .toc sections - // from input files. Both are type SELFGOT, so in that case + // from input files. Both are type sym.SELFGOT, so in that case // we skip size comparison and fall through to the name // comparison (conveniently, .got sorts before .toc). key.size = 0 @@ -1756,7 +1757,7 @@ func dodataSect(ctxt *Link, symn SymKind, syms []*Symbol) (result []*Symbol, max syms[len(syms)-1] = tail } - if Iself && symn == SELFROSECT { + if Iself && symn == sym.SELFROSECT { // Make .rela and .rela.plt contiguous, the ELF ABI requires this // and Solaris actually cares. reli, plti := -1, -1 @@ -1802,18 +1803,18 @@ func (ctxt *Link) textbuildid() { return } - sym := ctxt.Syms.Lookup("go.buildid", 0) - sym.Attr |= AttrReachable + s := ctxt.Syms.Lookup("go.buildid", 0) + s.Attr |= sym.AttrReachable // The \xff is invalid UTF-8, meant to make it less likely // to find one of these accidentally. data := "\xff Go build ID: " + strconv.Quote(*flagBuildid) + "\n \xff" - sym.Type = STEXT - sym.P = []byte(data) - sym.Size = int64(len(sym.P)) + s.Type = sym.STEXT + s.P = []byte(data) + s.Size = int64(len(s.P)) ctxt.Textp = append(ctxt.Textp, nil) copy(ctxt.Textp[1:], ctxt.Textp) - ctxt.Textp[0] = sym + ctxt.Textp[0] = s } // assign addresses to text @@ -1843,10 +1844,10 @@ func (ctxt *Link) textaddress() { n := 1 sect.Vaddr = va ntramps := 0 - for _, sym := range ctxt.Textp { - sect, n, va = assignAddress(ctxt, sect, n, sym, va, false) + for _, s := range ctxt.Textp { + sect, n, va = assignAddress(ctxt, sect, n, s, va, false) - trampoline(ctxt, sym) // resolve jumps, may add trampolines if jump too far + trampoline(ctxt, s) // resolve jumps, may add trampolines if jump too far // lay down trampolines after each function for ; ntramps < len(ctxt.tramps); ntramps++ { @@ -1860,13 +1861,13 @@ func (ctxt *Link) textaddress() { // merge tramps into Textp, keeping Textp in address order if ntramps != 0 { - newtextp := make([]*Symbol, 0, len(ctxt.Textp)+ntramps) + newtextp := make([]*sym.Symbol, 0, len(ctxt.Textp)+ntramps) i := 0 - for _, sym := range ctxt.Textp { - for ; i < ntramps && ctxt.tramps[i].Value < sym.Value; i++ { + for _, s := range ctxt.Textp { + for ; i < ntramps && ctxt.tramps[i].Value < s.Value; i++ { newtextp = append(newtextp, ctxt.tramps[i]) } - newtextp = append(newtextp, sym) + newtextp = append(newtextp, s) } newtextp = append(newtextp, ctxt.tramps[i:ntramps]...) @@ -1877,24 +1878,24 @@ func (ctxt *Link) textaddress() { // assigns address for a text symbol, returns (possibly new) section, its number, and the address // Note: once we have trampoline insertion support for external linking, this function // will not need to create new text sections, and so no need to return sect and n. -func assignAddress(ctxt *Link, sect *Section, n int, sym *Symbol, va uint64, isTramp bool) (*Section, int, uint64) { - sym.Sect = sect - if sym.Type&SSUB != 0 { +func assignAddress(ctxt *Link, sect *sym.Section, n int, s *sym.Symbol, va uint64, isTramp bool) (*sym.Section, int, uint64) { + s.Sect = sect + if s.Type&sym.SSUB != 0 { return sect, n, va } - if sym.Align != 0 { - va = uint64(Rnd(int64(va), int64(sym.Align))) + if s.Align != 0 { + va = uint64(Rnd(int64(va), int64(s.Align))) } else { va = uint64(Rnd(int64(va), int64(Funcalign))) } - sym.Value = 0 - for sub := sym; sub != nil; sub = sub.Sub { + s.Value = 0 + for sub := s; sub != nil; sub = sub.Sub { sub.Value += int64(va) } funcsize := uint64(MINFUNC) // spacing required for findfunctab - if sym.Size > MINFUNC { - funcsize = uint64(sym.Size) + if s.Size > MINFUNC { + funcsize = uint64(s.Size) } // On ppc64x a text section should not be larger than 2^26 bytes due to the size of @@ -1906,7 +1907,7 @@ func assignAddress(ctxt *Link, sect *Section, n int, sym *Symbol, va uint64, isT // Only break at outermost syms. - if ctxt.Arch.InFamily(sys.PPC64) && sym.Outer == nil && Iself && Linkmode == LinkExternal && va-sect.Vaddr+funcsize+maxSizeTrampolinesPPC64(sym, isTramp) > 0x1c00000 { + if ctxt.Arch.InFamily(sys.PPC64) && s.Outer == nil && Iself && Linkmode == LinkExternal && va-sect.Vaddr+funcsize+maxSizeTrampolinesPPC64(s, isTramp) > 0x1c00000 { // Set the length for the previous text section sect.Length = va - sect.Vaddr @@ -1914,7 +1915,7 @@ func assignAddress(ctxt *Link, sect *Section, n int, sym *Symbol, va uint64, isT // Create new section, set the starting Vaddr sect = addsection(ctxt.Arch, &Segtext, ".text", 05) sect.Vaddr = va - sym.Sect = sect + s.Sect = sect // Create a symbol for the start of the secondary text sections ctxt.Syms.Lookup(fmt.Sprintf("runtime.text.%d", n), 0).Sect = sect @@ -2002,10 +2003,10 @@ func (ctxt *Link) address() { if Headtype == objabi.Hplan9 { Segdata.Fileoff = Segtext.Fileoff + Segtext.Filelen } - var data *Section - var noptr *Section - var bss *Section - var noptrbss *Section + var data *sym.Section + var noptr *sym.Section + var bss *sym.Section + var noptrbss *sym.Section for i, s := range Segdata.Sections { if Iself && s.Name == ".tbss" { continue @@ -2081,12 +2082,12 @@ func (ctxt *Link) address() { } } - for _, sym := range dwarfp { - if sym.Sect != nil { - sym.Value += int64(sym.Sect.Vaddr) + for _, s := range dwarfp { + if s.Sect != nil { + s.Value += int64(s.Sect.Vaddr) } - for sub := sym.Sub; sub != nil; sub = sub.Sub { - sub.Value += sym.Value + for sub := s.Sub; sub != nil; sub = sub.Sub { + sub.Value += s.Value } } @@ -2097,8 +2098,8 @@ func (ctxt *Link) address() { s.Value = int64(sectSym.Sect.Vaddr + 16) } - ctxt.xdefine("runtime.text", STEXT, int64(text.Vaddr)) - ctxt.xdefine("runtime.etext", STEXT, int64(lasttext.Vaddr+lasttext.Length)) + ctxt.xdefine("runtime.text", sym.STEXT, int64(text.Vaddr)) + ctxt.xdefine("runtime.etext", sym.STEXT, int64(lasttext.Vaddr+lasttext.Length)) // If there are multiple text sections, create runtime.text.n for // their section Vaddr, using n for index @@ -2106,50 +2107,50 @@ func (ctxt *Link) address() { for _, sect := range Segtext.Sections[1:] { if sect.Name == ".text" { symname := fmt.Sprintf("runtime.text.%d", n) - ctxt.xdefine(symname, STEXT, int64(sect.Vaddr)) + ctxt.xdefine(symname, sym.STEXT, int64(sect.Vaddr)) n++ } else { break } } - ctxt.xdefine("runtime.rodata", SRODATA, int64(rodata.Vaddr)) - ctxt.xdefine("runtime.erodata", SRODATA, int64(rodata.Vaddr+rodata.Length)) - ctxt.xdefine("runtime.types", SRODATA, int64(types.Vaddr)) - ctxt.xdefine("runtime.etypes", SRODATA, int64(types.Vaddr+types.Length)) - ctxt.xdefine("runtime.itablink", SRODATA, int64(itablink.Vaddr)) - ctxt.xdefine("runtime.eitablink", SRODATA, int64(itablink.Vaddr+itablink.Length)) - - sym := ctxt.Syms.Lookup("runtime.gcdata", 0) - sym.Attr |= AttrLocal - ctxt.xdefine("runtime.egcdata", SRODATA, Symaddr(sym)+sym.Size) - ctxt.Syms.Lookup("runtime.egcdata", 0).Sect = sym.Sect - - sym = ctxt.Syms.Lookup("runtime.gcbss", 0) - sym.Attr |= AttrLocal - ctxt.xdefine("runtime.egcbss", SRODATA, Symaddr(sym)+sym.Size) - ctxt.Syms.Lookup("runtime.egcbss", 0).Sect = sym.Sect - - ctxt.xdefine("runtime.symtab", SRODATA, int64(symtab.Vaddr)) - ctxt.xdefine("runtime.esymtab", SRODATA, int64(symtab.Vaddr+symtab.Length)) - ctxt.xdefine("runtime.pclntab", SRODATA, int64(pclntab.Vaddr)) - ctxt.xdefine("runtime.epclntab", SRODATA, int64(pclntab.Vaddr+pclntab.Length)) - ctxt.xdefine("runtime.noptrdata", SNOPTRDATA, int64(noptr.Vaddr)) - ctxt.xdefine("runtime.enoptrdata", SNOPTRDATA, int64(noptr.Vaddr+noptr.Length)) - ctxt.xdefine("runtime.bss", SBSS, int64(bss.Vaddr)) - ctxt.xdefine("runtime.ebss", SBSS, int64(bss.Vaddr+bss.Length)) - ctxt.xdefine("runtime.data", SDATA, int64(data.Vaddr)) - ctxt.xdefine("runtime.edata", SDATA, int64(data.Vaddr+data.Length)) - ctxt.xdefine("runtime.noptrbss", SNOPTRBSS, int64(noptrbss.Vaddr)) - ctxt.xdefine("runtime.enoptrbss", SNOPTRBSS, int64(noptrbss.Vaddr+noptrbss.Length)) - ctxt.xdefine("runtime.end", SBSS, int64(Segdata.Vaddr+Segdata.Length)) + ctxt.xdefine("runtime.rodata", sym.SRODATA, int64(rodata.Vaddr)) + ctxt.xdefine("runtime.erodata", sym.SRODATA, int64(rodata.Vaddr+rodata.Length)) + ctxt.xdefine("runtime.types", sym.SRODATA, int64(types.Vaddr)) + ctxt.xdefine("runtime.etypes", sym.SRODATA, int64(types.Vaddr+types.Length)) + ctxt.xdefine("runtime.itablink", sym.SRODATA, int64(itablink.Vaddr)) + ctxt.xdefine("runtime.eitablink", sym.SRODATA, int64(itablink.Vaddr+itablink.Length)) + + s := ctxt.Syms.Lookup("runtime.gcdata", 0) + s.Attr |= sym.AttrLocal + ctxt.xdefine("runtime.egcdata", sym.SRODATA, Symaddr(s)+s.Size) + ctxt.Syms.Lookup("runtime.egcdata", 0).Sect = s.Sect + + s = ctxt.Syms.Lookup("runtime.gcbss", 0) + s.Attr |= sym.AttrLocal + ctxt.xdefine("runtime.egcbss", sym.SRODATA, Symaddr(s)+s.Size) + ctxt.Syms.Lookup("runtime.egcbss", 0).Sect = s.Sect + + ctxt.xdefine("runtime.symtab", sym.SRODATA, int64(symtab.Vaddr)) + ctxt.xdefine("runtime.esymtab", sym.SRODATA, int64(symtab.Vaddr+symtab.Length)) + ctxt.xdefine("runtime.pclntab", sym.SRODATA, int64(pclntab.Vaddr)) + ctxt.xdefine("runtime.epclntab", sym.SRODATA, int64(pclntab.Vaddr+pclntab.Length)) + ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr)) + ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr+noptr.Length)) + ctxt.xdefine("runtime.bss", sym.SBSS, int64(bss.Vaddr)) + ctxt.xdefine("runtime.ebss", sym.SBSS, int64(bss.Vaddr+bss.Length)) + ctxt.xdefine("runtime.data", sym.SDATA, int64(data.Vaddr)) + ctxt.xdefine("runtime.edata", sym.SDATA, int64(data.Vaddr+data.Length)) + ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr)) + ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr+noptrbss.Length)) + ctxt.xdefine("runtime.end", sym.SBSS, int64(Segdata.Vaddr+Segdata.Length)) } // add a trampoline with symbol s (to be laid down after the current function) -func (ctxt *Link) AddTramp(s *Symbol) { - s.Type = STEXT - s.Attr |= AttrReachable - s.Attr |= AttrOnList +func (ctxt *Link) AddTramp(s *sym.Symbol) { + s.Type = sym.STEXT + s.Attr |= sym.AttrReachable + s.Attr |= sym.AttrOnList ctxt.tramps = append(ctxt.tramps, s) if *FlagDebugTramp > 0 && ctxt.Debugvlog > 0 { ctxt.Logf("trampoline %s inserted\n", s) diff --git a/src/cmd/link/internal/ld/deadcode.go b/src/cmd/link/internal/ld/deadcode.go index 8333e6411c..a45ad891cd 100644 --- a/src/cmd/link/internal/ld/deadcode.go +++ b/src/cmd/link/internal/ld/deadcode.go @@ -7,6 +7,7 @@ package ld import ( "cmd/internal/objabi" "cmd/internal/sys" + "cmd/link/internal/sym" "fmt" "strings" "unicode" @@ -112,13 +113,13 @@ func deadcode(ctxt *Link) { // (When BuildmodeShared, always keep itablinks.) for _, s := range ctxt.Syms.Allsym { if strings.HasPrefix(s.Name, "go.itablink.") { - s.Attr.Set(AttrReachable, len(s.R) == 1 && s.R[0].Sym.Attr.Reachable()) + s.Attr.Set(sym.AttrReachable, len(s.R) == 1 && s.R[0].Sym.Attr.Reachable()) } } } // Remove dead text but keep file information (z symbols). - textp := make([]*Symbol, 0, len(ctxt.Textp)) + textp := make([]*sym.Symbol, 0, len(ctxt.Textp)) for _, s := range ctxt.Textp { if s.Attr.Reachable() { textp = append(textp, s) @@ -132,11 +133,11 @@ func deadcode(ctxt *Link) { // the reflect.method struct: mtyp, ifn, and tfn. type methodref struct { m methodsig - src *Symbol // receiver type symbol - r [3]*Reloc // R_METHODOFF relocations to fields of runtime.method + src *sym.Symbol // receiver type symbol + r [3]*sym.Reloc // R_METHODOFF relocations to fields of runtime.method } -func (m methodref) ifn() *Symbol { return m.r[1].Sym } +func (m methodref) ifn() *sym.Symbol { return m.r[1].Sym } func (m methodref) isExported() bool { for _, r := range m.m { @@ -148,13 +149,13 @@ func (m methodref) isExported() bool { // deadcodepass holds state for the deadcode flood fill. type deadcodepass struct { ctxt *Link - markQueue []*Symbol // symbols to flood fill in next pass + markQueue []*sym.Symbol // symbols to flood fill in next pass ifaceMethod map[methodsig]bool // methods declared in reached interfaces markableMethods []methodref // methods of reached types reflectMethod bool } -func (d *deadcodepass) cleanupReloc(r *Reloc) { +func (d *deadcodepass) cleanupReloc(r *sym.Reloc) { if r.Sym.Attr.Reachable() { r.Type = objabi.R_ADDROFF } else { @@ -167,7 +168,7 @@ func (d *deadcodepass) cleanupReloc(r *Reloc) { } // mark appends a symbol to the mark queue for flood filling. -func (d *deadcodepass) mark(s, parent *Symbol) { +func (d *deadcodepass) mark(s, parent *sym.Symbol) { if s == nil || s.Attr.Reachable() { return } @@ -181,7 +182,7 @@ func (d *deadcodepass) mark(s, parent *Symbol) { } fmt.Printf("%s -> %s\n", p, s.Name) } - s.Attr |= AttrReachable + s.Attr |= sym.AttrReachable s.Reachparent = parent d.markQueue = append(d.markQueue, s) } @@ -208,7 +209,7 @@ func (d *deadcodepass) init() { // Mark all symbols defined in this library as reachable when // building a shared library. for _, s := range d.ctxt.Syms.Allsym { - if s.Type != 0 && s.Type != SDYNIMPORT { + if s.Type != 0 && s.Type != sym.SDYNIMPORT { d.mark(s, nil) } } @@ -257,7 +258,7 @@ func (d *deadcodepass) flood() { for len(d.markQueue) > 0 { s := d.markQueue[0] d.markQueue = d.markQueue[1:] - if s.Type == STEXT { + if s.Type == sym.STEXT { if d.ctxt.Debugvlog > 1 { d.ctxt.Logf("marktext %s\n", s.Name) } diff --git a/src/cmd/link/internal/ld/decodesym.go b/src/cmd/link/internal/ld/decodesym.go index e4cd65a59f..3afb38948f 100644 --- a/src/cmd/link/internal/ld/decodesym.go +++ b/src/cmd/link/internal/ld/decodesym.go @@ -8,6 +8,7 @@ import ( "bytes" "cmd/internal/objabi" "cmd/internal/sys" + "cmd/link/internal/sym" "debug/elf" "fmt" ) @@ -28,7 +29,7 @@ const ( tflagExtraStar = 1 << 1 ) -func decodeReloc(s *Symbol, off int32) *Reloc { +func decodeReloc(s *sym.Symbol, off int32) *sym.Reloc { for i := range s.R { if s.R[i].Off == off { return &s.R[i] @@ -37,7 +38,7 @@ func decodeReloc(s *Symbol, off int32) *Reloc { return nil } -func decodeRelocSym(s *Symbol, off int32) *Symbol { +func decodeRelocSym(s *sym.Symbol, off int32) *sym.Symbol { r := decodeReloc(s, off) if r == nil { return nil @@ -64,27 +65,27 @@ func structfieldSize(arch *sys.Arch) int { return 3 * arch.PtrSize } // ru func uncommonSize() int { return 4 + 2 + 2 + 4 + 4 } // runtime.uncommontype // Type.commonType.kind -func decodetypeKind(arch *sys.Arch, s *Symbol) uint8 { +func decodetypeKind(arch *sys.Arch, s *sym.Symbol) uint8 { return s.P[2*arch.PtrSize+7] & objabi.KindMask // 0x13 / 0x1f } // Type.commonType.kind -func decodetypeUsegcprog(arch *sys.Arch, s *Symbol) uint8 { +func decodetypeUsegcprog(arch *sys.Arch, s *sym.Symbol) uint8 { return s.P[2*arch.PtrSize+7] & objabi.KindGCProg // 0x13 / 0x1f } // Type.commonType.size -func decodetypeSize(arch *sys.Arch, s *Symbol) int64 { +func decodetypeSize(arch *sys.Arch, s *sym.Symbol) int64 { return int64(decodeInuxi(arch, s.P, arch.PtrSize)) // 0x8 / 0x10 } // Type.commonType.ptrdata -func decodetypePtrdata(arch *sys.Arch, s *Symbol) int64 { +func decodetypePtrdata(arch *sys.Arch, s *sym.Symbol) int64 { return int64(decodeInuxi(arch, s.P[arch.PtrSize:], arch.PtrSize)) // 0x8 / 0x10 } // Type.commonType.tflag -func decodetypeHasUncommon(arch *sys.Arch, s *Symbol) bool { +func decodetypeHasUncommon(arch *sys.Arch, s *sym.Symbol) bool { return s.P[2*arch.PtrSize+4]&tflagUncommon != 0 } @@ -103,8 +104,8 @@ func findShlibSection(ctxt *Link, path string, addr uint64) *elf.Section { } // Type.commonType.gc -func decodetypeGcprog(ctxt *Link, s *Symbol) []byte { - if s.Type == SDYNIMPORT { +func decodetypeGcprog(ctxt *Link, s *sym.Symbol) []byte { + if s.Type == sym.SDYNIMPORT { addr := decodetypeGcprogShlib(ctxt, s) sect := findShlibSection(ctxt, s.File, addr) if sect != nil { @@ -122,7 +123,7 @@ func decodetypeGcprog(ctxt *Link, s *Symbol) []byte { return decodeRelocSym(s, 2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize)).P } -func decodetypeGcprogShlib(ctxt *Link, s *Symbol) uint64 { +func decodetypeGcprogShlib(ctxt *Link, s *sym.Symbol) uint64 { if ctxt.Arch.Family == sys.ARM64 { for _, shlib := range ctxt.Shlibs { if shlib.Path == s.File { @@ -134,8 +135,8 @@ func decodetypeGcprogShlib(ctxt *Link, s *Symbol) uint64 { return decodeInuxi(ctxt.Arch, s.P[2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize):], ctxt.Arch.PtrSize) } -func decodetypeGcmask(ctxt *Link, s *Symbol) []byte { - if s.Type == SDYNIMPORT { +func decodetypeGcmask(ctxt *Link, s *sym.Symbol) []byte { + if s.Type == sym.SDYNIMPORT { addr := decodetypeGcprogShlib(ctxt, s) ptrdata := decodetypePtrdata(ctxt.Arch, s) sect := findShlibSection(ctxt, s.File, addr) @@ -152,48 +153,48 @@ func decodetypeGcmask(ctxt *Link, s *Symbol) []byte { } // Type.ArrayType.elem and Type.SliceType.Elem -func decodetypeArrayElem(arch *sys.Arch, s *Symbol) *Symbol { +func decodetypeArrayElem(arch *sys.Arch, s *sym.Symbol) *sym.Symbol { return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30 } -func decodetypeArrayLen(arch *sys.Arch, s *Symbol) int64 { +func decodetypeArrayLen(arch *sys.Arch, s *sym.Symbol) int64 { return int64(decodeInuxi(arch, s.P[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize)) } // Type.PtrType.elem -func decodetypePtrElem(arch *sys.Arch, s *Symbol) *Symbol { +func decodetypePtrElem(arch *sys.Arch, s *sym.Symbol) *sym.Symbol { return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30 } // Type.MapType.key, elem -func decodetypeMapKey(arch *sys.Arch, s *Symbol) *Symbol { +func decodetypeMapKey(arch *sys.Arch, s *sym.Symbol) *sym.Symbol { return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30 } -func decodetypeMapValue(arch *sys.Arch, s *Symbol) *Symbol { +func decodetypeMapValue(arch *sys.Arch, s *sym.Symbol) *sym.Symbol { return decodeRelocSym(s, int32(commonsize(arch))+int32(arch.PtrSize)) // 0x20 / 0x38 } // Type.ChanType.elem -func decodetypeChanElem(arch *sys.Arch, s *Symbol) *Symbol { +func decodetypeChanElem(arch *sys.Arch, s *sym.Symbol) *sym.Symbol { return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30 } // Type.FuncType.dotdotdot -func decodetypeFuncDotdotdot(arch *sys.Arch, s *Symbol) bool { +func decodetypeFuncDotdotdot(arch *sys.Arch, s *sym.Symbol) bool { return uint16(decodeInuxi(arch, s.P[commonsize(arch)+2:], 2))&(1<<15) != 0 } // Type.FuncType.inCount -func decodetypeFuncInCount(arch *sys.Arch, s *Symbol) int { +func decodetypeFuncInCount(arch *sys.Arch, s *sym.Symbol) int { return int(decodeInuxi(arch, s.P[commonsize(arch):], 2)) } -func decodetypeFuncOutCount(arch *sys.Arch, s *Symbol) int { +func decodetypeFuncOutCount(arch *sys.Arch, s *sym.Symbol) int { return int(uint16(decodeInuxi(arch, s.P[commonsize(arch)+2:], 2)) & (1<<15 - 1)) } -func decodetypeFuncInType(arch *sys.Arch, s *Symbol, i int) *Symbol { +func decodetypeFuncInType(arch *sys.Arch, s *sym.Symbol, i int) *sym.Symbol { uadd := commonsize(arch) + 4 if arch.PtrSize == 8 { uadd += 4 @@ -204,16 +205,16 @@ func decodetypeFuncInType(arch *sys.Arch, s *Symbol, i int) *Symbol { return decodeRelocSym(s, int32(uadd+i*arch.PtrSize)) } -func decodetypeFuncOutType(arch *sys.Arch, s *Symbol, i int) *Symbol { +func decodetypeFuncOutType(arch *sys.Arch, s *sym.Symbol, i int) *sym.Symbol { return decodetypeFuncInType(arch, s, i+decodetypeFuncInCount(arch, s)) } // Type.StructType.fields.Slice::length -func decodetypeStructFieldCount(arch *sys.Arch, s *Symbol) int { +func decodetypeStructFieldCount(arch *sys.Arch, s *sym.Symbol) int { return int(decodeInuxi(arch, s.P[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize)) } -func decodetypeStructFieldArrayOff(arch *sys.Arch, s *Symbol, i int) int { +func decodetypeStructFieldArrayOff(arch *sys.Arch, s *sym.Symbol, i int) int { off := commonsize(arch) + 4*arch.PtrSize if decodetypeHasUncommon(arch, s) { off += uncommonSize() @@ -223,7 +224,7 @@ func decodetypeStructFieldArrayOff(arch *sys.Arch, s *Symbol, i int) int { } // decodetypeStr returns the contents of an rtype's str field (a nameOff). -func decodetypeStr(arch *sys.Arch, s *Symbol) string { +func decodetypeStr(arch *sys.Arch, s *sym.Symbol) string { str := decodetypeName(s, 4*arch.PtrSize+8) if s.P[2*arch.PtrSize+4]&tflagExtraStar != 0 { return str[1:] @@ -232,7 +233,7 @@ func decodetypeStr(arch *sys.Arch, s *Symbol) string { } // decodetypeName decodes the name from a reflect.name. -func decodetypeName(s *Symbol, off int) string { +func decodetypeName(s *sym.Symbol, off int) string { r := decodeReloc(s, int32(off)) if r == nil { return "" @@ -243,27 +244,27 @@ func decodetypeName(s *Symbol, off int) string { return string(data[3 : 3+namelen]) } -func decodetypeStructFieldName(arch *sys.Arch, s *Symbol, i int) string { +func decodetypeStructFieldName(arch *sys.Arch, s *sym.Symbol, i int) string { off := decodetypeStructFieldArrayOff(arch, s, i) return decodetypeName(s, off) } -func decodetypeStructFieldType(arch *sys.Arch, s *Symbol, i int) *Symbol { +func decodetypeStructFieldType(arch *sys.Arch, s *sym.Symbol, i int) *sym.Symbol { off := decodetypeStructFieldArrayOff(arch, s, i) return decodeRelocSym(s, int32(off+arch.PtrSize)) } -func decodetypeStructFieldOffs(arch *sys.Arch, s *Symbol, i int) int64 { +func decodetypeStructFieldOffs(arch *sys.Arch, s *sym.Symbol, i int) int64 { return decodetypeStructFieldOffsAnon(arch, s, i) >> 1 } -func decodetypeStructFieldOffsAnon(arch *sys.Arch, s *Symbol, i int) int64 { +func decodetypeStructFieldOffsAnon(arch *sys.Arch, s *sym.Symbol, i int) int64 { off := decodetypeStructFieldArrayOff(arch, s, i) return int64(decodeInuxi(arch, s.P[off+2*arch.PtrSize:], arch.PtrSize)) } // InterfaceType.methods.length -func decodetypeIfaceMethodCount(arch *sys.Arch, s *Symbol) int64 { +func decodetypeIfaceMethodCount(arch *sys.Arch, s *sym.Symbol) int64 { return int64(decodeInuxi(arch, s.P[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize)) } @@ -290,7 +291,7 @@ const ( // the function type. // // Conveniently this is the layout of both runtime.method and runtime.imethod. -func decodeMethodSig(arch *sys.Arch, s *Symbol, off, size, count int) []methodsig { +func decodeMethodSig(arch *sys.Arch, s *sym.Symbol, off, size, count int) []methodsig { var buf bytes.Buffer var methods []methodsig for i := 0; i < count; i++ { @@ -322,7 +323,7 @@ func decodeMethodSig(arch *sys.Arch, s *Symbol, off, size, count int) []methodsi return methods } -func decodeIfaceMethods(arch *sys.Arch, s *Symbol) []methodsig { +func decodeIfaceMethods(arch *sys.Arch, s *sym.Symbol) []methodsig { if decodetypeKind(arch, s)&kindMask != kindInterface { panic(fmt.Sprintf("symbol %q is not an interface", s.Name)) } @@ -339,7 +340,7 @@ func decodeIfaceMethods(arch *sys.Arch, s *Symbol) []methodsig { return decodeMethodSig(arch, s, off, sizeofIMethod, numMethods) } -func decodetypeMethods(arch *sys.Arch, s *Symbol) []methodsig { +func decodetypeMethods(arch *sys.Arch, s *sym.Symbol) []methodsig { if !decodetypeHasUncommon(arch, s) { panic(fmt.Sprintf("no methods on %q", s.Name)) } diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go index 40a2321f3a..069d1dfc3f 100644 --- a/src/cmd/link/internal/ld/dwarf.go +++ b/src/cmd/link/internal/ld/dwarf.go @@ -17,6 +17,7 @@ import ( "cmd/internal/dwarf" "cmd/internal/objabi" "cmd/internal/sys" + "cmd/link/internal/sym" "fmt" "log" "os" @@ -31,37 +32,37 @@ func (c dwctxt) PtrSize() int { return c.linkctxt.Arch.PtrSize } func (c dwctxt) AddInt(s dwarf.Sym, size int, i int64) { - ls := s.(*Symbol) - ls.addUintXX(c.linkctxt.Arch, uint64(i), size) + ls := s.(*sym.Symbol) + ls.AddUintXX(c.linkctxt.Arch, uint64(i), size) } func (c dwctxt) AddBytes(s dwarf.Sym, b []byte) { - ls := s.(*Symbol) + ls := s.(*sym.Symbol) ls.AddBytes(b) } func (c dwctxt) AddString(s dwarf.Sym, v string) { - Addstring(s.(*Symbol), v) + Addstring(s.(*sym.Symbol), v) } func (c dwctxt) SymValue(s dwarf.Sym) int64 { - return s.(*Symbol).Value + return s.(*sym.Symbol).Value } func (c dwctxt) AddAddress(s dwarf.Sym, data interface{}, value int64) { if value != 0 { - value -= (data.(*Symbol)).Value + value -= (data.(*sym.Symbol)).Value } - s.(*Symbol).AddAddrPlus(c.linkctxt.Arch, data.(*Symbol), value) + s.(*sym.Symbol).AddAddrPlus(c.linkctxt.Arch, data.(*sym.Symbol), value) } func (c dwctxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) { - ls := s.(*Symbol) + ls := s.(*sym.Symbol) switch size { default: Errorf(ls, "invalid size %d in adddwarfref\n", size) fallthrough case c.linkctxt.Arch.PtrSize: - ls.AddAddr(c.linkctxt.Arch, t.(*Symbol)) + ls.AddAddr(c.linkctxt.Arch, t.(*sym.Symbol)) case 4: - ls.AddAddrPlus4(t.(*Symbol), 0) + ls.AddAddrPlus4(t.(*sym.Symbol), 0) } r := &ls.R[len(ls.R)-1] r.Type = objabi.R_DWARFREF @@ -70,11 +71,11 @@ func (c dwctxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64 var gdbscript string -var dwarfp []*Symbol +var dwarfp []*sym.Symbol -func writeabbrev(ctxt *Link) *Symbol { +func writeabbrev(ctxt *Link) *sym.Symbol { s := ctxt.Syms.Lookup(".debug_abbrev", 0) - s.Type = SDWARFSECT + s.Type = sym.SDWARFSECT s.AddBytes(dwarf.GetAbbrev()) return s } @@ -136,10 +137,10 @@ func newdie(ctxt *Link, parent *dwarf.DWDie, abbrev int, name string, version in if name != "" && (abbrev <= dwarf.DW_ABRV_VARIABLE || abbrev >= dwarf.DW_ABRV_NULLTYPE) { if abbrev != dwarf.DW_ABRV_VARIABLE || version == 0 { - sym := ctxt.Syms.Lookup(dwarf.InfoPrefix+name, version) - sym.Attr |= AttrNotInSymbolTable - sym.Type = SDWARFINFO - die.Sym = sym + s := ctxt.Syms.Lookup(dwarf.InfoPrefix+name, version) + s.Attr |= sym.AttrNotInSymbolTable + s.Type = sym.SDWARFINFO + die.Sym = s } } @@ -162,7 +163,7 @@ func walktypedef(die *dwarf.DWDie) *dwarf.DWDie { return die } -func walksymtypedef(ctxt *Link, s *Symbol) *Symbol { +func walksymtypedef(ctxt *Link, s *sym.Symbol) *sym.Symbol { if t := ctxt.Syms.ROLookup(s.Name+"..def", int(s.Version)); t != nil { return t } @@ -187,18 +188,18 @@ func findchild(die *dwarf.DWDie, name string) *dwarf.DWDie { // Used to avoid string allocation when looking up dwarf symbols var prefixBuf = []byte(dwarf.InfoPrefix) -func find(ctxt *Link, name string) *Symbol { +func find(ctxt *Link, name string) *sym.Symbol { n := append(prefixBuf, name...) // The string allocation below is optimized away because it is only used in a map lookup. s := ctxt.Syms.ROLookup(string(n), 0) prefixBuf = n[:len(dwarf.InfoPrefix)] - if s != nil && s.Type == SDWARFINFO { + if s != nil && s.Type == sym.SDWARFINFO { return s } return nil } -func mustFind(ctxt *Link, name string) *Symbol { +func mustFind(ctxt *Link, name string) *sym.Symbol { r := find(ctxt, name) if r == nil { Exitf("dwarf find: cannot find %s", name) @@ -206,7 +207,7 @@ func mustFind(ctxt *Link, name string) *Symbol { return r } -func adddwarfref(ctxt *Link, s *Symbol, t *Symbol, size int) int64 { +func adddwarfref(ctxt *Link, s *sym.Symbol, t *sym.Symbol, size int) int64 { var result int64 switch size { default: @@ -222,14 +223,14 @@ func adddwarfref(ctxt *Link, s *Symbol, t *Symbol, size int) int64 { return result } -func newrefattr(die *dwarf.DWDie, attr uint16, ref *Symbol) *dwarf.DWAttr { +func newrefattr(die *dwarf.DWDie, attr uint16, ref *sym.Symbol) *dwarf.DWAttr { if ref == nil { return nil } return newattr(die, attr, dwarf.DW_CLS_REFERENCE, 0, ref) } -func putdies(linkctxt *Link, ctxt dwarf.Context, syms []*Symbol, die *dwarf.DWDie) []*Symbol { +func putdies(linkctxt *Link, ctxt dwarf.Context, syms []*sym.Symbol, die *dwarf.DWDie) []*sym.Symbol { for ; die != nil; die = die.Link { syms = putdie(linkctxt, ctxt, syms, die) } @@ -238,14 +239,14 @@ func putdies(linkctxt *Link, ctxt dwarf.Context, syms []*Symbol, die *dwarf.DWDi return syms } -func dtolsym(s dwarf.Sym) *Symbol { +func dtolsym(s dwarf.Sym) *sym.Symbol { if s == nil { return nil } - return s.(*Symbol) + return s.(*sym.Symbol) } -func putdie(linkctxt *Link, ctxt dwarf.Context, syms []*Symbol, die *dwarf.DWDie) []*Symbol { +func putdie(linkctxt *Link, ctxt dwarf.Context, syms []*sym.Symbol, die *dwarf.DWDie) []*sym.Symbol { s := dtolsym(die.Sym) if s == nil { s = syms[len(syms)-1] @@ -253,7 +254,7 @@ func putdie(linkctxt *Link, ctxt dwarf.Context, syms []*Symbol, die *dwarf.DWDie if s.Attr.OnList() { log.Fatalf("symbol %s listed multiple times", s.Name) } - s.Attr |= AttrOnList + s.Attr |= sym.AttrOnList syms = append(syms, s) } dwarf.Uleb128put(ctxt, s, int64(die.Abbrev)) @@ -292,13 +293,13 @@ func newmemberoffsetattr(die *dwarf.DWDie, offs int32) { // GDB doesn't like FORM_addr for AT_location, so emit a // location expression that evals to a const. -func newabslocexprattr(die *dwarf.DWDie, addr int64, sym *Symbol) { +func newabslocexprattr(die *dwarf.DWDie, addr int64, sym *sym.Symbol) { newattr(die, dwarf.DW_AT_location, dwarf.DW_CLS_ADDRESS, addr, sym) // below } // Lookup predefined types -func lookupOrDiag(ctxt *Link, n string) *Symbol { +func lookupOrDiag(ctxt *Link, n string) *sym.Symbol { s := ctxt.Syms.ROLookup(n, 0) if s == nil || s.Size == 0 { Exitf("dwarf: missing type: %s", n) @@ -325,10 +326,10 @@ func dotypedef(ctxt *Link, parent *dwarf.DWDie, name string, def *dwarf.DWDie) { Errorf(nil, "dwarf: bad def in dotypedef") } - sym := ctxt.Syms.Lookup(dtolsym(def.Sym).Name+"..def", 0) - sym.Attr |= AttrNotInSymbolTable - sym.Type = SDWARFINFO - def.Sym = sym + s := ctxt.Syms.Lookup(dtolsym(def.Sym).Name+"..def", 0) + s.Attr |= sym.AttrNotInSymbolTable + s.Type = sym.SDWARFINFO + def.Sym = s // The typedef entry must be created after the def, // so that future lookups will find the typedef instead @@ -336,11 +337,11 @@ func dotypedef(ctxt *Link, parent *dwarf.DWDie, name string, def *dwarf.DWDie) { // circular definition loops, so that gdb can understand them. die := newdie(ctxt, parent, dwarf.DW_ABRV_TYPEDECL, name, 0) - newrefattr(die, dwarf.DW_AT_type, sym) + newrefattr(die, dwarf.DW_AT_type, s) } // Define gotype, for composite ones recurse into constituents. -func defgotype(ctxt *Link, gotype *Symbol) *Symbol { +func defgotype(ctxt *Link, gotype *sym.Symbol) *sym.Symbol { if gotype == nil { return mustFind(ctxt, "") } @@ -358,10 +359,10 @@ func defgotype(ctxt *Link, gotype *Symbol) *Symbol { return sdie } - return newtype(ctxt, gotype).Sym.(*Symbol) + return newtype(ctxt, gotype).Sym.(*sym.Symbol) } -func newtype(ctxt *Link, gotype *Symbol) *dwarf.DWDie { +func newtype(ctxt *Link, gotype *sym.Symbol) *dwarf.DWDie { name := gotype.Name[5:] // could also decode from Type.string kind := decodetypeKind(ctxt.Arch, gotype) bytesize := decodetypeSize(ctxt.Arch, gotype) @@ -433,7 +434,7 @@ func newtype(ctxt *Link, gotype *Symbol) *dwarf.DWDie { newrefattr(die, dwarf.DW_AT_type, mustFind(ctxt, "void")) nfields := decodetypeFuncInCount(ctxt.Arch, gotype) var fld *dwarf.DWDie - var s *Symbol + var s *sym.Symbol for i := 0; i < nfields; i++ { s = decodetypeFuncInType(ctxt.Arch, gotype, i) fld = newdie(ctxt, die, dwarf.DW_ABRV_FUNCTYPEPARAM, s.Name[5:], 0) @@ -455,7 +456,7 @@ func newtype(ctxt *Link, gotype *Symbol) *dwarf.DWDie { dotypedef(ctxt, &dwtypes, name, die) newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0) nfields := int(decodetypeIfaceMethodCount(ctxt.Arch, gotype)) - var s *Symbol + var s *sym.Symbol if nfields == 0 { s = lookupOrDiag(ctxt, "type.runtime.eface") } else { @@ -529,12 +530,12 @@ func newtype(ctxt *Link, gotype *Symbol) *dwarf.DWDie { return die } -func nameFromDIESym(dwtype *Symbol) string { +func nameFromDIESym(dwtype *sym.Symbol) string { return strings.TrimSuffix(dwtype.Name[len(dwarf.InfoPrefix):], "..def") } // Find or construct *T given T. -func defptrto(ctxt *Link, dwtype *Symbol) *Symbol { +func defptrto(ctxt *Link, dwtype *sym.Symbol) *sym.Symbol { ptrname := "*" + nameFromDIESym(dwtype) die := find(ctxt, ptrname) if die == nil { @@ -570,7 +571,7 @@ func copychildren(ctxt *Link, dst *dwarf.DWDie, src *dwarf.DWDie) { // Search children (assumed to have TAG_member) for the one named // field and set its AT_type to dwtype -func substitutetype(structdie *dwarf.DWDie, field string, dwtype *Symbol) { +func substitutetype(structdie *dwarf.DWDie, field string, dwtype *sym.Symbol) { child := findchild(structdie, field) if child == nil { Exitf("dwarf substitutetype: %s does not have member %s", @@ -620,7 +621,7 @@ func synthesizeslicetypes(ctxt *Link, die *dwarf.DWDie) { continue } copychildren(ctxt, die, prototype) - elem := getattr(die, dwarf.DW_AT_go_elem).Data.(*Symbol) + elem := getattr(die, dwarf.DW_AT_go_elem).Data.(*sym.Symbol) substitutetype(die, "array", defptrto(ctxt, elem)) } } @@ -644,11 +645,11 @@ const ( BucketSize = 8 ) -func mkinternaltype(ctxt *Link, abbrev int, typename, keyname, valname string, f func(*dwarf.DWDie)) *Symbol { +func mkinternaltype(ctxt *Link, abbrev int, typename, keyname, valname string, f func(*dwarf.DWDie)) *sym.Symbol { name := mkinternaltypename(typename, keyname, valname) symname := dwarf.InfoPrefix + name s := ctxt.Syms.ROLookup(symname, 0) - if s != nil && s.Type == SDWARFINFO { + if s != nil && s.Type == sym.SDWARFINFO { return s } die := newdie(ctxt, &dwtypes, abbrev, name, 0) @@ -668,7 +669,7 @@ func synthesizemaptypes(ctxt *Link, die *dwarf.DWDie) { if die.Abbrev != dwarf.DW_ABRV_MAPTYPE { continue } - gotype := getattr(die, dwarf.DW_AT_type).Data.(*Symbol) + gotype := getattr(die, dwarf.DW_AT_type).Data.(*sym.Symbol) keytype := decodetypeMapKey(ctxt.Arch, gotype) valtype := decodetypeMapValue(ctxt.Arch, gotype) keysize, valsize := decodetypeSize(ctxt.Arch, keytype), decodetypeSize(ctxt.Arch, valtype) @@ -764,7 +765,7 @@ func synthesizechantypes(ctxt *Link, die *dwarf.DWDie) { if die.Abbrev != dwarf.DW_ABRV_CHANTYPE { continue } - elemgotype := getattr(die, dwarf.DW_AT_type).Data.(*Symbol) + elemgotype := getattr(die, dwarf.DW_AT_type).Data.(*sym.Symbol) elemname := elemgotype.Name[5:] elemtype := walksymtypedef(ctxt, defgotype(ctxt, elemgotype)) @@ -797,30 +798,30 @@ func synthesizechantypes(ctxt *Link, die *dwarf.DWDie) { } // For use with pass.c::genasmsym -func defdwsymb(ctxt *Link, sym *Symbol, s string, t SymbolType, v int64, gotype *Symbol) { - if strings.HasPrefix(s, "go.string.") { +func defdwsymb(ctxt *Link, s *sym.Symbol, str string, t SymbolType, v int64, gotype *sym.Symbol) { + if strings.HasPrefix(str, "go.string.") { return } - if strings.HasPrefix(s, "runtime.gcbits.") { + if strings.HasPrefix(str, "runtime.gcbits.") { return } - if strings.HasPrefix(s, "type.") && s != "type.*" && !strings.HasPrefix(s, "type..") { - defgotype(ctxt, sym) + if strings.HasPrefix(str, "type.") && str != "type.*" && !strings.HasPrefix(str, "type..") { + defgotype(ctxt, s) return } var dv *dwarf.DWDie - var dt *Symbol + var dt *sym.Symbol switch t { default: return case DataSym, BSSSym: - dv = newdie(ctxt, &dwglobals, dwarf.DW_ABRV_VARIABLE, s, int(sym.Version)) - newabslocexprattr(dv, v, sym) - if sym.Version == 0 { + dv = newdie(ctxt, &dwglobals, dwarf.DW_ABRV_VARIABLE, str, int(s.Version)) + newabslocexprattr(dv, v, s) + if s.Version == 0 { newattr(dv, dwarf.DW_AT_external, dwarf.DW_CLS_FLAG, 1, 0) } fallthrough @@ -847,7 +848,7 @@ func movetomodule(parent *dwarf.DWDie) { } // If the pcln table contains runtime/proc.go, use that to set gdbscript path. -func finddebugruntimepath(s *Symbol) { +func finddebugruntimepath(s *sym.Symbol) { if gdbscript != "" { return } @@ -875,7 +876,7 @@ const ( OPCODE_BASE = 10 ) -func putpclcdelta(linkctxt *Link, ctxt dwarf.Context, s *Symbol, deltaPC uint64, deltaLC int64) { +func putpclcdelta(linkctxt *Link, ctxt dwarf.Context, s *sym.Symbol, deltaPC uint64, deltaLC int64) { // Choose a special opcode that minimizes the number of bytes needed to // encode the remaining PC delta and LC delta. var opcode int64 @@ -976,9 +977,9 @@ func getCompilationDir() string { return "/" } -func importInfoSymbol(ctxt *Link, dsym *Symbol) { - dsym.Attr |= AttrNotInSymbolTable | AttrReachable - dsym.Type = SDWARFINFO +func importInfoSymbol(ctxt *Link, dsym *sym.Symbol) { + dsym.Attr |= sym.AttrNotInSymbolTable | sym.AttrReachable + dsym.Type = sym.SDWARFINFO for _, r := range dsym.R { if r.Type == objabi.R_DWARFREF && r.Sym.Size == 0 { if Buildmode == BuildmodeShared { @@ -991,20 +992,20 @@ func importInfoSymbol(ctxt *Link, dsym *Symbol) { } } -func writelines(ctxt *Link, syms []*Symbol) ([]*Symbol, []*Symbol) { +func writelines(ctxt *Link, syms []*sym.Symbol) ([]*sym.Symbol, []*sym.Symbol) { var dwarfctxt dwarf.Context = dwctxt{ctxt} ls := ctxt.Syms.Lookup(".debug_line", 0) - ls.Type = SDWARFSECT + ls.Type = sym.SDWARFSECT ls.R = ls.R[:0] syms = append(syms, ls) - var funcs []*Symbol + var funcs []*sym.Symbol unitstart := int64(-1) headerstart := int64(-1) headerend := int64(-1) epc := int64(0) - var epcs *Symbol + var epcs *sym.Symbol var dwinfo *dwarf.DWDie lang := dwarf.DW_LANG_Go @@ -1161,10 +1162,10 @@ func appendPCDeltaCFA(arch *sys.Arch, b []byte, deltapc, cfa int64) []byte { return b } -func writeframes(ctxt *Link, syms []*Symbol) []*Symbol { +func writeframes(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol { var dwarfctxt dwarf.Context = dwctxt{ctxt} fs := ctxt.Syms.Lookup(".debug_frame", 0) - fs.Type = SDWARFSECT + fs.Type = sym.SDWARFSECT fs.R = fs.R[:0] syms = append(syms, fs) @@ -1267,29 +1268,29 @@ func writeframes(ctxt *Link, syms []*Symbol) []*Symbol { fs.AddUint32(ctxt.Arch, 0) // CIE offset } fs.AddAddr(ctxt.Arch, s) - fs.addUintXX(ctxt.Arch, uint64(s.Size), ctxt.Arch.PtrSize) // address range + fs.AddUintXX(ctxt.Arch, uint64(s.Size), ctxt.Arch.PtrSize) // address range fs.AddBytes(deltaBuf) } return syms } -func writeranges(ctxt *Link, syms []*Symbol) []*Symbol { +func writeranges(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol { empty := true for _, s := range ctxt.Textp { rangeSym := ctxt.Syms.Lookup(dwarf.RangePrefix+s.Name, int(s.Version)) if rangeSym.Size == 0 { continue } - rangeSym.Attr |= AttrReachable | AttrNotInSymbolTable - rangeSym.Type = SDWARFRANGE + rangeSym.Attr |= sym.AttrReachable | sym.AttrNotInSymbolTable + rangeSym.Type = sym.SDWARFRANGE syms = append(syms, rangeSym) empty = false } if !empty { // PE does not like empty sections rangesec := ctxt.Syms.Lookup(".debug_ranges", 0) - rangesec.Type = SDWARFRANGE - rangesec.Attr |= AttrReachable + rangesec.Type = sym.SDWARFRANGE + rangesec.Attr |= sym.AttrReachable rangesec.R = rangesec.R[:0] syms = append(syms, rangesec) @@ -1304,11 +1305,11 @@ const ( COMPUNITHEADERSIZE = 4 + 2 + 4 + 1 ) -func writeinfo(ctxt *Link, syms []*Symbol, funcs, consts []*Symbol, abbrevsym *Symbol) []*Symbol { +func writeinfo(ctxt *Link, syms []*sym.Symbol, funcs, consts []*sym.Symbol, abbrevsym *sym.Symbol) []*sym.Symbol { infosec := ctxt.Syms.Lookup(".debug_info", 0) infosec.R = infosec.R[:0] - infosec.Type = SDWARFINFO - infosec.Attr |= AttrReachable + infosec.Type = sym.SDWARFINFO + infosec.Attr |= sym.AttrReachable syms = append(syms, infosec) arangessec := ctxt.Syms.Lookup(".dwarfaranges", 0) @@ -1333,7 +1334,7 @@ func writeinfo(ctxt *Link, syms []*Symbol, funcs, consts []*Symbol, abbrevsym *S dwarf.Uleb128put(dwarfctxt, s, int64(compunit.Abbrev)) dwarf.PutAttrs(dwarfctxt, s, compunit.Abbrev, compunit.Attr) - cu := []*Symbol{s} + cu := []*sym.Symbol{s} if funcs != nil { cu = append(cu, funcs...) funcs = nil @@ -1373,9 +1374,9 @@ func ispubtype(die *dwarf.DWDie) bool { return die.Abbrev >= dwarf.DW_ABRV_NULLTYPE } -func writepub(ctxt *Link, sname string, ispub func(*dwarf.DWDie) bool, syms []*Symbol) []*Symbol { +func writepub(ctxt *Link, sname string, ispub func(*dwarf.DWDie) bool, syms []*sym.Symbol) []*sym.Symbol { s := ctxt.Syms.Lookup(sname, 0) - s.Type = SDWARFSECT + s.Type = sym.SDWARFSECT syms = append(syms, s) for compunit := dwroot.Child; compunit != nil; compunit = compunit.Link { @@ -1413,9 +1414,9 @@ func writepub(ctxt *Link, sname string, ispub func(*dwarf.DWDie) bool, syms []*S * emit .debug_aranges. _info must have been written before, * because we need die->offs of dwarf.DW_globals. */ -func writearanges(ctxt *Link, syms []*Symbol) []*Symbol { +func writearanges(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol { s := ctxt.Syms.Lookup(".debug_aranges", 0) - s.Type = SDWARFSECT + s.Type = sym.SDWARFSECT // The first tuple is aligned to a multiple of the size of a single tuple // (twice the size of an address) headersize := int(Rnd(4+2+4+1+1, int64(ctxt.Arch.PtrSize*2))) // don't count unit_length field itself @@ -1444,10 +1445,10 @@ func writearanges(ctxt *Link, syms []*Symbol) []*Symbol { s.AddUint8(0) } - s.AddAddrPlus(ctxt.Arch, b.Data.(*Symbol), b.Value-(b.Data.(*Symbol)).Value) - s.addUintXX(ctxt.Arch, uint64(e.Value-b.Value), ctxt.Arch.PtrSize) - s.addUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize) - s.addUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize) + s.AddAddrPlus(ctxt.Arch, b.Data.(*sym.Symbol), b.Value-(b.Data.(*sym.Symbol)).Value) + s.AddUintXX(ctxt.Arch, uint64(e.Value-b.Value), ctxt.Arch.PtrSize) + s.AddUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize) + s.AddUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize) } if s.Size > 0 { syms = append(syms, s) @@ -1455,7 +1456,7 @@ func writearanges(ctxt *Link, syms []*Symbol) []*Symbol { return syms } -func writegdbscript(ctxt *Link, syms []*Symbol) []*Symbol { +func writegdbscript(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol { if Linkmode == LinkExternal && Headtype == objabi.Hwindows && Buildmode == BuildmodeCArchive { // gcc on Windows places .debug_gdb_scripts in the wrong location, which // causes the program not to run. See https://golang.org/issue/20183 @@ -1468,7 +1469,7 @@ func writegdbscript(ctxt *Link, syms []*Symbol) []*Symbol { if gdbscript != "" { s := ctxt.Syms.Lookup(".debug_gdb_scripts", 0) - s.Type = SDWARFSECT + s.Type = sym.SDWARFSECT syms = append(syms, s) s.AddUint8(1) // magic 1 byte? Addstring(s, gdbscript) @@ -1556,7 +1557,7 @@ func dwarfgeneratedebugsyms(ctxt *Link) { genasmsym(ctxt, defdwsymb) - var consts []*Symbol + var consts []*sym.Symbol for _, lib := range ctxt.Library { if s := ctxt.Syms.Lookup(dwarf.ConstInfoPrefix+lib.Pkg, 0); s != nil { importInfoSymbol(ctxt, s) @@ -1565,7 +1566,7 @@ func dwarfgeneratedebugsyms(ctxt *Link) { } abbrev := writeabbrev(ctxt) - syms := []*Symbol{abbrev} + syms := []*sym.Symbol{abbrev} syms, funcs := writelines(ctxt, syms) syms = writeframes(ctxt, syms) @@ -1581,7 +1582,7 @@ func dwarfgeneratedebugsyms(ctxt *Link) { movetomodule(&dwtypes) movetomodule(&dwglobals) - // Need to reorder symbols so SDWARFINFO is after all SDWARFSECT + // Need to reorder symbols so sym.SDWARFINFO is after all sym.SDWARFSECT // (but we need to generate dies before writepub) infosyms := writeinfo(ctxt, nil, funcs, consts, abbrev) @@ -1595,12 +1596,12 @@ func dwarfgeneratedebugsyms(ctxt *Link) { dwarfp = syms } -func collectlocs(ctxt *Link, syms []*Symbol, funcs []*Symbol) []*Symbol { +func collectlocs(ctxt *Link, syms []*sym.Symbol, funcs []*sym.Symbol) []*sym.Symbol { empty := true for _, fn := range funcs { for _, reloc := range fn.R { if reloc.Type == objabi.R_DWARFREF && strings.HasPrefix(reloc.Sym.Name, dwarf.LocPrefix) { - reloc.Sym.Attr |= AttrReachable | AttrNotInSymbolTable + reloc.Sym.Attr |= sym.AttrReachable | sym.AttrNotInSymbolTable syms = append(syms, reloc.Sym) empty = false // One location list entry per function, but many relocations to it. Don't duplicate. @@ -1612,8 +1613,8 @@ func collectlocs(ctxt *Link, syms []*Symbol, funcs []*Symbol) []*Symbol { if !empty { locsym := ctxt.Syms.Lookup(".debug_loc", 0) locsym.R = locsym.R[:0] - locsym.Type = SDWARFLOC - locsym.Attr |= AttrReachable + locsym.Type = sym.SDWARFLOC + locsym.Attr |= sym.AttrReachable syms = append(syms, locsym) } return syms @@ -1622,7 +1623,7 @@ func collectlocs(ctxt *Link, syms []*Symbol, funcs []*Symbol) []*Symbol { /* * Elf. */ -func dwarfaddshstrings(ctxt *Link, shstrtab *Symbol) { +func dwarfaddshstrings(ctxt *Link, shstrtab *sym.Symbol) { if *FlagW { // disable dwarf return } @@ -1658,20 +1659,20 @@ func dwarfaddelfsectionsyms(ctxt *Link) { if Linkmode != LinkExternal { return } - sym := ctxt.Syms.Lookup(".debug_info", 0) - putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum) - sym = ctxt.Syms.Lookup(".debug_abbrev", 0) - putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum) - sym = ctxt.Syms.Lookup(".debug_line", 0) - putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum) - sym = ctxt.Syms.Lookup(".debug_frame", 0) - putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum) - sym = ctxt.Syms.Lookup(".debug_loc", 0) - if sym.Sect != nil { - putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum) - } - sym = ctxt.Syms.Lookup(".debug_ranges", 0) - if sym.Sect != nil { - putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum) + s := ctxt.Syms.Lookup(".debug_info", 0) + putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum) + s = ctxt.Syms.Lookup(".debug_abbrev", 0) + putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum) + s = ctxt.Syms.Lookup(".debug_line", 0) + putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum) + s = ctxt.Syms.Lookup(".debug_frame", 0) + putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum) + s = ctxt.Syms.Lookup(".debug_loc", 0) + if s.Sect != nil { + putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum) + } + s = ctxt.Syms.Lookup(".debug_ranges", 0) + if s.Sect != nil { + putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum) } } diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go index 7c1e789827..da1a042fb5 100644 --- a/src/cmd/link/internal/ld/elf.go +++ b/src/cmd/link/internal/ld/elf.go @@ -7,6 +7,7 @@ package ld import ( "cmd/internal/objabi" "cmd/internal/sys" + "cmd/link/internal/sym" "crypto/sha1" "encoding/binary" "encoding/hex" @@ -809,7 +810,7 @@ type ElfShdr struct { addralign uint64 entsize uint64 shnum int - secsym *Symbol + secsym *sym.Symbol } /* @@ -1060,7 +1061,7 @@ func elfwriteshdrs(out *OutBuf) uint32 { return uint32(ehdr.shnum) * ELF32SHDRSIZE } -func elfsetstring(s *Symbol, str string, off int) { +func elfsetstring(s *sym.Symbol, str string, off int) { if nelfstr >= len(elfstr) { Errorf(s, "too many elf strings") errorexit() @@ -1175,7 +1176,7 @@ func elfhash(name string) uint32 { return h } -func Elfwritedynent(ctxt *Link, s *Symbol, tag int, val uint64) { +func Elfwritedynent(ctxt *Link, s *sym.Symbol, tag int, val uint64) { if elf64 { s.AddUint64(ctxt.Arch, uint64(tag)) s.AddUint64(ctxt.Arch, val) @@ -1185,11 +1186,11 @@ func Elfwritedynent(ctxt *Link, s *Symbol, tag int, val uint64) { } } -func elfwritedynentsym(ctxt *Link, s *Symbol, tag int, t *Symbol) { +func elfwritedynentsym(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol) { Elfwritedynentsymplus(ctxt, s, tag, t, 0) } -func Elfwritedynentsymplus(ctxt *Link, s *Symbol, tag int, t *Symbol, add int64) { +func Elfwritedynentsymplus(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol, add int64) { if elf64 { s.AddUint64(ctxt.Arch, uint64(tag)) } else { @@ -1198,7 +1199,7 @@ func Elfwritedynentsymplus(ctxt *Link, s *Symbol, tag int, t *Symbol, add int64) s.AddAddrPlus(ctxt.Arch, t, add) } -func elfwritedynentsymsize(ctxt *Link, s *Symbol, tag int, t *Symbol) { +func elfwritedynentsymsize(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol) { if elf64 { s.AddUint64(ctxt.Arch, uint64(tag)) } else { @@ -1446,8 +1447,8 @@ func elfdynhash(ctxt *Link) { nsym := Nelfsym s := ctxt.Syms.Lookup(".hash", 0) - s.Type = SELFROSECT - s.Attr |= AttrReachable + s.Type = sym.SELFROSECT + s.Attr |= sym.AttrReachable i := nsym nbucket := 1 @@ -1575,7 +1576,7 @@ func elfdynhash(ctxt *Link) { Elfwritedynent(ctxt, s, DT_NULL, 0) } -func elfphload(seg *Segment) *ElfPhdr { +func elfphload(seg *sym.Segment) *ElfPhdr { ph := newElfPhdr() ph.type_ = PT_LOAD if seg.Rwx&4 != 0 { @@ -1597,7 +1598,7 @@ func elfphload(seg *Segment) *ElfPhdr { return ph } -func elfphrelro(seg *Segment) { +func elfphrelro(seg *sym.Segment) { ph := newElfPhdr() ph.type_ = PT_GNU_RELRO ph.vaddr = seg.Vaddr @@ -1640,20 +1641,20 @@ func elfshnamedup(name string) *ElfShdr { return nil } -func elfshalloc(sect *Section) *ElfShdr { +func elfshalloc(sect *sym.Section) *ElfShdr { sh := elfshname(sect.Name) sect.Elfsect = sh return sh } -func elfshbits(sect *Section) *ElfShdr { +func elfshbits(sect *sym.Section) *ElfShdr { var sh *ElfShdr if sect.Name == ".text" { if sect.Elfsect == nil { sect.Elfsect = elfshnamedup(sect.Name) } - sh = sect.Elfsect + sh = sect.Elfsect.(*ElfShdr) } else { sh = elfshalloc(sect) } @@ -1712,7 +1713,7 @@ func elfshbits(sect *Section) *ElfShdr { return sh } -func elfshreloc(arch *sys.Arch, sect *Section) *ElfShdr { +func elfshreloc(arch *sys.Arch, sect *sym.Section) *ElfShdr { // If main section is SHT_NOBITS, nothing to relocate. // Also nothing to relocate in .shstrtab or notes. if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen { @@ -1721,7 +1722,7 @@ func elfshreloc(arch *sys.Arch, sect *Section) *ElfShdr { if sect.Name == ".shstrtab" || sect.Name == ".tbss" { return nil } - if sect.Elfsect.type_ == SHT_NOTE { + if sect.Elfsect.(*ElfShdr).type_ == SHT_NOTE { return nil } @@ -1737,7 +1738,7 @@ func elfshreloc(arch *sys.Arch, sect *Section) *ElfShdr { // its own .rela.text. if sect.Name == ".text" { - if sh.info != 0 && sh.info != uint32(sect.Elfsect.shnum) { + if sh.info != 0 && sh.info != uint32(sect.Elfsect.(*ElfShdr).shnum) { sh = elfshnamedup(elfRelType + sect.Name) } } @@ -1748,14 +1749,14 @@ func elfshreloc(arch *sys.Arch, sect *Section) *ElfShdr { sh.entsize += uint64(arch.RegSize) } sh.link = uint32(elfshname(".symtab").shnum) - sh.info = uint32(sect.Elfsect.shnum) + sh.info = uint32(sect.Elfsect.(*ElfShdr).shnum) sh.off = sect.Reloff sh.size = sect.Rellen sh.addralign = uint64(arch.RegSize) return sh } -func elfrelocsect(ctxt *Link, sect *Section, syms []*Symbol) { +func elfrelocsect(ctxt *Link, sect *sym.Section, syms []*sym.Symbol) { // If main section is SHT_NOBITS, nothing to relocate. // Also nothing to relocate in .shstrtab. if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen { @@ -1777,30 +1778,30 @@ func elfrelocsect(ctxt *Link, sect *Section, syms []*Symbol) { } eaddr := int32(sect.Vaddr + sect.Length) - for _, sym := range syms { - if !sym.Attr.Reachable() { + for _, s := range syms { + if !s.Attr.Reachable() { continue } - if sym.Value >= int64(eaddr) { + if s.Value >= int64(eaddr) { break } - for ri := 0; ri < len(sym.R); ri++ { - r := &sym.R[ri] + for ri := 0; ri < len(s.R); ri++ { + r := &s.R[ri] if r.Done { continue } if r.Xsym == nil { - Errorf(sym, "missing xsym in relocation %#v %#v", r.Sym.Name, sym) + Errorf(s, "missing xsym in relocation %#v %#v", r.Sym.Name, s) continue } if r.Xsym.ElfsymForReloc() == 0 { - Errorf(sym, "reloc %d (%s) to non-elf symbol %s (outer=%s) %d (%s)", r.Type, RelocName(ctxt.Arch, r.Type), r.Sym.Name, r.Xsym.Name, r.Sym.Type, r.Sym.Type) + Errorf(s, "reloc %d (%s) to non-elf symbol %s (outer=%s) %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Sym.Name, r.Xsym.Name, r.Sym.Type, r.Sym.Type) } if !r.Xsym.Attr.Reachable() { - Errorf(sym, "unreachable reloc %d (%s) target %v", r.Type, RelocName(ctxt.Arch, r.Type), r.Xsym.Name) + Errorf(s, "unreachable reloc %d (%s) target %v", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Xsym.Name) } - if !Thearch.Elfreloc1(ctxt, r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) { - Errorf(sym, "unsupported obj reloc %d (%s)/%d to %s", r.Type, RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name) + if !Thearch.Elfreloc1(ctxt, r, int64(uint64(s.Value+int64(r.Off))-sect.Vaddr)) { + Errorf(s, "unsupported obj reloc %d (%s)/%d to %s", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name) } } } @@ -1837,8 +1838,8 @@ func Elfemitreloc(ctxt *Link) { func addgonote(ctxt *Link, sectionName string, tag uint32, desc []byte) { s := ctxt.Syms.Lookup(sectionName, 0) - s.Attr |= AttrReachable - s.Type = SELFROSECT + s.Attr |= sym.AttrReachable + s.Type = sym.SELFROSECT // namesz s.AddUint32(ctxt.Arch, uint32(len(ELF_NOTE_GO_NAME))) // descsz @@ -1867,8 +1868,8 @@ func (ctxt *Link) doelf() { /* predefine strings we need for section headers */ shstrtab := ctxt.Syms.Lookup(".shstrtab", 0) - shstrtab.Type = SELFROSECT - shstrtab.Attr |= AttrReachable + shstrtab.Type = sym.SELFROSECT + shstrtab.Attr |= sym.AttrReachable Addstring(shstrtab, "") Addstring(shstrtab, ".text") @@ -1975,8 +1976,8 @@ func (ctxt *Link) doelf() { /* dynamic symbol table - first entry all zeros */ s := ctxt.Syms.Lookup(".dynsym", 0) - s.Type = SELFROSECT - s.Attr |= AttrReachable + s.Type = sym.SELFROSECT + s.Attr |= sym.AttrReachable if elf64 { s.Size += ELF64SYMSIZE } else { @@ -1986,8 +1987,8 @@ func (ctxt *Link) doelf() { /* dynamic string table */ s = ctxt.Syms.Lookup(".dynstr", 0) - s.Type = SELFROSECT - s.Attr |= AttrReachable + s.Type = sym.SELFROSECT + s.Attr |= sym.AttrReachable if s.Size == 0 { Addstring(s, "") } @@ -1995,62 +1996,62 @@ func (ctxt *Link) doelf() { /* relocation table */ s = ctxt.Syms.Lookup(elfRelType, 0) - s.Attr |= AttrReachable - s.Type = SELFROSECT + s.Attr |= sym.AttrReachable + s.Type = sym.SELFROSECT /* global offset table */ s = ctxt.Syms.Lookup(".got", 0) - s.Attr |= AttrReachable - s.Type = SELFGOT // writable + s.Attr |= sym.AttrReachable + s.Type = sym.SELFGOT // writable /* ppc64 glink resolver */ if ctxt.Arch.Family == sys.PPC64 { s := ctxt.Syms.Lookup(".glink", 0) - s.Attr |= AttrReachable - s.Type = SELFRXSECT + s.Attr |= sym.AttrReachable + s.Type = sym.SELFRXSECT } /* hash */ s = ctxt.Syms.Lookup(".hash", 0) - s.Attr |= AttrReachable - s.Type = SELFROSECT + s.Attr |= sym.AttrReachable + s.Type = sym.SELFROSECT s = ctxt.Syms.Lookup(".got.plt", 0) - s.Attr |= AttrReachable - s.Type = SELFSECT // writable + s.Attr |= sym.AttrReachable + s.Type = sym.SELFSECT // writable s = ctxt.Syms.Lookup(".plt", 0) - s.Attr |= AttrReachable + s.Attr |= sym.AttrReachable if ctxt.Arch.Family == sys.PPC64 { // In the ppc64 ABI, .plt is a data section // written by the dynamic linker. - s.Type = SELFSECT + s.Type = sym.SELFSECT } else { - s.Type = SELFRXSECT + s.Type = sym.SELFRXSECT } Thearch.Elfsetupplt(ctxt) s = ctxt.Syms.Lookup(elfRelType+".plt", 0) - s.Attr |= AttrReachable - s.Type = SELFROSECT + s.Attr |= sym.AttrReachable + s.Type = sym.SELFROSECT s = ctxt.Syms.Lookup(".gnu.version", 0) - s.Attr |= AttrReachable - s.Type = SELFROSECT + s.Attr |= sym.AttrReachable + s.Type = sym.SELFROSECT s = ctxt.Syms.Lookup(".gnu.version_r", 0) - s.Attr |= AttrReachable - s.Type = SELFROSECT + s.Attr |= sym.AttrReachable + s.Type = sym.SELFROSECT /* define dynamic elf table */ s = ctxt.Syms.Lookup(".dynamic", 0) - s.Attr |= AttrReachable - s.Type = SELFSECT // writable + s.Attr |= sym.AttrReachable + s.Type = sym.SELFSECT // writable /* * .dynamic table @@ -2102,10 +2103,10 @@ func (ctxt *Link) doelf() { // The go.link.abihashbytes symbol will be pointed at the appropriate // part of the .note.go.abihash section in data.go:func address(). s := ctxt.Syms.Lookup("go.link.abihashbytes", 0) - s.Attr |= AttrLocal - s.Type = SRODATA - s.Attr |= AttrSpecial - s.Attr |= AttrReachable + s.Attr |= sym.AttrLocal + s.Type = sym.SRODATA + s.Attr |= sym.AttrSpecial + s.Attr |= sym.AttrReachable s.Size = int64(sha1.Size) sort.Sort(byPkg(ctxt.Library)) @@ -2128,7 +2129,7 @@ func (ctxt *Link) doelf() { } // Do not write DT_NULL. elfdynhash will finish it. -func shsym(sh *ElfShdr, s *Symbol) { +func shsym(sh *ElfShdr, s *sym.Symbol) { addr := Symaddr(s) if sh.flags&SHF_ALLOC != 0 { sh.addr = uint64(addr) @@ -2579,7 +2580,7 @@ elfobj: elfshreloc(ctxt.Arch, sect) } for _, s := range dwarfp { - if len(s.R) > 0 || s.Type == SDWARFINFO || s.Type == SDWARFLOC { + if len(s.R) > 0 || s.Type == sym.SDWARFINFO || s.Type == sym.SDWARFLOC { elfshreloc(ctxt.Arch, s.Sect) } } @@ -2682,7 +2683,7 @@ elfobj: } } -func elfadddynsym(ctxt *Link, s *Symbol) { +func elfadddynsym(ctxt *Link, s *sym.Symbol) { if elf64 { s.Dynid = int32(Nelfsym) Nelfsym++ @@ -2695,7 +2696,7 @@ func elfadddynsym(ctxt *Link, s *Symbol) { /* type */ t := STB_GLOBAL << 4 - if s.Attr.CgoExport() && s.Type&SMASK == STEXT { + if s.Attr.CgoExport() && s.Type&sym.SMASK == sym.STEXT { t |= STT_FUNC } else { t |= STT_OBJECT @@ -2706,14 +2707,14 @@ func elfadddynsym(ctxt *Link, s *Symbol) { d.AddUint8(0) /* section where symbol is defined */ - if s.Type == SDYNIMPORT { + if s.Type == sym.SDYNIMPORT { d.AddUint16(ctxt.Arch, SHN_UNDEF) } else { d.AddUint16(ctxt.Arch, 1) } /* value */ - if s.Type == SDYNIMPORT { + if s.Type == sym.SDYNIMPORT { d.AddUint64(ctxt.Arch, 0) } else { d.AddAddr(ctxt.Arch, s) @@ -2737,7 +2738,7 @@ func elfadddynsym(ctxt *Link, s *Symbol) { d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name))) /* value */ - if s.Type == SDYNIMPORT { + if s.Type == sym.SDYNIMPORT { d.AddUint32(ctxt.Arch, 0) } else { d.AddAddr(ctxt.Arch, s) @@ -2750,9 +2751,9 @@ func elfadddynsym(ctxt *Link, s *Symbol) { t := STB_GLOBAL << 4 // TODO(mwhudson): presumably the behavior should actually be the same on both arm and 386. - if ctxt.Arch.Family == sys.I386 && s.Attr.CgoExport() && s.Type&SMASK == STEXT { + if ctxt.Arch.Family == sys.I386 && s.Attr.CgoExport() && s.Type&sym.SMASK == sym.STEXT { t |= STT_FUNC - } else if ctxt.Arch.Family == sys.ARM && s.Attr.CgoExportDynamic() && s.Type&SMASK == STEXT { + } else if ctxt.Arch.Family == sys.ARM && s.Attr.CgoExportDynamic() && s.Type&sym.SMASK == sym.STEXT { t |= STT_FUNC } else { t |= STT_OBJECT @@ -2761,7 +2762,7 @@ func elfadddynsym(ctxt *Link, s *Symbol) { d.AddUint8(0) /* shndx */ - if s.Type == SDYNIMPORT { + if s.Type == sym.SDYNIMPORT { d.AddUint16(ctxt.Arch, SHN_UNDEF) } else { d.AddUint16(ctxt.Arch, 1) diff --git a/src/cmd/link/internal/ld/go.go b/src/cmd/link/internal/ld/go.go index 491b4e70f8..b69e1f3a41 100644 --- a/src/cmd/link/internal/ld/go.go +++ b/src/cmd/link/internal/ld/go.go @@ -10,6 +10,7 @@ import ( "bytes" "cmd/internal/bio" "cmd/internal/objabi" + "cmd/link/internal/sym" "fmt" "io" "os" @@ -128,7 +129,7 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) { var next string var q string var lib string - var s *Symbol + var s *sym.Symbol p0 := "" for ; p != ""; p = next { @@ -184,12 +185,12 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) { remote, q = remote[:i], remote[i+1:] } s = ctxt.Syms.Lookup(local, 0) - if s.Type == 0 || s.Type == SXREF || s.Type == SHOSTOBJ { + if s.Type == 0 || s.Type == sym.SXREF || s.Type == sym.SHOSTOBJ { s.Dynimplib = lib s.Extname = remote s.Dynimpvers = q - if s.Type != SHOSTOBJ { - s.Type = SDYNIMPORT + if s.Type != sym.SHOSTOBJ { + s.Type = sym.SDYNIMPORT } havedynamic = 1 } @@ -203,7 +204,7 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) { } local := f[1] s = ctxt.Syms.Lookup(local, 0) - s.Type = SHOSTOBJ + s.Type = sym.SHOSTOBJ s.Size = 0 continue } @@ -248,9 +249,9 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) { } if f[0] == "cgo_export_static" { - s.Attr |= AttrCgoExportStatic + s.Attr |= sym.AttrCgoExportStatic } else { - s.Attr |= AttrCgoExportDynamic + s.Attr |= sym.AttrCgoExportDynamic } continue } @@ -308,7 +309,7 @@ func adddynlib(ctxt *Link, lib string) { } } -func Adddynsym(ctxt *Link, s *Symbol) { +func Adddynsym(ctxt *Link, s *sym.Symbol) { if s.Dynid >= 0 || Linkmode == LinkExternal { return } @@ -329,8 +330,8 @@ func fieldtrack(ctxt *Link) { var buf bytes.Buffer for _, s := range ctxt.Syms.Allsym { if strings.HasPrefix(s.Name, "go.track.") { - s.Attr |= AttrSpecial // do not lay out in data segment - s.Attr |= AttrNotInSymbolTable + s.Attr |= sym.AttrSpecial // do not lay out in data segment + s.Attr |= sym.AttrNotInSymbolTable if s.Attr.Reachable() { buf.WriteString(s.Name[9:]) for p := s.Reachparent; p != nil; p = p.Reachparent { @@ -340,7 +341,7 @@ func fieldtrack(ctxt *Link) { buf.WriteString("\n") } - s.Type = SCONST + s.Type = sym.SCONST s.Value = 0 } } @@ -353,7 +354,7 @@ func fieldtrack(ctxt *Link) { return } addstrdata(ctxt, *flagFieldTrack, buf.String()) - s.Type = SDATA + s.Type = sym.SDATA } func (ctxt *Link) addexport() { diff --git a/src/cmd/link/internal/ld/ldelf.go b/src/cmd/link/internal/ld/ldelf.go index 148e152eeb..c700d62697 100644 --- a/src/cmd/link/internal/ld/ldelf.go +++ b/src/cmd/link/internal/ld/ldelf.go @@ -5,6 +5,7 @@ import ( "cmd/internal/bio" "cmd/internal/objabi" "cmd/internal/sys" + "cmd/link/internal/sym" "encoding/binary" "fmt" "io" @@ -266,7 +267,7 @@ type ElfSect struct { align uint64 entsize uint64 base []byte - sym *Symbol + sym *sym.Symbol } type ElfObj struct { @@ -305,7 +306,7 @@ type ElfSym struct { type_ uint8 other uint8 shndx uint16 - sym *Symbol + sym *sym.Symbol } var ElfMagic = [4]uint8{0x7F, 'E', 'L', 'F'} @@ -711,21 +712,21 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { return case ElfSectFlagAlloc: - s.Type = SRODATA + s.Type = sym.SRODATA case ElfSectFlagAlloc + ElfSectFlagWrite: if sect.type_ == ElfSectNobits { - s.Type = SNOPTRBSS + s.Type = sym.SNOPTRBSS } else { - s.Type = SNOPTRDATA + s.Type = sym.SNOPTRDATA } case ElfSectFlagAlloc + ElfSectFlagExec: - s.Type = STEXT + s.Type = sym.STEXT } if sect.name == ".got" || sect.name == ".toc" { - s.Type = SELFGOT + s.Type = sym.SELFGOT } if sect.type_ == ElfSectProgbits { s.P = sect.base @@ -739,57 +740,57 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { // enter sub-symbols into symbol table. // symbol 0 is the null symbol. - symbols := make([]*Symbol, elfobj.nsymtab) + symbols := make([]*sym.Symbol, elfobj.nsymtab) for i := 1; i < elfobj.nsymtab; i++ { - var sym ElfSym - if err := readelfsym(ctxt, elfobj, i, &sym, 1, localSymVersion); err != nil { + var elfsym ElfSym + if err := readelfsym(ctxt, elfobj, i, &elfsym, 1, localSymVersion); err != nil { Errorf(nil, "%s: malformed elf file: %v", pn, err) return } - symbols[i] = sym.sym - if sym.type_ != ElfSymTypeFunc && sym.type_ != ElfSymTypeObject && sym.type_ != ElfSymTypeNone && sym.type_ != ElfSymTypeCommon { + symbols[i] = elfsym.sym + if elfsym.type_ != ElfSymTypeFunc && elfsym.type_ != ElfSymTypeObject && elfsym.type_ != ElfSymTypeNone && elfsym.type_ != ElfSymTypeCommon { continue } - if sym.shndx == ElfSymShnCommon || sym.type_ == ElfSymTypeCommon { - s := sym.sym - if uint64(s.Size) < sym.size { - s.Size = int64(sym.size) + if elfsym.shndx == ElfSymShnCommon || elfsym.type_ == ElfSymTypeCommon { + s := elfsym.sym + if uint64(s.Size) < elfsym.size { + s.Size = int64(elfsym.size) } - if s.Type == 0 || s.Type == SXREF { - s.Type = SNOPTRBSS + if s.Type == 0 || s.Type == sym.SXREF { + s.Type = sym.SNOPTRBSS } continue } - if uint(sym.shndx) >= elfobj.nsect || sym.shndx == 0 { + if uint(elfsym.shndx) >= elfobj.nsect || elfsym.shndx == 0 { continue } // even when we pass needSym == 1 to readelfsym, it might still return nil to skip some unwanted symbols - if sym.sym == nil { + if elfsym.sym == nil { continue } - sect = &elfobj.sect[sym.shndx] + sect = &elfobj.sect[elfsym.shndx] if sect.sym == nil { - if strings.HasPrefix(sym.name, ".Linfo_string") { // clang does this + if strings.HasPrefix(elfsym.name, ".Linfo_string") { // clang does this continue } - if sym.name == "" && sym.type_ == 0 && sect.name == ".debug_str" { + if elfsym.name == "" && elfsym.type_ == 0 && sect.name == ".debug_str" { // This reportedly happens with clang 3.7 on ARM. // See issue 13139. continue } - if strings.HasPrefix(sym.name, ".LASF") { // gcc on s390x does this + if strings.HasPrefix(elfsym.name, ".LASF") { // gcc on s390x does this continue } - Errorf(sym.sym, "%s: sym#%d: ignoring symbol in section %d (type %d)", pn, i, sym.shndx, sym.type_) + Errorf(elfsym.sym, "%s: sym#%d: ignoring symbol in section %d (type %d)", pn, i, elfsym.shndx, elfsym.type_) continue } - s := sym.sym + s := elfsym.sym if s.Outer != nil { if s.Attr.DuplicateOK() { continue @@ -799,26 +800,26 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { s.Sub = sect.sym.Sub sect.sym.Sub = s - s.Type = sect.sym.Type | s.Type&^SMASK | SSUB + s.Type = sect.sym.Type | s.Type&^sym.SMASK | sym.SSUB if !s.Attr.CgoExportDynamic() { s.Dynimplib = "" // satisfy dynimport } - s.Value = int64(sym.value) - s.Size = int64(sym.size) + s.Value = int64(elfsym.value) + s.Size = int64(elfsym.size) s.Outer = sect.sym - if sect.sym.Type == STEXT { + if sect.sym.Type == sym.STEXT { if s.Attr.External() && !s.Attr.DuplicateOK() { Errorf(s, "%s: duplicate symbol definition", pn) } - s.Attr |= AttrExternal + s.Attr |= sym.AttrExternal } if elfobj.machine == ElfMachPower64 { - flag := int(sym.other) >> 5 + flag := int(elfsym.other) >> 5 if 2 <= flag && flag <= 6 { s.Localentry = 1 << uint(flag-2) } else if flag == 7 { - Errorf(s, "%s: invalid sym.other 0x%x", pn, sym.other) + Errorf(s, "%s: invalid sym.other 0x%x", pn, elfsym.other) } } } @@ -833,17 +834,17 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { if s.Sub != nil { s.Sub = listsort(s.Sub) } - if s.Type == STEXT { + if s.Type == sym.STEXT { if s.Attr.OnList() { log.Fatalf("symbol %s listed multiple times", s.Name) } - s.Attr |= AttrOnList + s.Attr |= sym.AttrOnList ctxt.Textp = append(ctxt.Textp, s) for s = s.Sub; s != nil; s = s.Sub { if s.Attr.OnList() { log.Fatalf("symbol %s listed multiple times", s.Name) } - s.Attr |= AttrOnList + s.Attr |= sym.AttrOnList ctxt.Textp = append(ctxt.Textp, s) } } @@ -868,7 +869,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { rela = 1 } n := int(rsect.size / uint64(4+4*is64) / uint64(2+rela)) - r := make([]Reloc, n) + r := make([]sym.Reloc, n) p := rsect.base for j := 0; j < n; j++ { var add uint64 @@ -908,18 +909,18 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { if info>>32 == 0 { // absolute relocation, don't bother reading the null symbol rp.Sym = nil } else { - var sym ElfSym - if err := readelfsym(ctxt, elfobj, int(info>>32), &sym, 0, 0); err != nil { + var elfsym ElfSym + if err := readelfsym(ctxt, elfobj, int(info>>32), &elfsym, 0, 0); err != nil { Errorf(nil, "%s: malformed elf file: %v", pn, err) return } - sym.sym = symbols[info>>32] - if sym.sym == nil { - Errorf(nil, "%s: malformed elf file: %s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", pn, sect.sym.Name, j, int(info>>32), sym.name, sym.shndx, sym.type_) + elfsym.sym = symbols[info>>32] + if elfsym.sym == nil { + Errorf(nil, "%s: malformed elf file: %s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", pn, sect.sym.Name, j, int(info>>32), elfsym.name, elfsym.shndx, elfsym.type_) return } - rp.Sym = sym.sym + rp.Sym = elfsym.sym } rp.Type = 256 + objabi.RelocType(info) @@ -985,7 +986,7 @@ func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) { return nil } -func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int, localSymVersion int) (err error) { +func readelfsym(ctxt *Link, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, localSymVersion int) (err error) { if i >= elfobj.nsymtab || i < 0 { err = fmt.Errorf("invalid elf symbol index") return err @@ -998,44 +999,44 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int, loc if elfobj.is64 != 0 { b := new(ElfSymBytes64) binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF64SYMSIZE:(i+1)*ELF64SYMSIZE]), elfobj.e, b) - sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):]) - sym.value = elfobj.e.Uint64(b.Value[:]) - sym.size = elfobj.e.Uint64(b.Size[:]) - sym.shndx = elfobj.e.Uint16(b.Shndx[:]) - sym.bind = b.Info >> 4 - sym.type_ = b.Info & 0xf - sym.other = b.Other + elfsym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):]) + elfsym.value = elfobj.e.Uint64(b.Value[:]) + elfsym.size = elfobj.e.Uint64(b.Size[:]) + elfsym.shndx = elfobj.e.Uint16(b.Shndx[:]) + elfsym.bind = b.Info >> 4 + elfsym.type_ = b.Info & 0xf + elfsym.other = b.Other } else { b := new(ElfSymBytes) binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF32SYMSIZE:(i+1)*ELF32SYMSIZE]), elfobj.e, b) - sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):]) - sym.value = uint64(elfobj.e.Uint32(b.Value[:])) - sym.size = uint64(elfobj.e.Uint32(b.Size[:])) - sym.shndx = elfobj.e.Uint16(b.Shndx[:]) - sym.bind = b.Info >> 4 - sym.type_ = b.Info & 0xf - sym.other = b.Other + elfsym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):]) + elfsym.value = uint64(elfobj.e.Uint32(b.Value[:])) + elfsym.size = uint64(elfobj.e.Uint32(b.Size[:])) + elfsym.shndx = elfobj.e.Uint16(b.Shndx[:]) + elfsym.bind = b.Info >> 4 + elfsym.type_ = b.Info & 0xf + elfsym.other = b.Other } - var s *Symbol - if sym.name == "_GLOBAL_OFFSET_TABLE_" { - sym.name = ".got" + var s *sym.Symbol + if elfsym.name == "_GLOBAL_OFFSET_TABLE_" { + elfsym.name = ".got" } - if sym.name == ".TOC." { + if elfsym.name == ".TOC." { // Magic symbol on ppc64. Will be set to this object // file's .got+0x8000. - sym.bind = ElfSymBindLocal + elfsym.bind = ElfSymBindLocal } - switch sym.type_ { + switch elfsym.type_ { case ElfSymTypeSection: - s = elfobj.sect[sym.shndx].sym + s = elfobj.sect[elfsym.shndx].sym case ElfSymTypeObject, ElfSymTypeFunc, ElfSymTypeNone, ElfSymTypeCommon: - switch sym.bind { + switch elfsym.bind { case ElfSymBindGlobal: if needSym != 0 { - s = ctxt.Syms.Lookup(sym.name, 0) + s = ctxt.Syms.Lookup(elfsym.name, 0) // for global scoped hidden symbols we should insert it into // symbol hash table, but mark them as hidden. @@ -1044,25 +1045,25 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int, loc // TODO(minux): correctly handle __i686.get_pc_thunk.bx without // set dupok generally. See http://codereview.appspot.com/5823055/ // comment #5 for details. - if s != nil && sym.other == 2 { - s.Type |= SHIDDEN - s.Attr |= AttrDuplicateOK + if s != nil && elfsym.other == 2 { + s.Type |= sym.SHIDDEN + s.Attr |= sym.AttrDuplicateOK } } case ElfSymBindLocal: - if ctxt.Arch.Family == sys.ARM && (strings.HasPrefix(sym.name, "$a") || strings.HasPrefix(sym.name, "$d")) { + if ctxt.Arch.Family == sys.ARM && (strings.HasPrefix(elfsym.name, "$a") || strings.HasPrefix(elfsym.name, "$d")) { // binutils for arm generate these mapping // symbols, ignore these break } - if sym.name == ".TOC." { + if elfsym.name == ".TOC." { // We need to be able to look this up, // so put it in the hash table. if needSym != 0 { - s = ctxt.Syms.Lookup(sym.name, localSymVersion) - s.Type |= SHIDDEN + s = ctxt.Syms.Lookup(elfsym.name, localSymVersion) + s.Type |= sym.SHIDDEN } break @@ -1072,34 +1073,34 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int, loc // local names and hidden global names are unique // and should only be referenced by their index, not name, so we // don't bother to add them into the hash table - s = ctxt.Syms.newsym(sym.name, localSymVersion) + s = ctxt.Syms.Newsym(elfsym.name, localSymVersion) - s.Type |= SHIDDEN + s.Type |= sym.SHIDDEN } case ElfSymBindWeak: if needSym != 0 { - s = ctxt.Syms.Lookup(sym.name, 0) - if sym.other == 2 { - s.Type |= SHIDDEN + s = ctxt.Syms.Lookup(elfsym.name, 0) + if elfsym.other == 2 { + s.Type |= sym.SHIDDEN } } default: - err = fmt.Errorf("%s: invalid symbol binding %d", sym.name, sym.bind) + err = fmt.Errorf("%s: invalid symbol binding %d", elfsym.name, elfsym.bind) return err } } - if s != nil && s.Type == 0 && sym.type_ != ElfSymTypeSection { - s.Type = SXREF + if s != nil && s.Type == 0 && elfsym.type_ != ElfSymTypeSection { + s.Type = sym.SXREF } - sym.sym = s + elfsym.sym = s return nil } -type rbyoff []Reloc +type rbyoff []sym.Reloc func (x rbyoff) Len() int { return len(x) diff --git a/src/cmd/link/internal/ld/ldmacho.go b/src/cmd/link/internal/ld/ldmacho.go index 272161d482..598dba2727 100644 --- a/src/cmd/link/internal/ld/ldmacho.go +++ b/src/cmd/link/internal/ld/ldmacho.go @@ -4,6 +4,7 @@ import ( "cmd/internal/bio" "cmd/internal/objabi" "cmd/internal/sys" + "cmd/link/internal/sym" "encoding/binary" "fmt" "io" @@ -92,7 +93,7 @@ type ldMachoSect struct { flags uint32 res1 uint32 res2 uint32 - sym *Symbol + sym *sym.Symbol rel []ldMachoRel } @@ -123,7 +124,7 @@ type ldMachoSym struct { desc uint16 kind int8 value uint64 - sym *Symbol + sym *sym.Symbol } type ldMachoDysymtab struct { @@ -428,15 +429,14 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { var sect *ldMachoSect var rel *ldMachoRel var rpi int - var s *Symbol - var s1 *Symbol - var outer *Symbol + var s *sym.Symbol + var s1 *sym.Symbol + var outer *sym.Symbol var c *ldMachoCmd var symtab *ldMachoSymtab var dsymtab *ldMachoDysymtab - var sym *ldMachoSym - var r []Reloc - var rp *Reloc + var r []sym.Reloc + var rp *sym.Reloc var name string localSymVersion := ctxt.Syms.IncVersion() @@ -597,16 +597,16 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { if sect.segname == "__TEXT" { if sect.name == "__text" { - s.Type = STEXT + s.Type = sym.STEXT } else { - s.Type = SRODATA + s.Type = sym.SRODATA } } else { if sect.name == "__bss" { - s.Type = SNOPTRBSS + s.Type = sym.SNOPTRBSS s.P = s.P[:0] } else { - s.Type = SNOPTRDATA + s.Type = sym.SNOPTRDATA } } @@ -616,35 +616,35 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { // enter sub-symbols into symbol table. // have to guess sizes from next symbol. for i := 0; uint32(i) < symtab.nsym; i++ { - sym = &symtab.sym[i] - if sym.type_&N_STAB != 0 { + machsym := &symtab.sym[i] + if machsym.type_&N_STAB != 0 { continue } // TODO: check sym->type against outer->type. - name = sym.name + name = machsym.name if name[0] == '_' && name[1] != '\x00' { name = name[1:] } v := 0 - if sym.type_&N_EXT == 0 { + if machsym.type_&N_EXT == 0 { v = localSymVersion } s = ctxt.Syms.Lookup(name, v) - if sym.type_&N_EXT == 0 { - s.Attr |= AttrDuplicateOK + if machsym.type_&N_EXT == 0 { + s.Attr |= sym.AttrDuplicateOK } - sym.sym = s - if sym.sectnum == 0 { // undefined + machsym.sym = s + if machsym.sectnum == 0 { // undefined continue } - if uint32(sym.sectnum) > c.seg.nsect { - err = fmt.Errorf("reference to invalid section %d", sym.sectnum) + if uint32(machsym.sectnum) > c.seg.nsect { + err = fmt.Errorf("reference to invalid section %d", machsym.sectnum) goto bad } - sect = &c.seg.sect[sym.sectnum-1] + sect = &c.seg.sect[machsym.sectnum-1] outer = sect.sym if outer == nil { err = fmt.Errorf("reference to invalid section %s/%s", sect.segname, sect.name) @@ -658,22 +658,22 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name) } - s.Type = outer.Type | SSUB + s.Type = outer.Type | sym.SSUB s.Sub = outer.Sub outer.Sub = s s.Outer = outer - s.Value = int64(sym.value - sect.addr) + s.Value = int64(machsym.value - sect.addr) if !s.Attr.CgoExportDynamic() { s.Dynimplib = "" // satisfy dynimport } - if outer.Type == STEXT { + if outer.Type == sym.STEXT { if s.Attr.External() && !s.Attr.DuplicateOK() { Errorf(s, "%s: duplicate symbol definition", pn) } - s.Attr |= AttrExternal + s.Attr |= sym.AttrExternal } - sym.sym = s + machsym.sym = s } // Sort outer lists by address, adding to textp. @@ -697,17 +697,17 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { } } - if s.Type == STEXT { + if s.Type == sym.STEXT { if s.Attr.OnList() { log.Fatalf("symbol %s listed multiple times", s.Name) } - s.Attr |= AttrOnList + s.Attr |= sym.AttrOnList ctxt.Textp = append(ctxt.Textp, s) for s1 = s.Sub; s1 != nil; s1 = s1.Sub { if s1.Attr.OnList() { log.Fatalf("symbol %s listed multiple times", s1.Name) } - s1.Attr |= AttrOnList + s1.Attr |= sym.AttrOnList ctxt.Textp = append(ctxt.Textp, s1) } } @@ -724,7 +724,7 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { if sect.rel == nil { continue } - r = make([]Reloc, sect.nreloc) + r = make([]sym.Reloc, sect.nreloc) rpi = 0 Reloc: for j = 0; uint32(j) < sect.nreloc; j++ { diff --git a/src/cmd/link/internal/ld/ldpe.go b/src/cmd/link/internal/ld/ldpe.go index a74b46655f..ec960fe9d3 100644 --- a/src/cmd/link/internal/ld/ldpe.go +++ b/src/cmd/link/internal/ld/ldpe.go @@ -8,6 +8,7 @@ import ( "cmd/internal/bio" "cmd/internal/objabi" "cmd/internal/sys" + "cmd/link/internal/sym" "debug/pe" "errors" "fmt" @@ -132,7 +133,7 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin localSymVersion := ctxt.Syms.IncVersion() - sectsyms := make(map[*pe.Section]*Symbol) + sectsyms := make(map[*pe.Section]*sym.Symbol) sectdata := make(map[*pe.Section][]byte) // Some input files are archives containing multiple of @@ -167,22 +168,22 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin switch sect.Characteristics & (IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE) { case IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ: //.rdata - s.Type = SRODATA + s.Type = sym.SRODATA case IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE: //.bss - s.Type = SNOPTRBSS + s.Type = sym.SNOPTRBSS case IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE: //.data - s.Type = SNOPTRDATA + s.Type = sym.SNOPTRDATA case IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ: //.text - s.Type = STEXT + s.Type = sym.STEXT default: return fmt.Errorf("unexpected flags %#06x for PE section %s", sect.Characteristics, sect.Name) } - if s.Type != SNOPTRBSS { + if s.Type != sym.SNOPTRBSS { data, err := sect.Data() if err != nil { return err @@ -214,7 +215,7 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin continue } - rs := make([]Reloc, rsect.NumberOfRelocations) + rs := make([]sym.Reloc, rsect.NumberOfRelocations) for j, r := range rsect.Relocs { rp := &rs[j] if int(r.SymbolTableIndex) >= len(f.COFFSymbols) { @@ -314,11 +315,11 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin } if pesym.SectionNumber == 0 { // extern - if s.Type == SDYNIMPORT { + if s.Type == sym.SDYNIMPORT { s.Plt = -2 // flag for dynimport in PE object files. } - if s.Type == SXREF && pesym.Value > 0 { // global data - s.Type = SNOPTRDATA + if s.Type == sym.SXREF && pesym.Value > 0 { // global data + s.Type = sym.SNOPTRDATA s.Size = int64(pesym.Value) } @@ -346,15 +347,15 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin sectsym := sectsyms[sect] s.Sub = sectsym.Sub sectsym.Sub = s - s.Type = sectsym.Type | SSUB + s.Type = sectsym.Type | sym.SSUB s.Value = int64(pesym.Value) s.Size = 4 s.Outer = sectsym - if sectsym.Type == STEXT { + if sectsym.Type == sym.STEXT { if s.Attr.External() && !s.Attr.DuplicateOK() { Errorf(s, "%s: duplicate symbol definition", pn) } - s.Attr |= AttrExternal + s.Attr |= sym.AttrExternal } } @@ -368,17 +369,17 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin if s.Sub != nil { s.Sub = listsort(s.Sub) } - if s.Type == STEXT { + if s.Type == sym.STEXT { if s.Attr.OnList() { log.Fatalf("symbol %s listed multiple times", s.Name) } - s.Attr |= AttrOnList + s.Attr |= sym.AttrOnList ctxt.Textp = append(ctxt.Textp, s) for s = s.Sub; s != nil; s = s.Sub { if s.Attr.OnList() { log.Fatalf("symbol %s listed multiple times", s.Name) } - s.Attr |= AttrOnList + s.Attr |= sym.AttrOnList ctxt.Textp = append(ctxt.Textp, s) } } @@ -391,14 +392,14 @@ func issect(s *pe.COFFSymbol) bool { return s.StorageClass == IMAGE_SYM_CLASS_STATIC && s.Type == 0 && s.Name[0] == '.' } -func readpesym(ctxt *Link, f *pe.File, sym *pe.COFFSymbol, sectsyms map[*pe.Section]*Symbol, localSymVersion int) (*Symbol, error) { - symname, err := sym.FullName(f.StringTable) +func readpesym(ctxt *Link, f *pe.File, pesym *pe.COFFSymbol, sectsyms map[*pe.Section]*sym.Symbol, localSymVersion int) (*sym.Symbol, error) { + symname, err := pesym.FullName(f.StringTable) if err != nil { return nil, err } var name string - if issect(sym) { - name = sectsyms[f.Sections[sym.SectionNumber-1]].Name + if issect(pesym) { + name = sectsyms[f.Sections[pesym.SectionNumber-1]].Name } else { name = symname if strings.HasPrefix(name, "__imp_") { @@ -414,27 +415,27 @@ func readpesym(ctxt *Link, f *pe.File, sym *pe.COFFSymbol, sectsyms map[*pe.Sect name = name[:i] } - var s *Symbol - switch sym.Type { + var s *sym.Symbol + switch pesym.Type { default: - return nil, fmt.Errorf("%s: invalid symbol type %d", symname, sym.Type) + return nil, fmt.Errorf("%s: invalid symbol type %d", symname, pesym.Type) case IMAGE_SYM_DTYPE_FUNCTION, IMAGE_SYM_DTYPE_NULL: - switch sym.StorageClass { + switch pesym.StorageClass { case IMAGE_SYM_CLASS_EXTERNAL: //global s = ctxt.Syms.Lookup(name, 0) case IMAGE_SYM_CLASS_NULL, IMAGE_SYM_CLASS_STATIC, IMAGE_SYM_CLASS_LABEL: s = ctxt.Syms.Lookup(name, localSymVersion) - s.Attr |= AttrDuplicateOK + s.Attr |= sym.AttrDuplicateOK default: - return nil, fmt.Errorf("%s: invalid symbol binding %d", symname, sym.StorageClass) + return nil, fmt.Errorf("%s: invalid symbol binding %d", symname, pesym.StorageClass) } } - if s != nil && s.Type == 0 && (sym.StorageClass != IMAGE_SYM_CLASS_STATIC || sym.Value != 0) { - s.Type = SXREF + if s != nil && s.Type == 0 && (pesym.StorageClass != IMAGE_SYM_CLASS_STATIC || pesym.Value != 0) { + s.Type = sym.SXREF } if strings.HasPrefix(symname, "__imp_") { s.Got = -2 // flag for __imp_ diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 1cedb44a38..22c028a763 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -36,6 +36,7 @@ import ( "cmd/internal/bio" "cmd/internal/objabi" "cmd/internal/sys" + "cmd/link/internal/sym" "crypto/sha1" "debug/elf" "encoding/base64" @@ -97,17 +98,17 @@ type Arch struct { Openbsddynld string Dragonflydynld string Solarisdynld string - Adddynrel func(*Link, *Symbol, *Reloc) bool + Adddynrel func(*Link, *sym.Symbol, *sym.Reloc) bool Archinit func(*Link) - Archreloc func(*Link, *Reloc, *Symbol, *int64) bool - Archrelocvariant func(*Link, *Reloc, *Symbol, int64) int64 - Trampoline func(*Link, *Reloc, *Symbol) + Archreloc func(*Link, *sym.Reloc, *sym.Symbol, *int64) bool + Archrelocvariant func(*Link, *sym.Reloc, *sym.Symbol, int64) int64 + Trampoline func(*Link, *sym.Reloc, *sym.Symbol) Asmb func(*Link) - Elfreloc1 func(*Link, *Reloc, int64) bool + Elfreloc1 func(*Link, *sym.Reloc, int64) bool Elfsetupplt func(*Link) Gentext func(*Link) - Machoreloc1 func(*sys.Arch, *OutBuf, *Symbol, *Reloc, int64) bool - PEreloc1 func(*sys.Arch, *OutBuf, *Symbol, *Reloc, int64) bool + Machoreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool + PEreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool // TLSIEtoLE converts a TLS Initial Executable relocation to // a TLS Local Executable relocation. @@ -115,7 +116,7 @@ type Arch struct { // This is possible when a TLS IE relocation refers to a local // symbol in an executable, which is typical when internally // linking PIE binaries. - TLSIEtoLE func(s *Symbol, off, size int) + TLSIEtoLE func(s *sym.Symbol, off, size int) } var ( @@ -126,37 +127,10 @@ var ( Symsize int32 ) -// Terrible but standard terminology. -// A segment describes a block of file to load into memory. -// A section further describes the pieces of that block for -// use in debuggers and such. - const ( MINFUNC = 16 // minimum size for a function ) -type Segment struct { - Rwx uint8 // permission as usual unix bits (5 = r-x etc) - Vaddr uint64 // virtual address - Length uint64 // length in memory - Fileoff uint64 // file offset - Filelen uint64 // length on disk - Sections []*Section -} - -type Section struct { - Rwx uint8 - Extnum int16 - Align int32 - Name string - Vaddr uint64 - Length uint64 - Seg *Segment - Elfsect *ElfShdr - Reloff uint64 - Rellen uint64 -} - // DynlinkingGo returns whether we are producing Go code that can live // in separate shared libraries linked together at runtime. func (ctxt *Link) DynlinkingGo() bool { @@ -183,7 +157,7 @@ func UseRelro() bool { } var ( - dynexp []*Symbol + dynexp []*sym.Symbol dynlib []string ldflag []string havedynamic int @@ -201,11 +175,11 @@ var ( ) var ( - Segtext Segment - Segrodata Segment - Segrelrodata Segment - Segdata Segment - Segdwarf Segment + Segtext sym.Segment + Segrodata sym.Segment + Segrelrodata sym.Segment + Segdata sym.Segment + Segdwarf sym.Segment ) /* whence for ldpkg */ @@ -359,11 +333,11 @@ func (ctxt *Link) loadlib() { switch Buildmode { case BuildmodeCShared, BuildmodePlugin: s := ctxt.Syms.Lookup("runtime.islibrary", 0) - s.Attr |= AttrDuplicateOK + s.Attr |= sym.AttrDuplicateOK s.AddUint8(1) case BuildmodeCArchive: s := ctxt.Syms.Lookup("runtime.isarchive", 0) - s.Attr |= AttrDuplicateOK + s.Attr |= sym.AttrDuplicateOK s.AddUint8(1) } @@ -414,7 +388,7 @@ func (ctxt *Link) loadlib() { if Linkmode == LinkExternal && ctxt.Arch.Family == sys.PPC64 { toc := ctxt.Syms.Lookup(".TOC.", 0) - toc.Type = SDYNIMPORT + toc.Type = sym.SDYNIMPORT } if Linkmode == LinkExternal && !iscgo && ctxt.LibraryByPkg["runtime/cgo"] == nil { @@ -438,13 +412,13 @@ func (ctxt *Link) loadlib() { // Drop all the cgo_import_static declarations. // Turns out we won't be needing them. for _, s := range ctxt.Syms.Allsym { - if s.Type == SHOSTOBJ { + if s.Type == sym.SHOSTOBJ { // If a symbol was marked both // cgo_import_static and cgo_import_dynamic, // then we want to make it cgo_import_dynamic // now. if s.Extname != "" && s.Dynimplib != "" && !s.Attr.CgoExport() { - s.Type = SDYNIMPORT + s.Type = sym.SDYNIMPORT } else { s.Type = 0 } @@ -457,22 +431,22 @@ func (ctxt *Link) loadlib() { // runtime.tlsg is used for external linking on platforms that do not define // a variable to hold g in assembly (currently only intel). if tlsg.Type == 0 { - tlsg.Type = STLSBSS + tlsg.Type = sym.STLSBSS tlsg.Size = int64(ctxt.Arch.PtrSize) - } else if tlsg.Type != SDYNIMPORT { + } else if tlsg.Type != sym.SDYNIMPORT { Errorf(nil, "runtime declared tlsg variable %v", tlsg.Type) } - tlsg.Attr |= AttrReachable + tlsg.Attr |= sym.AttrReachable ctxt.Tlsg = tlsg - var moduledata *Symbol + var moduledata *sym.Symbol if Buildmode == BuildmodePlugin { moduledata = ctxt.Syms.Lookup("local.pluginmoduledata", 0) - moduledata.Attr |= AttrLocal + moduledata.Attr |= sym.AttrLocal } else { moduledata = ctxt.Syms.Lookup("runtime.firstmoduledata", 0) } - if moduledata.Type != 0 && moduledata.Type != SDYNIMPORT { + if moduledata.Type != 0 && moduledata.Type != sym.SDYNIMPORT { // If the module (toolchain-speak for "executable or shared // library") we are linking contains the runtime package, it // will define the runtime.firstmoduledata symbol and we @@ -484,14 +458,14 @@ func (ctxt *Link) loadlib() { // recording the value of GOARM. if ctxt.Arch.Family == sys.ARM { s := ctxt.Syms.Lookup("runtime.goarm", 0) - s.Type = SRODATA + s.Type = sym.SRODATA s.Size = 0 s.AddUint8(uint8(objabi.GOARM)) } if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) { s := ctxt.Syms.Lookup("runtime.framepointer_enabled", 0) - s.Type = SRODATA + s.Type = sym.SRODATA s.Size = 0 s.AddUint8(1) } @@ -499,19 +473,19 @@ func (ctxt *Link) loadlib() { // If OTOH the module does not contain the runtime package, // create a local symbol for the moduledata. moduledata = ctxt.Syms.Lookup("local.moduledata", 0) - moduledata.Attr |= AttrLocal + moduledata.Attr |= sym.AttrLocal } // In all cases way we mark the moduledata as noptrdata to hide it from // the GC. - moduledata.Type = SNOPTRDATA - moduledata.Attr |= AttrReachable + moduledata.Type = sym.SNOPTRDATA + moduledata.Attr |= sym.AttrReachable ctxt.Moduledata = moduledata // Now that we know the link mode, trim the dynexp list. - x := AttrCgoExportDynamic + x := sym.AttrCgoExportDynamic if Linkmode == LinkExternal { - x = AttrCgoExportStatic + x = sym.AttrCgoExportStatic } w := 0 for i := 0; i < len(dynexp); i++ { @@ -531,7 +505,7 @@ func (ctxt *Link) loadlib() { any := false for _, s := range ctxt.Syms.Allsym { for _, r := range s.R { - if r.Sym != nil && r.Sym.Type&SMASK == SXREF && r.Sym.Name != ".got" { + if r.Sym != nil && r.Sym.Type&sym.SMASK == sym.SXREF && r.Sym.Name != ".got" { any = true break } @@ -618,8 +592,8 @@ func (ctxt *Link) loadlib() { if ctxt.Arch == sys.Arch386 { if (Buildmode == BuildmodeCArchive && Iself) || Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE || ctxt.DynlinkingGo() { got := ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0) - got.Type = SDYNIMPORT - got.Attr |= AttrReachable + got.Type = sym.SDYNIMPORT + got.Attr |= sym.AttrReachable } } @@ -638,7 +612,7 @@ func (ctxt *Link) loadlib() { for _, s := range lib.dupTextSyms { if !s.Attr.OnList() { ctxt.Textp = append(ctxt.Textp, s) - s.Attr |= AttrOnList + s.Attr |= sym.AttrOnList // dupok symbols may be defined in multiple packages. its // associated package is chosen sort of arbitrarily (the // first containing package that the linker loads). canonicalize @@ -654,9 +628,9 @@ func (ctxt *Link) loadlib() { // We might have overwritten some functions above (this tends to happen for the // autogenerated type equality/hashing functions) and we don't want to generated // pcln table entries for these any more so remove them from Textp. - textp := make([]*Symbol, 0, len(ctxt.Textp)) + textp := make([]*sym.Symbol, 0, len(ctxt.Textp)) for _, s := range ctxt.Textp { - if s.Type != SDYNIMPORT { + if s.Type != sym.SDYNIMPORT { textp = append(textp, s) } } @@ -676,12 +650,12 @@ func (ctxt *Link) loadlib() { // packages. All Go binaries contain these symbols, but only only // those programs loaded dynamically in multiple parts need these // symbols to have entries in the symbol table. -func typeSymbolMangling(syms *Symbols) bool { +func typeSymbolMangling(syms *sym.Symbols) bool { return Buildmode == BuildmodeShared || *FlagLinkshared || Buildmode == BuildmodePlugin || syms.ROLookup("plugin.Open", 0) != nil } // typeSymbolMangle mangles the given symbol name into something shorter. -func typeSymbolMangle(syms *Symbols, name string) string { +func typeSymbolMangle(syms *sym.Symbols, name string) string { if !typeSymbolMangling(syms) { return name } @@ -1181,7 +1155,7 @@ func (l *Link) hostlink() { // Do not let the host linker generate COPY relocations. These // can move symbols out of sections that rely on stable offsets - // from the beginning of the section (like STYPE). + // from the beginning of the section (like sym.STYPE). argv = append(argv, "-Wl,-znocopyreloc") if l.Arch.InFamily(sys.ARM, sys.ARM64) { @@ -1626,7 +1600,7 @@ func ldshlibsyms(ctxt *Link, shlib string) { Errorf(nil, "cannot read symbols from shared library: %s", libpath) return } - gcdataLocations := make(map[uint64]*Symbol) + gcdataLocations := make(map[uint64]*sym.Symbol) for _, elfsym := range syms { if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION { continue @@ -1636,10 +1610,10 @@ func ldshlibsyms(ctxt *Link, shlib string) { // libraries, any non-dynimport symbols we find that duplicate symbols // already loaded should be ignored (the symbols from the .a files // "win"). - if lsym.Type != 0 && lsym.Type != SDYNIMPORT { + if lsym.Type != 0 && lsym.Type != sym.SDYNIMPORT { continue } - lsym.Type = SDYNIMPORT + lsym.Type = sym.SDYNIMPORT lsym.ElfType = elf.ST_TYPE(elfsym.Info) lsym.Size = int64(elfsym.Size) if elfsym.Section != elf.SHN_UNDEF { @@ -1653,7 +1627,7 @@ func ldshlibsyms(ctxt *Link, shlib string) { } } } - gcdataAddresses := make(map[*Symbol]uint64) + gcdataAddresses := make(map[*sym.Symbol]uint64) if ctxt.Arch.Family == sys.ARM64 { for _, sect := range f.Sections { if sect.Type == elf.SHT_RELA { @@ -1682,8 +1656,8 @@ func ldshlibsyms(ctxt *Link, shlib string) { ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdataAddresses: gcdataAddresses}) } -func addsection(arch *sys.Arch, seg *Segment, name string, rwx int) *Section { - sect := new(Section) +func addsection(arch *sys.Arch, seg *sym.Segment, name string, rwx int) *sym.Section { + sect := new(sym.Section) sect.Rwx = uint8(rwx) sect.Name = name sect.Seg = seg @@ -1713,12 +1687,12 @@ func Be32(b []byte) uint32 { } type chain struct { - sym *Symbol + sym *sym.Symbol up *chain limit int // limit on entry to sym } -var morestack *Symbol +var morestack *sym.Symbol // TODO: Record enough information in new object files to // allow stack checks here. @@ -1785,7 +1759,7 @@ func stkcheck(ctxt *Link, up *chain, depth int) int { if s.Attr.StackCheck() { return 0 } - s.Attr |= AttrStackCheck + s.Attr |= sym.AttrStackCheck } if depth > 100 { @@ -1799,7 +1773,7 @@ func stkcheck(ctxt *Link, up *chain, depth int) int { // should never be called directly. // onlyctxt.Diagnose the direct caller. // TODO(mwhudson): actually think about this. - if depth == 1 && s.Type != SXREF && !ctxt.DynlinkingGo() && + if depth == 1 && s.Type != sym.SXREF && !ctxt.DynlinkingGo() && Buildmode != BuildmodeCArchive && Buildmode != BuildmodePIE && Buildmode != BuildmodeCShared && Buildmode != BuildmodePlugin { Errorf(s, "call to external function") @@ -1845,7 +1819,7 @@ func stkcheck(ctxt *Link, up *chain, depth int) int { endr := len(s.R) var ch1 chain var pcsp Pciter - var r *Reloc + var r *sym.Reloc for pciterinit(ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) { // pcsp.value is in effect for [pcsp.pc, pcsp.nextpc). @@ -1947,11 +1921,11 @@ const ( AutoSym = 'a' ) -func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, *Symbol)) { +func genasmsym(ctxt *Link, put func(*Link, *sym.Symbol, string, SymbolType, int64, *sym.Symbol)) { // These symbols won't show up in the first loop below because we - // skip STEXT symbols. Normal STEXT symbols are emitted by walking textp. + // skip sym.STEXT symbols. Normal sym.STEXT symbols are emitted by walking textp. s := ctxt.Syms.Lookup("runtime.text", 0) - if s.Type == STEXT { + if s.Type == sym.STEXT { // We've already included this symbol in ctxt.Textp // if ctxt.DynlinkingGo() && Headtype == objabi.Hdarwin. // See data.go:/textaddress @@ -1975,14 +1949,14 @@ func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, * if s == nil { break } - if s.Type == STEXT { + if s.Type == sym.STEXT { put(ctxt, s, s.Name, TextSym, s.Value, nil) } n++ } s = ctxt.Syms.Lookup("runtime.etext", 0) - if s.Type == STEXT { + if s.Type == sym.STEXT { // We've already included this symbol in ctxt.Textp // if ctxt.DynlinkingGo() && Headtype == objabi.Hdarwin. // See data.go:/textaddress @@ -1998,36 +1972,36 @@ func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, * if (s.Name == "" || s.Name[0] == '.') && s.Version == 0 && s.Name != ".rathole" && s.Name != ".TOC." { continue } - switch s.Type & SMASK { - case SCONST, - SRODATA, - SSYMTAB, - SPCLNTAB, - SINITARR, - SDATA, - SNOPTRDATA, - SELFROSECT, - SMACHOGOT, - STYPE, - SSTRING, - SGOSTRING, - SGOFUNC, - SGCBITS, - STYPERELRO, - SSTRINGRELRO, - SGOSTRINGRELRO, - SGOFUNCRELRO, - SGCBITSRELRO, - SRODATARELRO, - STYPELINK, - SITABLINK, - SWINDOWS: + switch s.Type & sym.SMASK { + case sym.SCONST, + sym.SRODATA, + sym.SSYMTAB, + sym.SPCLNTAB, + sym.SINITARR, + sym.SDATA, + sym.SNOPTRDATA, + sym.SELFROSECT, + sym.SMACHOGOT, + sym.STYPE, + sym.SSTRING, + sym.SGOSTRING, + sym.SGOFUNC, + sym.SGCBITS, + sym.STYPERELRO, + sym.SSTRINGRELRO, + sym.SGOSTRINGRELRO, + sym.SGOFUNCRELRO, + sym.SGCBITSRELRO, + sym.SRODATARELRO, + sym.STYPELINK, + sym.SITABLINK, + sym.SWINDOWS: if !s.Attr.Reachable() { continue } put(ctxt, s, s.Name, DataSym, Symaddr(s), s.Gotype) - case SBSS, SNOPTRBSS: + case sym.SBSS, sym.SNOPTRBSS: if !s.Attr.Reachable() { continue } @@ -2036,18 +2010,18 @@ func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, * } put(ctxt, s, s.Name, BSSSym, Symaddr(s), s.Gotype) - case SHOSTOBJ: + case sym.SHOSTOBJ: if Headtype == objabi.Hwindows || Iself { put(ctxt, s, s.Name, UndefinedSym, s.Value, nil) } - case SDYNIMPORT: + case sym.SDYNIMPORT: if !s.Attr.Reachable() { continue } put(ctxt, s, s.Extname, UndefinedSym, 0, nil) - case STLSBSS: + case sym.STLSBSS: if Linkmode == LinkExternal { put(ctxt, s, s.Name, TLSSym, Symaddr(s), s.Gotype) } @@ -2103,23 +2077,23 @@ func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, * } } -func Symaddr(s *Symbol) int64 { +func Symaddr(s *sym.Symbol) int64 { if !s.Attr.Reachable() { Errorf(s, "unreachable symbol in symaddr") } return s.Value } -func (ctxt *Link) xdefine(p string, t SymKind, v int64) { +func (ctxt *Link) xdefine(p string, t sym.SymKind, v int64) { s := ctxt.Syms.Lookup(p, 0) s.Type = t s.Value = v - s.Attr |= AttrReachable - s.Attr |= AttrSpecial - s.Attr |= AttrLocal + s.Attr |= sym.AttrReachable + s.Attr |= sym.AttrSpecial + s.Attr |= sym.AttrLocal } -func datoff(s *Symbol, addr int64) int64 { +func datoff(s *sym.Symbol, addr int64) int64 { if uint64(addr) >= Segdata.Vaddr { return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff) } @@ -2139,21 +2113,21 @@ func Entryvalue(ctxt *Link) int64 { if s.Type == 0 { return *FlagTextAddr } - if s.Type != STEXT { + if s.Type != sym.STEXT { Errorf(s, "entry not text") } return s.Value } -func undefsym(ctxt *Link, s *Symbol) { - var r *Reloc +func undefsym(ctxt *Link, s *sym.Symbol) { + var r *sym.Reloc for i := 0; i < len(s.R); i++ { r = &s.R[i] if r.Sym == nil { // happens for some external ARM relocs continue } - if r.Sym.Type == Sxxx || r.Sym.Type == SXREF { + if r.Sym.Type == sym.Sxxx || r.Sym.Type == sym.SXREF { Errorf(s, "undefined: %q", r.Sym.Name) } if !r.Sym.Attr.Reachable() && r.Type != objabi.R_WEAKADDROFF { @@ -2180,14 +2154,14 @@ func (ctxt *Link) callgraph() { } var i int - var r *Reloc + var r *sym.Reloc for _, s := range ctxt.Textp { for i = 0; i < len(s.R); i++ { r = &s.R[i] if r.Sym == nil { continue } - if (r.Type == objabi.R_CALL || r.Type == objabi.R_CALLARM || r.Type == objabi.R_CALLPOWER || r.Type == objabi.R_CALLMIPS) && r.Sym.Type == STEXT { + if (r.Type == objabi.R_CALL || r.Type == objabi.R_CALLARM || r.Type == objabi.R_CALLPOWER || r.Type == objabi.R_CALLMIPS) && r.Sym.Type == sym.STEXT { ctxt.Logf("%s calls %s\n", s.Name, r.Sym.Name) } } diff --git a/src/cmd/link/internal/ld/link.go b/src/cmd/link/internal/ld/link.go index 76ba09965b..25db52f3f4 100644 --- a/src/cmd/link/internal/ld/link.go +++ b/src/cmd/link/internal/ld/link.go @@ -34,124 +34,17 @@ import ( "bufio" "cmd/internal/objabi" "cmd/internal/sys" + "cmd/link/internal/sym" "debug/elf" "fmt" ) -// Attribute is a set of common symbol attributes. -type Attribute int16 - -const ( - // AttrDuplicateOK marks a symbol that can be present in multiple object - // files. - AttrDuplicateOK Attribute = 1 << iota - // AttrExternal marks function symbols loaded from host object files. - AttrExternal - // AttrNoSplit marks functions that cannot split the stack; the linker - // cares because it checks that there are no call chains of nosplit - // functions that require more than StackLimit bytes (see - // lib.go:dostkcheck) - AttrNoSplit - // AttrReachable marks symbols that are transitively referenced from the - // entry points. Unreachable symbols are not written to the output. - AttrReachable - // AttrCgoExportDynamic and AttrCgoExportStatic mark symbols referenced - // by directives written by cgo (in response to //export directives in - // the source). - AttrCgoExportDynamic - AttrCgoExportStatic - // AttrSpecial marks symbols that do not have their address (i.e. Value) - // computed by the usual mechanism of data.go:dodata() & - // data.go:address(). - AttrSpecial - // AttrStackCheck is used by dostkcheck to only check each NoSplit - // function's stack usage once. - AttrStackCheck - // AttrNotInSymbolTable marks symbols that are not written to the symbol table. - AttrNotInSymbolTable - // AttrOnList marks symbols that are on some list (such as the list of - // all text symbols, or one of the lists of data symbols) and is - // consulted to avoid bugs where a symbol is put on a list twice. - AttrOnList - // AttrLocal marks symbols that are only visible within the module - // (executable or shared library) being linked. Only relevant when - // dynamically linking Go code. - AttrLocal - // AttrReflectMethod marks certain methods from the reflect package that - // can be used to call arbitrary methods. If no symbol with this bit set - // is marked as reachable, more dead code elimination can be done. - AttrReflectMethod - // AttrMakeTypelink Amarks types that should be added to the typelink - // table. See typelinks.go:typelinks(). - AttrMakeTypelink - // AttrShared marks symbols compiled with the -shared option. - AttrShared - // 14 attributes defined so far. -) - -func (a Attribute) DuplicateOK() bool { return a&AttrDuplicateOK != 0 } -func (a Attribute) External() bool { return a&AttrExternal != 0 } -func (a Attribute) NoSplit() bool { return a&AttrNoSplit != 0 } -func (a Attribute) Reachable() bool { return a&AttrReachable != 0 } -func (a Attribute) CgoExportDynamic() bool { return a&AttrCgoExportDynamic != 0 } -func (a Attribute) CgoExportStatic() bool { return a&AttrCgoExportStatic != 0 } -func (a Attribute) Special() bool { return a&AttrSpecial != 0 } -func (a Attribute) StackCheck() bool { return a&AttrStackCheck != 0 } -func (a Attribute) NotInSymbolTable() bool { return a&AttrNotInSymbolTable != 0 } -func (a Attribute) OnList() bool { return a&AttrOnList != 0 } -func (a Attribute) Local() bool { return a&AttrLocal != 0 } -func (a Attribute) ReflectMethod() bool { return a&AttrReflectMethod != 0 } -func (a Attribute) MakeTypelink() bool { return a&AttrMakeTypelink != 0 } -func (a Attribute) Shared() bool { return a&AttrShared != 0 } - -func (a Attribute) CgoExport() bool { - return a.CgoExportDynamic() || a.CgoExportStatic() -} - -func (a *Attribute) Set(flag Attribute, value bool) { - if value { - *a |= flag - } else { - *a &^= flag - } -} - -// Reloc is a relocation. -// -// The typical Reloc rewrites part of a symbol at offset Off to address Sym. -// A Reloc is stored in a slice on the Symbol it rewrites. -// -// Relocations are generated by the compiler as the type -// cmd/internal/obj.Reloc, which is encoded into the object file wire -// format and decoded by the linker into this type. A separate type is -// used to hold linker-specific state about the relocation. -// -// Some relocations are created by cmd/link. -type Reloc struct { - Off int32 // offset to rewrite - Siz uint8 // number of bytes to rewrite, 1, 2, or 4 - Done bool // set to true when relocation is complete - Variant RelocVariant // variation on Type - Type objabi.RelocType // the relocation type - Add int64 // addend - Xadd int64 // addend passed to external linker - Sym *Symbol // symbol the relocation addresses - Xsym *Symbol // symbol passed to external linker -} - -type Auto struct { - Asym *Symbol - Gotype *Symbol - Aoffset int32 - Name int16 -} - type Shlib struct { Path string Hash []byte Deps []string File *elf.File - gcdataAddresses map[*Symbol]uint64 + gcdataAddresses map[*sym.Symbol]uint64 } // Link holds the context for writing object code from a compiler @@ -159,7 +52,7 @@ type Shlib struct { type Link struct { Out *OutBuf - Syms *Symbols + Syms *sym.Symbols Arch *sys.Arch Debugvlog int @@ -167,20 +60,20 @@ type Link struct { Loaded bool // set after all inputs have been loaded as symbols - Tlsg *Symbol + Tlsg *sym.Symbol Libdir []string Library []*Library LibraryByPkg map[string]*Library Shlibs []Shlib Tlsoffset int - Textp []*Symbol - Filesyms []*Symbol - Moduledata *Symbol + Textp []*sym.Symbol + Filesyms []*sym.Symbol + Moduledata *sym.Symbol PackageFile map[string]string PackageShlib map[string]string - tramps []*Symbol // trampolines + tramps []*sym.Symbol // trampolines } // The smallest possible offset from the hardware stack pointer to a local @@ -214,8 +107,8 @@ type Library struct { hash string importStrings []string imports []*Library - textp []*Symbol // text symbols defined in this library - dupTextSyms []*Symbol // dupok text symbols defined in this library + textp []*sym.Symbol // text symbols defined in this library + dupTextSyms []*sym.Symbol // dupok text symbols defined in this library } func (l Library) String() string { @@ -233,35 +126,8 @@ func (l *Library) addImports(ctxt *Link, pn string) { l.importStrings = nil } -type FuncInfo struct { - Args int32 - Locals int32 - Autom []Auto - Pcsp Pcdata - Pcfile Pcdata - Pcline Pcdata - Pcinline Pcdata - Pcdata []Pcdata - Funcdata []*Symbol - Funcdataoff []int64 - File []*Symbol - InlTree []InlinedCall -} - -// InlinedCall is a node in a local inlining tree (FuncInfo.InlTree). -type InlinedCall struct { - Parent int32 // index of parent in InlTree - File *Symbol // file of the inlined call - Line int32 // line number of the inlined call - Func *Symbol // function that was inlined -} - -type Pcdata struct { - P []byte -} - type Pciter struct { - d Pcdata + d sym.Pcdata p []byte pc uint32 nextpc uint32 @@ -270,66 +136,3 @@ type Pciter struct { start int done int } - -// RelocVariant is a linker-internal variation on a relocation. -type RelocVariant uint8 - -const ( - RV_NONE RelocVariant = iota - RV_POWER_LO - RV_POWER_HI - RV_POWER_HA - RV_POWER_DS - - // RV_390_DBL is a s390x-specific relocation variant that indicates that - // the value to be placed into the relocatable field should first be - // divided by 2. - RV_390_DBL - - RV_CHECK_OVERFLOW RelocVariant = 1 << 7 - RV_TYPE_MASK RelocVariant = RV_CHECK_OVERFLOW - 1 -) - -func RelocName(arch *sys.Arch, r objabi.RelocType) string { - // We didn't have some relocation types at Go1.4. - // Uncomment code when we include those in bootstrap code. - - switch { - case r >= 512: // Mach-O - // nr := (r - 512)>>1 - // switch ctxt.Arch.Family { - // case sys.AMD64: - // return macho.RelocTypeX86_64(nr).String() - // case sys.ARM: - // return macho.RelocTypeARM(nr).String() - // case sys.ARM64: - // return macho.RelocTypeARM64(nr).String() - // case sys.I386: - // return macho.RelocTypeGeneric(nr).String() - // default: - // panic("unreachable") - // } - case r >= 256: // ELF - nr := r - 256 - switch arch.Family { - case sys.AMD64: - return elf.R_X86_64(nr).String() - case sys.ARM: - return elf.R_ARM(nr).String() - case sys.ARM64: - return elf.R_AARCH64(nr).String() - case sys.I386: - return elf.R_386(nr).String() - case sys.MIPS, sys.MIPS64: - // return elf.R_MIPS(nr).String() - case sys.PPC64: - // return elf.R_PPC64(nr).String() - case sys.S390X: - // return elf.R_390(nr).String() - default: - panic("unreachable") - } - } - - return r.String() -} diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go index 29f3a1d1d4..1ce4dc876d 100644 --- a/src/cmd/link/internal/ld/macho.go +++ b/src/cmd/link/internal/ld/macho.go @@ -7,6 +7,7 @@ package ld import ( "cmd/internal/objabi" "cmd/internal/sys" + "cmd/link/internal/sym" "sort" "strings" ) @@ -169,7 +170,7 @@ const ( var nkind [NumSymKind]int -var sortsym []*Symbol +var sortsym []*sym.Symbol var nsortsym int @@ -346,32 +347,32 @@ func (ctxt *Link) domacho() { // empirically, string table must begin with " \x00". s := ctxt.Syms.Lookup(".machosymstr", 0) - s.Type = SMACHOSYMSTR - s.Attr |= AttrReachable + s.Type = sym.SMACHOSYMSTR + s.Attr |= sym.AttrReachable s.AddUint8(' ') s.AddUint8('\x00') s = ctxt.Syms.Lookup(".machosymtab", 0) - s.Type = SMACHOSYMTAB - s.Attr |= AttrReachable + s.Type = sym.SMACHOSYMTAB + s.Attr |= sym.AttrReachable if Linkmode != LinkExternal { s := ctxt.Syms.Lookup(".plt", 0) // will be __symbol_stub - s.Type = SMACHOPLT - s.Attr |= AttrReachable + s.Type = sym.SMACHOPLT + s.Attr |= sym.AttrReachable s = ctxt.Syms.Lookup(".got", 0) // will be __nl_symbol_ptr - s.Type = SMACHOGOT - s.Attr |= AttrReachable + s.Type = sym.SMACHOGOT + s.Attr |= sym.AttrReachable s.Align = 4 s = ctxt.Syms.Lookup(".linkedit.plt", 0) // indirect table for .plt - s.Type = SMACHOINDIRECTPLT - s.Attr |= AttrReachable + s.Type = sym.SMACHOINDIRECTPLT + s.Attr |= sym.AttrReachable s = ctxt.Syms.Lookup(".linkedit.got", 0) // indirect table for .got - s.Type = SMACHOINDIRECTGOT - s.Attr |= AttrReachable + s.Type = sym.SMACHOINDIRECTGOT + s.Attr |= sym.AttrReachable } } @@ -396,7 +397,7 @@ func machoadddynlib(lib string) { dylib = append(dylib, lib) } -func machoshbits(ctxt *Link, mseg *MachoSeg, sect *Section, segname string) { +func machoshbits(ctxt *Link, mseg *MachoSeg, sect *sym.Section, segname string) { buf := "__" + strings.Replace(sect.Name[1:], ".", "_", -1) var msect *MachoSect @@ -647,8 +648,8 @@ func Asmbmacho(ctxt *Link) { } } -func symkind(s *Symbol) int { - if s.Type == SDYNIMPORT { +func symkind(s *sym.Symbol) int { + if s.Type == sym.SDYNIMPORT { return SymKindUndef } if s.Attr.CgoExport() { @@ -657,7 +658,7 @@ func symkind(s *Symbol) int { return SymKindLocal } -func addsym(ctxt *Link, s *Symbol, name string, type_ SymbolType, addr int64, gotype *Symbol) { +func addsym(ctxt *Link, s *sym.Symbol, name string, type_ SymbolType, addr int64, gotype *sym.Symbol) { if s == nil { return } @@ -678,7 +679,7 @@ func addsym(ctxt *Link, s *Symbol, name string, type_ SymbolType, addr int64, go nsortsym++ } -type machoscmp []*Symbol +type machoscmp []*sym.Symbol func (x machoscmp) Len() int { return len(x) @@ -704,7 +705,7 @@ func (x machoscmp) Less(i, j int) bool { func machogenasmsym(ctxt *Link) { genasmsym(ctxt, addsym) for _, s := range ctxt.Syms.Allsym { - if s.Type == SDYNIMPORT || s.Type == SHOSTOBJ { + if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ { if s.Attr.Reachable() { addsym(ctxt, s, "", DataSym, 0, nil) } @@ -717,10 +718,10 @@ func machosymorder(ctxt *Link) { // So we sort them here and pre-allocate dynid for them // See https://golang.org/issue/4029 for i := 0; i < len(dynexp); i++ { - dynexp[i].Attr |= AttrReachable + dynexp[i].Attr |= sym.AttrReachable } machogenasmsym(ctxt) - sortsym = make([]*Symbol, nsortsym) + sortsym = make([]*sym.Symbol, nsortsym) nsortsym = 0 machogenasmsym(ctxt) sort.Sort(machoscmp(sortsym[:nsortsym])) @@ -733,7 +734,7 @@ func machosymorder(ctxt *Link) { // // When dynamically linking, all non-local variables and plugin-exported // symbols need to be exported. -func machoShouldExport(ctxt *Link, s *Symbol) bool { +func machoShouldExport(ctxt *Link, s *sym.Symbol) bool { if !ctxt.DynlinkingGo() || s.Attr.Local() { return false } @@ -752,7 +753,7 @@ func machoShouldExport(ctxt *Link, s *Symbol) bool { if strings.HasPrefix(s.Name, "go.link.pkghash") { return true } - return s.Type >= SELFSECT // only writable sections + return s.Type >= sym.SELFSECT // only writable sections } func machosymtab(ctxt *Link) { @@ -780,11 +781,11 @@ func machosymtab(ctxt *Link) { // replace "·" as ".", because DTrace cannot handle it. Addstring(symstr, strings.Replace(s.Extname, "·", ".", -1)) - if s.Type == SDYNIMPORT || s.Type == SHOSTOBJ { + if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ { symtab.AddUint8(0x01) // type N_EXT, external symbol symtab.AddUint8(0) // no section symtab.AddUint16(ctxt.Arch, 0) // desc - symtab.addUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize) // no value + symtab.AddUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize) // no value } else { if s.Attr.CgoExport() || export { symtab.AddUint8(0x0f) @@ -802,7 +803,7 @@ func machosymtab(ctxt *Link) { symtab.AddUint8(uint8(o.Sect.Extnum)) } symtab.AddUint16(ctxt.Arch, 0) // desc - symtab.addUintXX(ctxt.Arch, uint64(Symaddr(s)), ctxt.Arch.PtrSize) + symtab.AddUintXX(ctxt.Arch, uint64(Symaddr(s)), ctxt.Arch.PtrSize) } } } @@ -889,7 +890,7 @@ func Domacholink(ctxt *Link) int64 { return Rnd(int64(size), int64(*FlagRound)) } -func machorelocsect(ctxt *Link, sect *Section, syms []*Symbol) { +func machorelocsect(ctxt *Link, sect *sym.Section, syms []*sym.Symbol) { // If main section has no bits, nothing to relocate. if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen { return @@ -907,27 +908,27 @@ func machorelocsect(ctxt *Link, sect *Section, syms []*Symbol) { } eaddr := int32(sect.Vaddr + sect.Length) - for _, sym := range syms { - if !sym.Attr.Reachable() { + for _, s := range syms { + if !s.Attr.Reachable() { continue } - if sym.Value >= int64(eaddr) { + if s.Value >= int64(eaddr) { break } - for ri := 0; ri < len(sym.R); ri++ { - r := &sym.R[ri] + for ri := 0; ri < len(s.R); ri++ { + r := &s.R[ri] if r.Done { continue } if r.Xsym == nil { - Errorf(sym, "missing xsym in relocation") + Errorf(s, "missing xsym in relocation") continue } if !r.Xsym.Attr.Reachable() { - Errorf(sym, "unreachable reloc %d (%s) target %v", r.Type, RelocName(ctxt.Arch, r.Type), r.Xsym.Name) + Errorf(s, "unreachable reloc %d (%s) target %v", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Xsym.Name) } - if !Thearch.Machoreloc1(ctxt.Arch, ctxt.Out, sym, r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) { - Errorf(sym, "unsupported obj reloc %d (%s)/%d to %s", r.Type, RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name) + if !Thearch.Machoreloc1(ctxt.Arch, ctxt.Out, s, r, int64(uint64(s.Value+int64(r.Off))-sect.Vaddr)) { + Errorf(s, "unsupported obj reloc %d (%s)/%d to %s", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name) } } } diff --git a/src/cmd/link/internal/ld/objfile.go b/src/cmd/link/internal/ld/objfile.go index c3bf281a6c..221183891f 100644 --- a/src/cmd/link/internal/ld/objfile.go +++ b/src/cmd/link/internal/ld/objfile.go @@ -13,6 +13,7 @@ import ( "cmd/internal/dwarf" "cmd/internal/objabi" "cmd/internal/sys" + "cmd/link/internal/sym" "io" "log" "strconv" @@ -30,27 +31,27 @@ var emptyPkg = []byte(`"".`) type objReader struct { rd *bufio.Reader arch *sys.Arch - syms *Symbols + syms *sym.Symbols lib *Library pn string - dupSym *Symbol + dupSym *sym.Symbol localSymVersion int // rdBuf is used by readString and readSymName as scratch for reading strings. rdBuf []byte // List of symbol references for the file being read. - refs []*Symbol + refs []*sym.Symbol data []byte - reloc []Reloc - pcdata []Pcdata - autom []Auto - funcdata []*Symbol + reloc []sym.Reloc + pcdata []sym.Pcdata + autom []sym.Auto + funcdata []*sym.Symbol funcdataoff []int64 - file []*Symbol + file []*sym.Symbol } -func LoadObjFile(arch *sys.Arch, syms *Symbols, f *bio.Reader, lib *Library, length int64, pn string) { +func LoadObjFile(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, lib *Library, length int64, pn string) { start := f.Offset() r := &objReader{ rd: f.Reader, @@ -58,7 +59,7 @@ func LoadObjFile(arch *sys.Arch, syms *Symbols, f *bio.Reader, lib *Library, len arch: arch, syms: syms, pn: pn, - dupSym: &Symbol{Name: ".dup"}, + dupSym: &sym.Symbol{Name: ".dup"}, localSymVersion: syms.IncVersion(), } r.loadObjFile() @@ -90,8 +91,8 @@ func (r *objReader) loadObjFile() { r.lib.importStrings = append(r.lib.importStrings, lib) } - // Symbol references - r.refs = []*Symbol{nil} // zeroth ref is nil + // sym.Symbol references + r.refs = []*sym.Symbol{nil} // zeroth ref is nil for { c, err := r.rd.Peek(1) if err != nil { @@ -134,16 +135,16 @@ func (r *objReader) readSlices() { n := r.readInt() r.data = make([]byte, n) n = r.readInt() - r.reloc = make([]Reloc, n) + r.reloc = make([]sym.Reloc, n) n = r.readInt() - r.pcdata = make([]Pcdata, n) + r.pcdata = make([]sym.Pcdata, n) n = r.readInt() - r.autom = make([]Auto, n) + r.autom = make([]sym.Auto, n) n = r.readInt() - r.funcdata = make([]*Symbol, n) + r.funcdata = make([]*sym.Symbol, n) r.funcdataoff = make([]int64, n) n = r.readInt() - r.file = make([]*Symbol, n) + r.file = make([]*sym.Symbol, n) } // Symbols are prefixed so their content doesn't get confused with the magic footer. @@ -158,7 +159,7 @@ func (r *objReader) readSym() { if c, err = r.rd.ReadByte(); err != nil { log.Fatalln("error reading input: ", err) } - t := abiSymKindToSymKind[c] + t := sym.AbiSymKindToSymKind[c] s := r.readSymIndex() flags := r.readInt() dupok := flags&1 != 0 @@ -171,9 +172,9 @@ func (r *objReader) readSym() { pkg := objabi.PathToPrefix(r.lib.Pkg) isdup := false - var dup *Symbol - if s.Type != 0 && s.Type != SXREF { - if (t == SDATA || t == SBSS || t == SNOPTRBSS) && len(data) == 0 && nreloc == 0 { + var dup *sym.Symbol + if s.Type != 0 && s.Type != sym.SXREF { + if (t == sym.SDATA || t == sym.SBSS || t == sym.SNOPTRBSS) && len(data) == 0 && nreloc == 0 { if s.Size < int64(size) { s.Size = int64(size) } @@ -183,10 +184,10 @@ func (r *objReader) readSym() { return } - if (s.Type == SDATA || s.Type == SBSS || s.Type == SNOPTRBSS) && len(s.P) == 0 && len(s.R) == 0 { + if (s.Type == sym.SDATA || s.Type == sym.SBSS || s.Type == sym.SNOPTRBSS) && len(s.P) == 0 && len(s.R) == 0 { goto overwrite } - if s.Type != SBSS && s.Type != SNOPTRBSS && !dupok && !s.Attr.DuplicateOK() { + if s.Type != sym.SBSS && s.Type != sym.SNOPTRBSS && !dupok && !s.Attr.DuplicateOK() { log.Fatalf("duplicate symbol %s (types %d and %d) in %s and %s", s.Name, s.Type, t, s.File, r.pn) } if len(s.P) > 0 { @@ -199,23 +200,23 @@ func (r *objReader) readSym() { overwrite: s.File = pkg if dupok { - s.Attr |= AttrDuplicateOK + s.Attr |= sym.AttrDuplicateOK } - if t == SXREF { + if t == sym.SXREF { log.Fatalf("bad sxref") } if t == 0 { log.Fatalf("missing type for %s in %s", s.Name, r.pn) } - if t == SBSS && (s.Type == SRODATA || s.Type == SNOPTRBSS) { + if t == sym.SBSS && (s.Type == sym.SRODATA || s.Type == sym.SNOPTRBSS) { t = s.Type } s.Type = t if s.Size < int64(size) { s.Size = int64(size) } - s.Attr.Set(AttrLocal, local) - s.Attr.Set(AttrMakeTypelink, makeTypelink) + s.Attr.Set(sym.AttrLocal, local) + s.Attr.Set(sym.AttrMakeTypelink, makeTypelink) if typ != nil { s.Gotype = typ } @@ -230,7 +231,7 @@ overwrite: } for i := 0; i < nreloc; i++ { - s.R[i] = Reloc{ + s.R[i] = sym.Reloc{ Off: r.readInt32(), Siz: r.readUint8(), Type: objabi.RelocType(r.readInt32()), @@ -240,21 +241,21 @@ overwrite: } } - if s.Type == STEXT { - s.FuncInfo = new(FuncInfo) + if s.Type == sym.STEXT { + s.FuncInfo = new(sym.FuncInfo) pc := s.FuncInfo pc.Args = r.readInt32() pc.Locals = r.readInt32() if r.readUint8() != 0 { - s.Attr |= AttrNoSplit + s.Attr |= sym.AttrNoSplit } flags := r.readInt() if flags&(1<<2) != 0 { - s.Attr |= AttrReflectMethod + s.Attr |= sym.AttrReflectMethod } if flags&(1<<3) != 0 { - s.Attr |= AttrShared + s.Attr |= sym.AttrShared } n := r.readInt() pc.Autom = r.autom[:n:n] @@ -263,7 +264,7 @@ overwrite: } for i := 0; i < n; i++ { - pc.Autom[i] = Auto{ + pc.Autom[i] = sym.Auto{ Asym: r.readSymIndex(), Aoffset: r.readInt32(), Name: r.readInt16(), @@ -305,7 +306,7 @@ overwrite: pc.File[i] = r.readSymIndex() } n = r.readInt() - pc.InlTree = make([]InlinedCall, n) + pc.InlTree = make([]sym.InlinedCall, n) for i := 0; i < n; i++ { pc.InlTree[i].Parent = r.readInt32() pc.InlTree[i].File = r.readSymIndex() @@ -317,7 +318,7 @@ overwrite: if s.Attr.OnList() { log.Fatalf("symbol %s listed multiple times", s.Name) } - s.Attr |= AttrOnList + s.Attr |= sym.AttrOnList r.lib.textp = append(r.lib.textp, s) } else { // there may ba a dup in another package @@ -329,12 +330,12 @@ overwrite: } } } - if s.Type == SDWARFINFO { + if s.Type == sym.SDWARFINFO { r.patchDWARFName(s) } } -func (r *objReader) patchDWARFName(s *Symbol) { +func (r *objReader) patchDWARFName(s *sym.Symbol) { // This is kind of ugly. Really the package name should not // even be included here. if s.Size < 1 || s.P[0] != dwarf.DW_ABRV_FUNCTION { @@ -392,8 +393,8 @@ func (r *objReader) readRef() { if err != nil { log.Panicf("failed to parse $-symbol %s: %v", s.Name, err) } - s.Type = SRODATA - s.Attr |= AttrLocal + s.Type = sym.SRODATA + s.Attr |= sym.AttrLocal switch s.Name[:5] { case "$f32.": if uint64(uint32(x)) != x { @@ -405,10 +406,10 @@ func (r *objReader) readRef() { default: log.Panicf("unrecognized $-symbol: %s", s.Name) } - s.Attr.Set(AttrReachable, false) + s.Attr.Set(sym.AttrReachable, false) } if strings.HasPrefix(s.Name, "runtime.gcbits.") { - s.Attr |= AttrLocal + s.Attr |= sym.AttrLocal } } @@ -521,7 +522,7 @@ func (r *objReader) readSymName() string { } // Reads the index of a symbol reference and resolves it to a symbol -func (r *objReader) readSymIndex() *Symbol { +func (r *objReader) readSymIndex() *sym.Symbol { i := r.readInt() return r.refs[i] } diff --git a/src/cmd/link/internal/ld/pcln.go b/src/cmd/link/internal/ld/pcln.go index c21056ccff..519bdf7c97 100644 --- a/src/cmd/link/internal/ld/pcln.go +++ b/src/cmd/link/internal/ld/pcln.go @@ -7,6 +7,7 @@ package ld import ( "cmd/internal/objabi" "cmd/internal/src" + "cmd/link/internal/sym" "log" "os" "path/filepath" @@ -58,7 +59,7 @@ func pciternext(it *Pciter) { it.nextpc = it.pc + v*it.pcscale } -func pciterinit(ctxt *Link, it *Pciter, d *Pcdata) { +func pciterinit(ctxt *Link, it *Pciter, d *sym.Pcdata) { it.d = *d it.p = it.d.P it.pc = 0 @@ -70,7 +71,7 @@ func pciterinit(ctxt *Link, it *Pciter, d *Pcdata) { pciternext(it) } -func addvarint(d *Pcdata, val uint32) { +func addvarint(d *sym.Pcdata, val uint32) { n := int32(0) for v := val; v >= 0x80; v >>= 7 { n++ @@ -92,7 +93,7 @@ func addvarint(d *Pcdata, val uint32) { p[0] = byte(v) } -func addpctab(ctxt *Link, ftab *Symbol, off int32, d *Pcdata) int32 { +func addpctab(ctxt *Link, ftab *sym.Symbol, off int32, d *sym.Pcdata) int32 { var start int32 if len(d.P) > 0 { start = int32(len(ftab.P)) @@ -101,7 +102,7 @@ func addpctab(ctxt *Link, ftab *Symbol, off int32, d *Pcdata) int32 { return int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(start))) } -func ftabaddstring(ctxt *Link, ftab *Symbol, s string) int32 { +func ftabaddstring(ctxt *Link, ftab *sym.Symbol, s string) int32 { n := int32(len(s)) + 1 start := int32(len(ftab.P)) ftab.Grow(int64(start) + int64(n) + 1) @@ -110,18 +111,18 @@ func ftabaddstring(ctxt *Link, ftab *Symbol, s string) int32 { } // numberfile assigns a file number to the file if it hasn't been assigned already. -func numberfile(ctxt *Link, file *Symbol) { - if file.Type != SFILEPATH { +func numberfile(ctxt *Link, file *sym.Symbol) { + if file.Type != sym.SFILEPATH { ctxt.Filesyms = append(ctxt.Filesyms, file) file.Value = int64(len(ctxt.Filesyms)) - file.Type = SFILEPATH + file.Type = sym.SFILEPATH path := file.Name[len(src.FileSymPrefix):] file.Name = expandGoroot(path) } } -func renumberfiles(ctxt *Link, files []*Symbol, d *Pcdata) { - var f *Symbol +func renumberfiles(ctxt *Link, files []*sym.Symbol, d *sym.Pcdata) { + var f *sym.Symbol // Give files numbers. for i := 0; i < len(files); i++ { @@ -130,7 +131,7 @@ func renumberfiles(ctxt *Link, files []*Symbol, d *Pcdata) { } newval := int32(-1) - var out Pcdata + var out sym.Pcdata var it Pciter for pciterinit(ctxt, &it, d); it.done == 0; pciternext(&it) { // value delta @@ -163,7 +164,7 @@ func renumberfiles(ctxt *Link, files []*Symbol, d *Pcdata) { // onlycsymbol reports whether this is a cgo symbol provided by the // runtime and only used from C code. -func onlycsymbol(s *Symbol) bool { +func onlycsymbol(s *sym.Symbol) bool { switch s.Name { case "_cgo_topofstack", "_cgo_panic", "crosscall2": return true @@ -171,7 +172,7 @@ func onlycsymbol(s *Symbol) bool { return false } -func emitPcln(s *Symbol) bool { +func emitPcln(s *sym.Symbol) bool { if s == nil { return true } @@ -180,7 +181,7 @@ func emitPcln(s *Symbol) bool { } // We want to generate func table entries only for the "lowest level" symbols, // not containers of subsymbols. - if s.Type&SCONTAINER != 0 { + if s.Type&sym.SCONTAINER != 0 { return false } return true @@ -189,20 +190,20 @@ func emitPcln(s *Symbol) bool { // pclntab initializes the pclntab symbol with // runtime function and file name information. -var pclntabZpcln FuncInfo +var pclntabZpcln sym.FuncInfo // These variables are used to initialize runtime.firstmoduledata, see symtab.go:symtab. var pclntabNfunc int32 var pclntabFiletabOffset int32 var pclntabPclntabOffset int32 -var pclntabFirstFunc *Symbol -var pclntabLastFunc *Symbol +var pclntabFirstFunc *sym.Symbol +var pclntabLastFunc *sym.Symbol func (ctxt *Link) pclntab() { funcdataBytes := int64(0) ftab := ctxt.Syms.Lookup("runtime.pclntab", 0) - ftab.Type = SPCLNTAB - ftab.Attr |= AttrReachable + ftab.Type = sym.SPCLNTAB + ftab.Attr |= sym.AttrReachable // See golang.org/s/go12symtab for the format. Briefly: // 8-byte header @@ -212,10 +213,10 @@ func (ctxt *Link) pclntab() { // offset to file table [4 bytes] nfunc := int32(0) - // Find container symbols, mark them with SCONTAINER + // Find container symbols, mark them with sym.SCONTAINER for _, s := range ctxt.Textp { if s.Outer != nil { - s.Outer.Type |= SCONTAINER + s.Outer.Type |= sym.SCONTAINER } } @@ -244,7 +245,7 @@ func (ctxt *Link) pclntab() { } nfunc = 0 - var last *Symbol + var last *sym.Symbol for _, s := range ctxt.Textp { last = s if !emitPcln(s) { @@ -262,14 +263,14 @@ func (ctxt *Link) pclntab() { if len(pcln.InlTree) > 0 { if len(pcln.Pcdata) <= objabi.PCDATA_InlTreeIndex { // Create inlining pcdata table. - pcdata := make([]Pcdata, objabi.PCDATA_InlTreeIndex+1) + pcdata := make([]sym.Pcdata, objabi.PCDATA_InlTreeIndex+1) copy(pcdata, pcln.Pcdata) pcln.Pcdata = pcdata } if len(pcln.Funcdataoff) <= objabi.FUNCDATA_InlTree { // Create inline tree funcdata. - funcdata := make([]*Symbol, objabi.FUNCDATA_InlTree+1) + funcdata := make([]*sym.Symbol, objabi.FUNCDATA_InlTree+1) funcdataoff := make([]int64, objabi.FUNCDATA_InlTree+1) copy(funcdata, pcln.Funcdata) copy(funcdataoff, pcln.Funcdataoff) @@ -334,8 +335,8 @@ func (ctxt *Link) pclntab() { if len(pcln.InlTree) > 0 { inlTreeSym := ctxt.Syms.Lookup("inltree."+s.Name, 0) - inlTreeSym.Type = SRODATA - inlTreeSym.Attr |= AttrReachable | AttrDuplicateOK + inlTreeSym.Type = sym.SRODATA + inlTreeSym.Attr |= sym.AttrReachable | sym.AttrDuplicateOK for i, call := range pcln.InlTree { // Usually, call.File is already numbered since the file @@ -443,9 +444,9 @@ const ( // function for a pc. See src/runtime/symtab.go:findfunc for details. func (ctxt *Link) findfunctab() { t := ctxt.Syms.Lookup("runtime.findfunctab", 0) - t.Type = SRODATA - t.Attr |= AttrReachable - t.Attr |= AttrLocal + t.Type = sym.SRODATA + t.Attr |= sym.AttrReachable + t.Attr |= sym.AttrLocal // find min and max address min := ctxt.Textp[0].Value @@ -468,7 +469,7 @@ func (ctxt *Link) findfunctab() { continue } p := s.Value - var e *Symbol + var e *sym.Symbol i++ if i < len(ctxt.Textp) { e = ctxt.Textp[i] diff --git a/src/cmd/link/internal/ld/pe.go b/src/cmd/link/internal/ld/pe.go index 545c464e33..7a5c133ea5 100644 --- a/src/cmd/link/internal/ld/pe.go +++ b/src/cmd/link/internal/ld/pe.go @@ -7,6 +7,7 @@ package ld import ( "cmd/internal/objabi" "cmd/internal/sys" + "cmd/link/internal/sym" "debug/pe" "encoding/binary" "fmt" @@ -231,7 +232,7 @@ var dosstub = []uint8{ } type Imp struct { - s *Symbol + s *sym.Symbol off uint64 next *Imp argsize int @@ -246,12 +247,12 @@ type Dll struct { } var ( - rsrcsym *Symbol + rsrcsym *sym.Symbol PESECTHEADR int32 PEFILEHEADR int32 pe64 int dr *Dll - dexport [1024]*Symbol + dexport [1024]*sym.Symbol nexport int ) @@ -308,7 +309,7 @@ func (sect *peSection) checkOffset(off int64) { // checkSegment verifies COFF section sect matches address // and file offset provided in segment seg. -func (sect *peSection) checkSegment(seg *Segment) { +func (sect *peSection) checkSegment(seg *sym.Segment) { if seg.Vaddr-PEBASE != uint64(sect.virtualAddress) { Errorf(nil, "%s.VirtualAddress = %#x, want %#x", sect.name, uint64(int64(sect.virtualAddress)), uint64(int64(seg.Vaddr-PEBASE))) errorexit() @@ -481,7 +482,7 @@ func (f *peFile) emitRelocations(ctxt *Link) { // relocsect relocates symbols from first in section sect, and returns // the total number of relocations emitted. - relocsect := func(sect *Section, syms []*Symbol, base uint64) int { + relocsect := func(sect *sym.Section, syms []*sym.Symbol, base uint64) int { // If main section has no bits, nothing to relocate. if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen { return 0 @@ -574,7 +575,7 @@ dwarfLoop: // writeSymbol appends symbol s to file f symbol table. // It also sets s.Dynid to written symbol number. -func (f *peFile) writeSymbol(out *OutBuf, s *Symbol, value int64, sectidx int, typ uint16, class uint8) { +func (f *peFile) writeSymbol(out *OutBuf, s *sym.Symbol, value int64, sectidx int, typ uint16, class uint8) { if len(s.Name) > 8 { out.Write32(0) out.Write32(uint32(f.stringTable.add(s.Name))) @@ -594,7 +595,7 @@ func (f *peFile) writeSymbol(out *OutBuf, s *Symbol, value int64, sectidx int, t // mapToPESection searches peFile f for s symbol's location. // It returns PE section index, and offset within that section. -func (f *peFile) mapToPESection(s *Symbol) (pesectidx int, offset int64, err error) { +func (f *peFile) mapToPESection(s *sym.Symbol) (pesectidx int, offset int64, err error) { if s.Sect == nil { return 0, 0, fmt.Errorf("could not map %s symbol with no section", s.Name) } @@ -608,10 +609,10 @@ func (f *peFile) mapToPESection(s *Symbol) (pesectidx int, offset int64, err err if Linkmode != LinkExternal { return f.dataSect.index, int64(v), nil } - if s.Type == SDATA { + if s.Type == sym.SDATA { return f.dataSect.index, int64(v), nil } - // Note: although address of runtime.edata (type SDATA) is at the start of .bss section + // Note: although address of runtime.edata (type sym.SDATA) is at the start of .bss section // it still belongs to the .data section, not the .bss section. if v < Segdata.Filelen { return f.dataSect.index, int64(v), nil @@ -622,7 +623,7 @@ func (f *peFile) mapToPESection(s *Symbol) (pesectidx int, offset int64, err err // writeSymbols writes all COFF symbol table records. func (f *peFile) writeSymbols(ctxt *Link) { - put := func(ctxt *Link, s *Symbol, name string, type_ SymbolType, addr int64, gotype *Symbol) { + put := func(ctxt *Link, s *sym.Symbol, name string, type_ SymbolType, addr int64, gotype *sym.Symbol) { if s == nil { return } @@ -638,7 +639,7 @@ func (f *peFile) writeSymbols(ctxt *Link) { // Only windows/386 requires underscore prefix on external symbols. if ctxt.Arch.Family == sys.I386 && Linkmode == LinkExternal && - (s.Type == SHOSTOBJ || s.Attr.CgoExport()) { + (s.Type == sym.SHOSTOBJ || s.Attr.CgoExport()) { s.Name = "_" + s.Name } @@ -659,7 +660,7 @@ func (f *peFile) writeSymbols(ctxt *Link) { } } class := IMAGE_SYM_CLASS_EXTERNAL - if s.Version != 0 || (s.Type&SHIDDEN != 0) || s.Attr.Local() { + if s.Version != 0 || (s.Type&sym.SHIDDEN != 0) || s.Attr.Local() { class = IMAGE_SYM_CLASS_STATIC } f.writeSymbol(ctxt.Out, s, value, sect, typ, uint8(class)) @@ -897,8 +898,8 @@ func Peinit(ctxt *Link) { if Linkmode == LinkInternal { // some mingw libs depend on this symbol, for example, FindPESectionByName - ctxt.xdefine("__image_base__", SDATA, PEBASE) - ctxt.xdefine("_image_base__", SDATA, PEBASE) + ctxt.xdefine("__image_base__", sym.SDATA, PEBASE) + ctxt.xdefine("_image_base__", sym.SDATA, PEBASE) } HEADR = PEFILEHEADR @@ -947,7 +948,7 @@ func initdynimport(ctxt *Link) *Dll { dr = nil var m *Imp for _, s := range ctxt.Syms.Allsym { - if !s.Attr.Reachable() || s.Type != SDYNIMPORT { + if !s.Attr.Reachable() || s.Type != sym.SDYNIMPORT { continue } for d = dr; d != nil; d = d.next { @@ -989,7 +990,7 @@ func initdynimport(ctxt *Link) *Dll { // Add real symbol name for d := dr; d != nil; d = d.next { for m = d.ms; m != nil; m = m.next { - m.s.Type = SDATA + m.s.Type = sym.SDATA m.s.Grow(int64(ctxt.Arch.PtrSize)) dynName := m.s.Extname // only windows/386 requires stdcall decoration @@ -997,8 +998,8 @@ func initdynimport(ctxt *Link) *Dll { dynName += fmt.Sprintf("@%d", m.argsize) } dynSym := ctxt.Syms.Lookup(dynName, 0) - dynSym.Attr |= AttrReachable - dynSym.Type = SHOSTOBJ + dynSym.Attr |= sym.AttrReachable + dynSym.Type = sym.SHOSTOBJ r := m.s.AddRel() r.Sym = dynSym r.Off = 0 @@ -1008,11 +1009,11 @@ func initdynimport(ctxt *Link) *Dll { } } else { dynamic := ctxt.Syms.Lookup(".windynamic", 0) - dynamic.Attr |= AttrReachable - dynamic.Type = SWINDOWS + dynamic.Attr |= sym.AttrReachable + dynamic.Type = sym.SWINDOWS for d := dr; d != nil; d = d.next { for m = d.ms; m != nil; m = m.next { - m.s.Type = SWINDOWS | SSUB + m.s.Type = sym.SWINDOWS | sym.SSUB m.s.Sub = dynamic.Sub dynamic.Sub = m.s m.s.Value = dynamic.Size @@ -1143,7 +1144,7 @@ func addimports(ctxt *Link, datsect *peSection) { out.SeekSet(endoff) } -type byExtname []*Symbol +type byExtname []*sym.Symbol func (s byExtname) Len() int { return len(s) } func (s byExtname) Swap(i, j int) { s[i], s[j] = s[j], s[i] } @@ -1237,14 +1238,14 @@ func (ctxt *Link) dope() { /* relocation table */ rel := ctxt.Syms.Lookup(".rel", 0) - rel.Attr |= AttrReachable - rel.Type = SELFROSECT + rel.Attr |= sym.AttrReachable + rel.Type = sym.SELFROSECT initdynimport(ctxt) initdynexport(ctxt) } -func setpersrc(ctxt *Link, sym *Symbol) { +func setpersrc(ctxt *Link, sym *sym.Symbol) { if rsrcsym != nil { Errorf(sym, "too many .rsrc sections") } @@ -1263,7 +1264,7 @@ func addpersrc(ctxt *Link) { // relocation var p []byte - var r *Reloc + var r *sym.Reloc var val uint32 for ri := 0; ri < len(rsrcsym.R); ri++ { r = &rsrcsym.R[ri] diff --git a/src/cmd/link/internal/ld/sym.go b/src/cmd/link/internal/ld/sym.go index 0bb5841d72..9b60cedbbf 100644 --- a/src/cmd/link/internal/ld/sym.go +++ b/src/cmd/link/internal/ld/sym.go @@ -34,19 +34,13 @@ package ld import ( "cmd/internal/objabi" "cmd/internal/sys" + "cmd/link/internal/sym" "log" ) func linknew(arch *sys.Arch) *Link { ctxt := &Link{ - Syms: &Symbols{ - hash: []map[string]*Symbol{ - // preallocate about 2mb for hash of - // non static symbols - make(map[string]*Symbol, 100000), - }, - Allsym: make([]*Symbol, 0, 100000), - }, + Syms: sym.NewSymbols(), Out: &OutBuf{arch: arch}, Arch: arch, LibraryByPkg: make(map[string]*Library), diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go index 0912cb5fe6..a6100e306e 100644 --- a/src/cmd/link/internal/ld/symtab.go +++ b/src/cmd/link/internal/ld/symtab.go @@ -33,6 +33,7 @@ package ld import ( "cmd/internal/objabi" "cmd/internal/sys" + "cmd/link/internal/sym" "fmt" "path/filepath" "strings" @@ -76,7 +77,7 @@ var numelfsym int = 1 // 0 is reserved var elfbind int -func putelfsym(ctxt *Link, x *Symbol, s string, t SymbolType, addr int64, go_ *Symbol) { +func putelfsym(ctxt *Link, x *sym.Symbol, s string, t SymbolType, addr int64, go_ *sym.Symbol) { var typ int switch t { @@ -109,7 +110,7 @@ func putelfsym(ctxt *Link, x *Symbol, s string, t SymbolType, addr int64, go_ *S } var elfshnum int - if xo.Type == SDYNIMPORT || xo.Type == SHOSTOBJ { + if xo.Type == sym.SDYNIMPORT || xo.Type == sym.SHOSTOBJ { elfshnum = SHN_UNDEF } else { if xo.Sect == nil { @@ -120,14 +121,14 @@ func putelfsym(ctxt *Link, x *Symbol, s string, t SymbolType, addr int64, go_ *S Errorf(x, "missing ELF section in putelfsym") return } - elfshnum = xo.Sect.Elfsect.shnum + elfshnum = xo.Sect.Elfsect.(*ElfShdr).shnum } // One pass for each binding: STB_LOCAL, STB_GLOBAL, // maybe one day STB_WEAK. bind := STB_GLOBAL - if x.Version != 0 || (x.Type&SHIDDEN != 0) || x.Attr.Local() { + if x.Version != 0 || (x.Type&sym.SHIDDEN != 0) || x.Attr.Local() { bind = STB_LOCAL } @@ -144,7 +145,7 @@ func putelfsym(ctxt *Link, x *Symbol, s string, t SymbolType, addr int64, go_ *S addr -= int64(xo.Sect.Vaddr) } other := STV_DEFAULT - if x.Type&SHIDDEN != 0 { + if x.Type&sym.SHIDDEN != 0 { other = STV_HIDDEN } if ctxt.Arch.Family == sys.PPC64 && typ == STT_FUNC && x.Attr.Shared() && x.Name != "runtime.duffzero" && x.Name != "runtime.duffcopy" { @@ -165,13 +166,13 @@ func putelfsym(ctxt *Link, x *Symbol, s string, t SymbolType, addr int64, go_ *S s = strings.Replace(s, "·", ".", -1) } - if ctxt.DynlinkingGo() && bind == STB_GLOBAL && elfbind == STB_LOCAL && x.Type == STEXT { + if ctxt.DynlinkingGo() && bind == STB_GLOBAL && elfbind == STB_LOCAL && x.Type == sym.STEXT { // When dynamically linking, we want references to functions defined // in this module to always be to the function object, not to the // PLT. We force this by writing an additional local symbol for every // global function symbol and making all relocations against the // global symbol refer to this local symbol instead (see - // (*Symbol).ElfsymForReloc). This is approximately equivalent to the + // (*sym.Symbol).ElfsymForReloc). This is approximately equivalent to the // ELF linker -Bsymbolic-functions option, but that is buggy on // several platforms. putelfsyment(ctxt.Out, putelfstr("local."+s), addr, size, STB_LOCAL<<4|typ&0xf, elfshnum, other) @@ -187,7 +188,7 @@ func putelfsym(ctxt *Link, x *Symbol, s string, t SymbolType, addr int64, go_ *S numelfsym++ } -func putelfsectionsym(out *OutBuf, s *Symbol, shndx int) { +func putelfsectionsym(out *OutBuf, s *sym.Symbol, shndx int) { putelfsyment(out, 0, 0, 0, STB_LOCAL<<4|STT_SECTION, shndx, 0) s.Elfsym = int32(numelfsym) numelfsym++ @@ -214,7 +215,7 @@ func Asmelfsym(ctxt *Link) { genasmsym(ctxt, putelfsym) } -func putplan9sym(ctxt *Link, x *Symbol, s string, typ SymbolType, addr int64, go_ *Symbol) { +func putplan9sym(ctxt *Link, x *sym.Symbol, s string, typ SymbolType, addr int64, go_ *sym.Symbol) { t := int(typ) switch typ { case TextSym, DataSym, BSSSym: @@ -247,7 +248,7 @@ func Asmplan9sym(ctxt *Link) { genasmsym(ctxt, putplan9sym) } -var symt *Symbol +var symt *sym.Symbol type byPkg []*Library @@ -268,8 +269,8 @@ func (libs byPkg) Swap(a, b int) { func textsectionmap(ctxt *Link) uint32 { t := ctxt.Syms.Lookup("runtime.textsectionmap", 0) - t.Type = SRODATA - t.Attr |= AttrReachable + t.Type = sym.SRODATA + t.Attr |= sym.AttrReachable nsections := int64(0) for _, sect := range Segtext.Sections { @@ -324,98 +325,98 @@ func (ctxt *Link) symtab() { // Define these so that they'll get put into the symbol table. // data.c:/^address will provide the actual values. - ctxt.xdefine("runtime.text", STEXT, 0) - - ctxt.xdefine("runtime.etext", STEXT, 0) - ctxt.xdefine("runtime.itablink", SRODATA, 0) - ctxt.xdefine("runtime.eitablink", SRODATA, 0) - ctxt.xdefine("runtime.rodata", SRODATA, 0) - ctxt.xdefine("runtime.erodata", SRODATA, 0) - ctxt.xdefine("runtime.types", SRODATA, 0) - ctxt.xdefine("runtime.etypes", SRODATA, 0) - ctxt.xdefine("runtime.noptrdata", SNOPTRDATA, 0) - ctxt.xdefine("runtime.enoptrdata", SNOPTRDATA, 0) - ctxt.xdefine("runtime.data", SDATA, 0) - ctxt.xdefine("runtime.edata", SDATA, 0) - ctxt.xdefine("runtime.bss", SBSS, 0) - ctxt.xdefine("runtime.ebss", SBSS, 0) - ctxt.xdefine("runtime.noptrbss", SNOPTRBSS, 0) - ctxt.xdefine("runtime.enoptrbss", SNOPTRBSS, 0) - ctxt.xdefine("runtime.end", SBSS, 0) - ctxt.xdefine("runtime.epclntab", SRODATA, 0) - ctxt.xdefine("runtime.esymtab", SRODATA, 0) + ctxt.xdefine("runtime.text", sym.STEXT, 0) + + ctxt.xdefine("runtime.etext", sym.STEXT, 0) + ctxt.xdefine("runtime.itablink", sym.SRODATA, 0) + ctxt.xdefine("runtime.eitablink", sym.SRODATA, 0) + ctxt.xdefine("runtime.rodata", sym.SRODATA, 0) + ctxt.xdefine("runtime.erodata", sym.SRODATA, 0) + ctxt.xdefine("runtime.types", sym.SRODATA, 0) + ctxt.xdefine("runtime.etypes", sym.SRODATA, 0) + ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, 0) + ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATA, 0) + ctxt.xdefine("runtime.data", sym.SDATA, 0) + ctxt.xdefine("runtime.edata", sym.SDATA, 0) + ctxt.xdefine("runtime.bss", sym.SBSS, 0) + ctxt.xdefine("runtime.ebss", sym.SBSS, 0) + ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, 0) + ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, 0) + ctxt.xdefine("runtime.end", sym.SBSS, 0) + ctxt.xdefine("runtime.epclntab", sym.SRODATA, 0) + ctxt.xdefine("runtime.esymtab", sym.SRODATA, 0) // garbage collection symbols s := ctxt.Syms.Lookup("runtime.gcdata", 0) - s.Type = SRODATA + s.Type = sym.SRODATA s.Size = 0 - s.Attr |= AttrReachable - ctxt.xdefine("runtime.egcdata", SRODATA, 0) + s.Attr |= sym.AttrReachable + ctxt.xdefine("runtime.egcdata", sym.SRODATA, 0) s = ctxt.Syms.Lookup("runtime.gcbss", 0) - s.Type = SRODATA + s.Type = sym.SRODATA s.Size = 0 - s.Attr |= AttrReachable - ctxt.xdefine("runtime.egcbss", SRODATA, 0) + s.Attr |= sym.AttrReachable + ctxt.xdefine("runtime.egcbss", sym.SRODATA, 0) // pseudo-symbols to mark locations of type, string, and go string data. - var symtype *Symbol - var symtyperel *Symbol + var symtype *sym.Symbol + var symtyperel *sym.Symbol if UseRelro() && (Buildmode == BuildmodeCArchive || Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE) { s = ctxt.Syms.Lookup("type.*", 0) - s.Type = STYPE + s.Type = sym.STYPE s.Size = 0 - s.Attr |= AttrReachable + s.Attr |= sym.AttrReachable symtype = s s = ctxt.Syms.Lookup("typerel.*", 0) - s.Type = STYPERELRO + s.Type = sym.STYPERELRO s.Size = 0 - s.Attr |= AttrReachable + s.Attr |= sym.AttrReachable symtyperel = s } else if !ctxt.DynlinkingGo() { s = ctxt.Syms.Lookup("type.*", 0) - s.Type = STYPE + s.Type = sym.STYPE s.Size = 0 - s.Attr |= AttrReachable + s.Attr |= sym.AttrReachable symtype = s symtyperel = s } - groupSym := func(name string, t SymKind) *Symbol { + groupSym := func(name string, t sym.SymKind) *sym.Symbol { s := ctxt.Syms.Lookup(name, 0) s.Type = t s.Size = 0 - s.Attr |= AttrLocal | AttrReachable + s.Attr |= sym.AttrLocal | sym.AttrReachable return s } var ( - symgostring = groupSym("go.string.*", SGOSTRING) - symgofunc = groupSym("go.func.*", SGOFUNC) - symgcbits = groupSym("runtime.gcbits.*", SGCBITS) + symgostring = groupSym("go.string.*", sym.SGOSTRING) + symgofunc = groupSym("go.func.*", sym.SGOFUNC) + symgcbits = groupSym("runtime.gcbits.*", sym.SGCBITS) ) - var symgofuncrel *Symbol + var symgofuncrel *sym.Symbol if !ctxt.DynlinkingGo() { if UseRelro() { - symgofuncrel = groupSym("go.funcrel.*", SGOFUNCRELRO) + symgofuncrel = groupSym("go.funcrel.*", sym.SGOFUNCRELRO) } else { symgofuncrel = symgofunc } } symitablink := ctxt.Syms.Lookup("runtime.itablink", 0) - symitablink.Type = SITABLINK + symitablink.Type = sym.SITABLINK symt = ctxt.Syms.Lookup("runtime.symtab", 0) - symt.Attr |= AttrLocal - symt.Type = SSYMTAB + symt.Attr |= sym.AttrLocal + symt.Type = sym.SSYMTAB symt.Size = 0 - symt.Attr |= AttrReachable + symt.Attr |= sym.AttrReachable nitablinks := 0 @@ -424,53 +425,53 @@ func (ctxt *Link) symtab() { // just defined above will be first. // hide the specific symbols. for _, s := range ctxt.Syms.Allsym { - if !s.Attr.Reachable() || s.Attr.Special() || s.Type != SRODATA { + if !s.Attr.Reachable() || s.Attr.Special() || s.Type != sym.SRODATA { continue } switch { case strings.HasPrefix(s.Name, "type."): if !ctxt.DynlinkingGo() { - s.Attr |= AttrNotInSymbolTable + s.Attr |= sym.AttrNotInSymbolTable } if UseRelro() { - s.Type = STYPERELRO + s.Type = sym.STYPERELRO s.Outer = symtyperel } else { - s.Type = STYPE + s.Type = sym.STYPE s.Outer = symtype } case strings.HasPrefix(s.Name, "go.importpath.") && UseRelro(): // Keep go.importpath symbols in the same section as types and // names, as they can be referred to by a section offset. - s.Type = STYPERELRO + s.Type = sym.STYPERELRO case strings.HasPrefix(s.Name, "go.itablink."): nitablinks++ - s.Type = SITABLINK - s.Attr |= AttrNotInSymbolTable + s.Type = sym.SITABLINK + s.Attr |= sym.AttrNotInSymbolTable s.Outer = symitablink case strings.HasPrefix(s.Name, "go.string."): - s.Type = SGOSTRING - s.Attr |= AttrNotInSymbolTable + s.Type = sym.SGOSTRING + s.Attr |= sym.AttrNotInSymbolTable s.Outer = symgostring case strings.HasPrefix(s.Name, "runtime.gcbits."): - s.Type = SGCBITS - s.Attr |= AttrNotInSymbolTable + s.Type = sym.SGCBITS + s.Attr |= sym.AttrNotInSymbolTable s.Outer = symgcbits case strings.HasSuffix(s.Name, "·f"): if !ctxt.DynlinkingGo() { - s.Attr |= AttrNotInSymbolTable + s.Attr |= sym.AttrNotInSymbolTable } if UseRelro() { - s.Type = SGOFUNCRELRO + s.Type = sym.SGOFUNCRELRO s.Outer = symgofuncrel } else { - s.Type = SGOFUNC + s.Type = sym.SGOFUNC s.Outer = symgofunc } @@ -478,8 +479,8 @@ func (ctxt *Link) symtab() { strings.HasPrefix(s.Name, "gclocals."), strings.HasPrefix(s.Name, "gclocals·"), strings.HasPrefix(s.Name, "inltree."): - s.Type = SGOFUNC - s.Attr |= AttrNotInSymbolTable + s.Type = sym.SGOFUNC + s.Attr |= sym.AttrNotInSymbolTable s.Outer = symgofunc s.Align = 4 liveness += (s.Size + int64(s.Align) - 1) &^ (int64(s.Align) - 1) @@ -488,8 +489,8 @@ func (ctxt *Link) symtab() { if Buildmode == BuildmodeShared { abihashgostr := ctxt.Syms.Lookup("go.link.abihash."+filepath.Base(*flagOutfile), 0) - abihashgostr.Attr |= AttrReachable - abihashgostr.Type = SRODATA + abihashgostr.Attr |= sym.AttrReachable + abihashgostr.Type = sym.SRODATA hashsym := ctxt.Syms.Lookup("go.link.abihashbytes", 0) abihashgostr.AddAddr(ctxt.Arch, hashsym) abihashgostr.AddUint(ctxt.Arch, uint64(hashsym.Size)) @@ -497,13 +498,13 @@ func (ctxt *Link) symtab() { if Buildmode == BuildmodePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil { for _, l := range ctxt.Library { s := ctxt.Syms.Lookup("go.link.pkghashbytes."+l.Pkg, 0) - s.Attr |= AttrReachable - s.Type = SRODATA + s.Attr |= sym.AttrReachable + s.Type = sym.SRODATA s.Size = int64(len(l.hash)) s.P = []byte(l.hash) str := ctxt.Syms.Lookup("go.link.pkghash."+l.Pkg, 0) - str.Attr |= AttrReachable - str.Type = SRODATA + str.Attr |= sym.AttrReachable + str.Type = sym.SRODATA str.AddAddr(ctxt.Arch, s) str.AddUint(ctxt.Arch, uint64(len(l.hash))) } @@ -567,8 +568,8 @@ func (ctxt *Link) symtab() { moduledata.AddUint(ctxt.Arch, uint64(nitablinks)) // The ptab slice if ptab := ctxt.Syms.ROLookup("go.plugin.tabs", 0); ptab != nil && ptab.Attr.Reachable() { - ptab.Attr |= AttrLocal - ptab.Type = SRODATA + ptab.Attr |= sym.AttrLocal + ptab.Type = sym.SRODATA nentries := uint64(len(ptab.P) / 8) // sizeof(nameOff) + sizeof(typeOff) moduledata.AddAddr(ctxt.Arch, ptab) @@ -583,9 +584,9 @@ func (ctxt *Link) symtab() { addgostring(ctxt, moduledata, "go.link.thispluginpath", *flagPluginPath) pkghashes := ctxt.Syms.Lookup("go.link.pkghashes", 0) - pkghashes.Attr |= AttrReachable - pkghashes.Attr |= AttrLocal - pkghashes.Type = SRODATA + pkghashes.Attr |= sym.AttrReachable + pkghashes.Attr |= sym.AttrLocal + pkghashes.Type = sym.SRODATA for i, l := range ctxt.Library { // pkghashes[i].name @@ -617,9 +618,9 @@ func (ctxt *Link) symtab() { addgostring(ctxt, moduledata, "go.link.thismodulename", thismodulename) modulehashes := ctxt.Syms.Lookup("go.link.abihashes", 0) - modulehashes.Attr |= AttrReachable - modulehashes.Attr |= AttrLocal - modulehashes.Type = SRODATA + modulehashes.Attr |= sym.AttrReachable + modulehashes.Attr |= sym.AttrLocal + modulehashes.Type = sym.SRODATA for i, shlib := range ctxt.Shlibs { // modulehashes[i].modulename @@ -631,7 +632,7 @@ func (ctxt *Link) symtab() { // modulehashes[i].runtimehash abihash := ctxt.Syms.Lookup("go.link.abihash."+modulename, 0) - abihash.Attr |= AttrReachable + abihash.Attr |= sym.AttrReachable modulehashes.AddAddr(ctxt.Arch, abihash) } @@ -649,8 +650,8 @@ func (ctxt *Link) symtab() { moduledata.Grow(moduledata.Size) lastmoduledatap := ctxt.Syms.Lookup("runtime.lastmoduledatap", 0) - if lastmoduledatap.Type != SDYNIMPORT { - lastmoduledatap.Type = SNOPTRDATA + if lastmoduledatap.Type != sym.SDYNIMPORT { + lastmoduledatap.Type = sym.SNOPTRDATA lastmoduledatap.Size = 0 // overwrite existing value lastmoduledatap.AddAddr(ctxt.Arch, moduledata) } diff --git a/src/cmd/link/internal/ld/typelink.go b/src/cmd/link/internal/ld/typelink.go index 29e497a730..6b5ab080f3 100644 --- a/src/cmd/link/internal/ld/typelink.go +++ b/src/cmd/link/internal/ld/typelink.go @@ -6,6 +6,7 @@ package ld import ( "cmd/internal/objabi" + "cmd/link/internal/sym" "sort" ) @@ -13,7 +14,7 @@ type byTypeStr []typelinkSortKey type typelinkSortKey struct { TypeStr string - Type *Symbol + Type *sym.Symbol } func (s byTypeStr) Less(i, j int) bool { return s[i].TypeStr < s[j].TypeStr } @@ -33,11 +34,11 @@ func (ctxt *Link) typelink() { sort.Sort(typelinks) tl := ctxt.Syms.Lookup("runtime.typelink", 0) - tl.Type = STYPELINK - tl.Attr |= AttrReachable | AttrLocal + tl.Type = sym.STYPELINK + tl.Attr |= sym.AttrReachable | sym.AttrLocal tl.Size = int64(4 * len(typelinks)) tl.P = make([]byte, tl.Size) - tl.R = make([]Reloc, len(typelinks)) + tl.R = make([]sym.Reloc, len(typelinks)) for i, s := range typelinks { r := &tl.R[i] r.Sym = s.Type diff --git a/src/cmd/link/internal/ld/util.go b/src/cmd/link/internal/ld/util.go index 85a0e2e4be..71d4325111 100644 --- a/src/cmd/link/internal/ld/util.go +++ b/src/cmd/link/internal/ld/util.go @@ -6,6 +6,7 @@ package ld import ( "bytes" + "cmd/link/internal/sym" "encoding/binary" "fmt" "os" @@ -102,7 +103,7 @@ func Exitf(format string, a ...interface{}) { // // Logging an error means that on exit cmd/link will delete any // output file and return a non-zero error code. -func Errorf(s *Symbol, format string, args ...interface{}) { +func Errorf(s *sym.Symbol, format string, args ...interface{}) { if s != nil { format = s.Name + ": " + format } diff --git a/src/cmd/link/internal/mips/asm.go b/src/cmd/link/internal/mips/asm.go index 2f5008f089..42babfaa59 100644 --- a/src/cmd/link/internal/mips/asm.go +++ b/src/cmd/link/internal/mips/asm.go @@ -34,6 +34,7 @@ import ( "cmd/internal/objabi" "cmd/internal/sys" "cmd/link/internal/ld" + "cmd/link/internal/sym" "fmt" "log" ) @@ -42,12 +43,12 @@ func gentext(ctxt *ld.Link) { return } -func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { +func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { log.Fatalf("adddynrel not implemented") return false } -func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool { +func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ctxt.Out.Write32(uint32(sectoff)) elfsym := r.Xsym.ElfsymForReloc() @@ -76,11 +77,11 @@ func elfsetupplt(ctxt *ld.Link) { return } -func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool { +func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { return false } -func applyrel(arch *sys.Arch, r *ld.Reloc, s *ld.Symbol, val *int64, t int64) { +func applyrel(arch *sys.Arch, r *sym.Reloc, s *sym.Symbol, val *int64, t int64) { o := arch.ByteOrder.Uint32(s.P[r.Off:]) switch r.Type { case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSTLS: @@ -92,7 +93,7 @@ func applyrel(arch *sys.Arch, r *ld.Reloc, s *ld.Symbol, val *int64, t int64) { } } -func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { +func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool { if ld.Linkmode == ld.LinkExternal { switch r.Type { default: @@ -108,7 +109,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { rs = rs.Outer } - if rs.Type != ld.SHOSTOBJ && rs.Type != ld.SDYNIMPORT && rs.Sect == nil { + if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil { ld.Errorf(s, "missing section for %s", rs.Name) } r.Xsym = rs @@ -161,7 +162,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { return false } -func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 { +func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { return -1 } diff --git a/src/cmd/link/internal/mips64/asm.go b/src/cmd/link/internal/mips64/asm.go index c61421e10c..c56bba24d2 100644 --- a/src/cmd/link/internal/mips64/asm.go +++ b/src/cmd/link/internal/mips64/asm.go @@ -34,18 +34,19 @@ import ( "cmd/internal/objabi" "cmd/internal/sys" "cmd/link/internal/ld" + "cmd/link/internal/sym" "fmt" "log" ) func gentext(ctxt *ld.Link) {} -func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { +func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { log.Fatalf("adddynrel not implemented") return false } -func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool { +func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { // mips64 ELF relocation (endian neutral) // offset uint64 // sym uint32 @@ -93,11 +94,11 @@ func elfsetupplt(ctxt *ld.Link) { return } -func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool { +func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { return false } -func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { +func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool { if ld.Linkmode == ld.LinkExternal { switch r.Type { default: @@ -114,7 +115,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { rs = rs.Outer } - if rs.Type != ld.SHOSTOBJ && rs.Type != ld.SDYNIMPORT && rs.Sect == nil { + if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil { ld.Errorf(s, "missing section for %s", rs.Name) } r.Xsym = rs @@ -168,7 +169,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { return false } -func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 { +func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { return -1 } diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go index bf0c8f6153..9404910750 100644 --- a/src/cmd/link/internal/ppc64/asm.go +++ b/src/cmd/link/internal/ppc64/asm.go @@ -34,6 +34,7 @@ import ( "cmd/internal/objabi" "cmd/internal/sys" "cmd/link/internal/ld" + "cmd/link/internal/sym" "encoding/binary" "fmt" "log" @@ -88,11 +89,11 @@ func genplt(ctxt *ld.Link) { // // This assumes "case 1" from the ABI, where the caller needs // us to save and restore the TOC pointer. - var stubs []*ld.Symbol + var stubs []*sym.Symbol for _, s := range ctxt.Textp { for i := range s.R { r := &s.R[i] - if r.Type != 256+ld.R_PPC64_REL24 || r.Sym.Type != ld.SDYNIMPORT { + if r.Type != 256+ld.R_PPC64_REL24 || r.Sym.Type != sym.SDYNIMPORT { continue } @@ -105,7 +106,7 @@ func genplt(ctxt *ld.Link) { stub := ctxt.Syms.Lookup(n, 0) if s.Attr.Reachable() { - stub.Attr |= ld.AttrReachable + stub.Attr |= sym.AttrReachable } if stub.Size == 0 { // Need outer to resolve .TOC. @@ -132,14 +133,14 @@ func genplt(ctxt *ld.Link) { func genaddmoduledata(ctxt *ld.Link) { addmoduledata := ctxt.Syms.ROLookup("runtime.addmoduledata", 0) - if addmoduledata.Type == ld.STEXT && ld.Buildmode != ld.BuildmodePlugin { + if addmoduledata.Type == sym.STEXT && ld.Buildmode != ld.BuildmodePlugin { return } - addmoduledata.Attr |= ld.AttrReachable + addmoduledata.Attr |= sym.AttrReachable initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0) - initfunc.Type = ld.STEXT - initfunc.Attr |= ld.AttrLocal - initfunc.Attr |= ld.AttrReachable + initfunc.Type = sym.STEXT + initfunc.Attr |= sym.AttrLocal + initfunc.Attr |= sym.AttrReachable o := func(op uint32) { initfunc.AddUint32(ctxt.Arch, op) } @@ -148,7 +149,7 @@ func genaddmoduledata(ctxt *ld.Link) { rel.Off = int32(initfunc.Size) rel.Siz = 8 rel.Sym = ctxt.Syms.Lookup(".TOC.", 0) - rel.Sym.Attr |= ld.AttrReachable + rel.Sym.Attr |= sym.AttrReachable rel.Type = objabi.R_ADDRPOWER_PCREL o(0x3c4c0000) // addi r2, r2, .TOC.-func@l @@ -166,8 +167,8 @@ func genaddmoduledata(ctxt *ld.Link) { } else { rel.Sym = ctxt.Syms.Lookup("runtime.firstmoduledata", 0) } - rel.Sym.Attr |= ld.AttrReachable - rel.Sym.Attr |= ld.AttrLocal + rel.Sym.Attr |= sym.AttrReachable + rel.Sym.Attr |= sym.AttrLocal rel.Type = objabi.R_ADDRPOWER_GOT o(0x3c620000) // ld r3, local.moduledata@got@l(r3) @@ -195,9 +196,9 @@ func genaddmoduledata(ctxt *ld.Link) { } initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0) ctxt.Textp = append(ctxt.Textp, initfunc) - initarray_entry.Attr |= ld.AttrReachable - initarray_entry.Attr |= ld.AttrLocal - initarray_entry.Type = ld.SINITARR + initarray_entry.Attr |= sym.AttrReachable + initarray_entry.Attr |= sym.AttrLocal + initarray_entry.Type = sym.SINITARR initarray_entry.AddAddr(ctxt.Arch, initfunc) } @@ -213,7 +214,7 @@ func gentext(ctxt *ld.Link) { // Construct a call stub in stub that calls symbol targ via its PLT // entry. -func gencallstub(ctxt *ld.Link, abicase int, stub *ld.Symbol, targ *ld.Symbol) { +func gencallstub(ctxt *ld.Link, abicase int, stub *sym.Symbol, targ *sym.Symbol) { if abicase != 1 { // If we see R_PPC64_TOCSAVE or R_PPC64_REL24_NOTOC // relocations, we'll need to implement cases 2 and 3. @@ -222,7 +223,7 @@ func gencallstub(ctxt *ld.Link, abicase int, stub *ld.Symbol, targ *ld.Symbol) { plt := ctxt.Syms.Lookup(".plt", 0) - stub.Type = ld.STEXT + stub.Type = sym.STEXT // Save TOC pointer in TOC save slot stub.AddUint32(ctxt.Arch, 0xf8410018) // std r2,24(r1) @@ -238,7 +239,7 @@ func gencallstub(ctxt *ld.Link, abicase int, stub *ld.Symbol, targ *ld.Symbol) { r.Off += int32(r.Siz) } r.Type = objabi.R_POWER_TOC - r.Variant = ld.RV_POWER_HA + r.Variant = sym.RV_POWER_HA stub.AddUint32(ctxt.Arch, 0x3d820000) // addis r12,r2,targ@plt@toc@ha r = stub.AddRel() r.Off = int32(stub.Size) @@ -249,7 +250,7 @@ func gencallstub(ctxt *ld.Link, abicase int, stub *ld.Symbol, targ *ld.Symbol) { r.Off += int32(r.Siz) } r.Type = objabi.R_POWER_TOC - r.Variant = ld.RV_POWER_LO + r.Variant = sym.RV_POWER_LO stub.AddUint32(ctxt.Arch, 0xe98c0000) // ld r12,targ@plt@toc@l(r12) // Jump to the loaded pointer @@ -257,13 +258,13 @@ func gencallstub(ctxt *ld.Link, abicase int, stub *ld.Symbol, targ *ld.Symbol) { stub.AddUint32(ctxt.Arch, 0x4e800420) // bctr } -func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { +func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { targ := r.Sym switch r.Type { default: if r.Type >= 256 { - ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, ld.RelocName(ctxt.Arch, r.Type)) + ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type)) return false } @@ -278,7 +279,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { // to use r12 to compute r2.) r.Add += int64(r.Sym.Localentry) * 4 - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { // Should have been handled in elfsetupplt ld.Errorf(s, "unexpected R_PPC64_REL24 for dyn import") } @@ -289,7 +290,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { r.Type = objabi.R_PCREL r.Add += 4 - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { ld.Errorf(s, "unexpected R_PPC_REL32 for dyn import") } @@ -297,7 +298,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { case 256 + ld.R_PPC64_ADDR64: r.Type = objabi.R_ADDR - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { // These happen in .toc sections ld.Adddynsym(ctxt, targ) @@ -312,55 +313,55 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { case 256 + ld.R_PPC64_TOC16: r.Type = objabi.R_POWER_TOC - r.Variant = ld.RV_POWER_LO | ld.RV_CHECK_OVERFLOW + r.Variant = sym.RV_POWER_LO | sym.RV_CHECK_OVERFLOW return true case 256 + ld.R_PPC64_TOC16_LO: r.Type = objabi.R_POWER_TOC - r.Variant = ld.RV_POWER_LO + r.Variant = sym.RV_POWER_LO return true case 256 + ld.R_PPC64_TOC16_HA: r.Type = objabi.R_POWER_TOC - r.Variant = ld.RV_POWER_HA | ld.RV_CHECK_OVERFLOW + r.Variant = sym.RV_POWER_HA | sym.RV_CHECK_OVERFLOW return true case 256 + ld.R_PPC64_TOC16_HI: r.Type = objabi.R_POWER_TOC - r.Variant = ld.RV_POWER_HI | ld.RV_CHECK_OVERFLOW + r.Variant = sym.RV_POWER_HI | sym.RV_CHECK_OVERFLOW return true case 256 + ld.R_PPC64_TOC16_DS: r.Type = objabi.R_POWER_TOC - r.Variant = ld.RV_POWER_DS | ld.RV_CHECK_OVERFLOW + r.Variant = sym.RV_POWER_DS | sym.RV_CHECK_OVERFLOW return true case 256 + ld.R_PPC64_TOC16_LO_DS: r.Type = objabi.R_POWER_TOC - r.Variant = ld.RV_POWER_DS + r.Variant = sym.RV_POWER_DS return true case 256 + ld.R_PPC64_REL16_LO: r.Type = objabi.R_PCREL - r.Variant = ld.RV_POWER_LO + r.Variant = sym.RV_POWER_LO r.Add += 2 // Compensate for relocation size of 2 return true case 256 + ld.R_PPC64_REL16_HI: r.Type = objabi.R_PCREL - r.Variant = ld.RV_POWER_HI | ld.RV_CHECK_OVERFLOW + r.Variant = sym.RV_POWER_HI | sym.RV_CHECK_OVERFLOW r.Add += 2 return true case 256 + ld.R_PPC64_REL16_HA: r.Type = objabi.R_PCREL - r.Variant = ld.RV_POWER_HA | ld.RV_CHECK_OVERFLOW + r.Variant = sym.RV_POWER_HA | sym.RV_CHECK_OVERFLOW r.Add += 2 return true } // Handle references to ELF symbols from our own object files. - if targ.Type != ld.SDYNIMPORT { + if targ.Type != sym.SDYNIMPORT { return true } @@ -369,7 +370,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { return false } -func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool { +func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ctxt.Out.Write64(uint64(sectoff)) elfsym := r.Xsym.ElfsymForReloc() @@ -448,13 +449,13 @@ func elfsetupplt(ctxt *ld.Link) { } } -func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool { +func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { return false } // Return the value of .TOC. for symbol s -func symtoc(ctxt *ld.Link, s *ld.Symbol) int64 { - var toc *ld.Symbol +func symtoc(ctxt *ld.Link, s *sym.Symbol) int64 { + var toc *sym.Symbol if s.Outer != nil { toc = ctxt.Syms.ROLookup(".TOC.", int(s.Outer.Version)) @@ -470,7 +471,7 @@ func symtoc(ctxt *ld.Link, s *ld.Symbol) int64 { return toc.Value } -func archrelocaddr(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { +func archrelocaddr(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool { var o1, o2 uint32 if ctxt.Arch.ByteOrder == binary.BigEndian { o1 = uint32(*val >> 32) @@ -518,7 +519,7 @@ func archrelocaddr(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { } // resolve direct jump relocation r in s, and add trampoline if necessary -func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) { +func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) { // Trampolines are created if the branch offset is too large and the linker cannot insert a call stub to handle it. // For internal linking, trampolines are always created for long calls. @@ -536,7 +537,7 @@ func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) { // If branch offset is too far then create a trampoline. if (ld.Linkmode == ld.LinkExternal && s.Sect != r.Sym.Sect) || (ld.Linkmode == ld.LinkInternal && int64(int32(t<<6)>>6) != t) || (*ld.FlagDebugTramp > 1 && s.File != r.Sym.File) { - var tramp *ld.Symbol + var tramp *sym.Symbol for i := 0; ; i++ { // Using r.Add as part of the name is significant in functions like duffzero where the call @@ -579,11 +580,11 @@ func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) { r.Done = false } default: - ld.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type, ld.RelocName(ctxt.Arch, r.Type)) + ld.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type)) } } -func gentramp(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) { +func gentramp(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) { // Used for default build mode for an executable // Address of the call target is generated using // relocation and doesn't depend on r2 (TOC). @@ -619,7 +620,7 @@ func gentramp(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) { arch.ByteOrder.PutUint32(tramp.P[12:], o4) } -func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { +func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool { if ld.Linkmode == ld.LinkExternal { switch r.Type { default: @@ -646,7 +647,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { rs = rs.Outer } - if rs.Type != ld.SHOSTOBJ && rs.Type != ld.SDYNIMPORT && rs.Sect == nil { + if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil { ld.Errorf(s, "missing section for %s", rs.Name) } r.Xsym = rs @@ -704,17 +705,17 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { return false } -func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 { - switch r.Variant & ld.RV_TYPE_MASK { +func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { + switch r.Variant & sym.RV_TYPE_MASK { default: ld.Errorf(s, "unexpected relocation variant %d", r.Variant) fallthrough - case ld.RV_NONE: + case sym.RV_NONE: return t - case ld.RV_POWER_LO: - if r.Variant&ld.RV_CHECK_OVERFLOW != 0 { + case sym.RV_POWER_LO: + if r.Variant&sym.RV_CHECK_OVERFLOW != 0 { // Whether to check for signed or unsigned // overflow depends on the instruction var o1 uint32 @@ -740,15 +741,15 @@ func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 { return int64(int16(t)) - case ld.RV_POWER_HA: + case sym.RV_POWER_HA: t += 0x8000 fallthrough // Fallthrough - case ld.RV_POWER_HI: + case sym.RV_POWER_HI: t >>= 16 - if r.Variant&ld.RV_CHECK_OVERFLOW != 0 { + if r.Variant&sym.RV_CHECK_OVERFLOW != 0 { // Whether to check for signed or unsigned // overflow depends on the instruction var o1 uint32 @@ -774,7 +775,7 @@ func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 { return int64(int16(t)) - case ld.RV_POWER_DS: + case sym.RV_POWER_DS: var o1 uint32 if ctxt.Arch.ByteOrder == binary.BigEndian { o1 = uint32(ld.Be16(s.P[r.Off:])) @@ -784,7 +785,7 @@ func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 { if t&3 != 0 { ld.Errorf(s, "relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t) } - if (r.Variant&ld.RV_CHECK_OVERFLOW != 0) && int64(int16(t)) != t { + if (r.Variant&sym.RV_CHECK_OVERFLOW != 0) && int64(int16(t)) != t { goto overflow } return int64(o1)&0x3 | int64(int16(t)) @@ -795,7 +796,7 @@ overflow: return t } -func addpltsym(ctxt *ld.Link, s *ld.Symbol) { +func addpltsym(ctxt *ld.Link, s *sym.Symbol) { if s.Plt >= 0 { return } @@ -841,7 +842,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) { } // Generate the glink resolver stub if necessary and return the .glink section -func ensureglinkresolver(ctxt *ld.Link) *ld.Symbol { +func ensureglinkresolver(ctxt *ld.Link) *sym.Symbol { glink := ctxt.Syms.Lookup(".glink", 0) if glink.Size != 0 { return glink diff --git a/src/cmd/link/internal/s390x/asm.go b/src/cmd/link/internal/s390x/asm.go index 28044433d3..4000c95f22 100644 --- a/src/cmd/link/internal/s390x/asm.go +++ b/src/cmd/link/internal/s390x/asm.go @@ -34,6 +34,7 @@ import ( "cmd/internal/objabi" "cmd/internal/sys" "cmd/link/internal/ld" + "cmd/link/internal/sym" "debug/elf" "fmt" ) @@ -53,16 +54,16 @@ func gentext(ctxt *ld.Link) { return } addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0) - if addmoduledata.Type == ld.STEXT && ld.Buildmode != ld.BuildmodePlugin { + if addmoduledata.Type == sym.STEXT && ld.Buildmode != ld.BuildmodePlugin { // we're linking a module containing the runtime -> no need for // an init function return } - addmoduledata.Attr |= ld.AttrReachable + addmoduledata.Attr |= sym.AttrReachable initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0) - initfunc.Type = ld.STEXT - initfunc.Attr |= ld.AttrLocal - initfunc.Attr |= ld.AttrReachable + initfunc.Type = sym.STEXT + initfunc.Attr |= sym.AttrLocal + initfunc.Attr |= sym.AttrReachable // larl %r2, initfunc.AddUint8(0xc0) @@ -72,7 +73,7 @@ func gentext(ctxt *ld.Link) { lmd.Siz = 4 lmd.Sym = ctxt.Moduledata lmd.Type = objabi.R_PCREL - lmd.Variant = ld.RV_390_DBL + lmd.Variant = sym.RV_390_DBL lmd.Add = 2 + int64(lmd.Siz) initfunc.AddUint32(ctxt.Arch, 0) @@ -84,7 +85,7 @@ func gentext(ctxt *ld.Link) { rel.Siz = 4 rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0) rel.Type = objabi.R_CALL - rel.Variant = ld.RV_390_DBL + rel.Variant = sym.RV_390_DBL rel.Add = 2 + int64(rel.Siz) initfunc.AddUint32(ctxt.Arch, 0) @@ -95,13 +96,13 @@ func gentext(ctxt *ld.Link) { } ctxt.Textp = append(ctxt.Textp, initfunc) initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0) - initarray_entry.Attr |= ld.AttrLocal - initarray_entry.Attr |= ld.AttrReachable - initarray_entry.Type = ld.SINITARR + initarray_entry.Attr |= sym.AttrLocal + initarray_entry.Attr |= sym.AttrReachable + initarray_entry.Type = sym.SINITARR initarray_entry.AddAddr(ctxt.Arch, initfunc) } -func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { +func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { targ := r.Sym switch r.Type { @@ -121,7 +122,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { 256 + ld.R_390_16, 256 + ld.R_390_32, 256 + ld.R_390_64: - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { ld.Errorf(s, "unexpected R_390_nn relocation for dynamic symbol %s", targ.Name) } r.Type = objabi.R_ADDR @@ -130,10 +131,10 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { case 256 + ld.R_390_PC16, 256 + ld.R_390_PC32, 256 + ld.R_390_PC64: - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { ld.Errorf(s, "unexpected R_390_PCnn relocation for dynamic symbol %s", targ.Name) } - if targ.Type == 0 || targ.Type == ld.SXREF { + if targ.Type == 0 || targ.Type == sym.SXREF { ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name) } r.Type = objabi.R_PCREL @@ -149,9 +150,9 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { case 256 + ld.R_390_PLT16DBL, 256 + ld.R_390_PLT32DBL: r.Type = objabi.R_PCREL - r.Variant = ld.RV_390_DBL + r.Variant = sym.RV_390_DBL r.Add += int64(r.Siz) - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { addpltsym(ctxt, targ) r.Sym = ctxt.Syms.Lookup(".plt", 0) r.Add += int64(targ.Plt) @@ -162,7 +163,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { 256 + ld.R_390_PLT64: r.Type = objabi.R_PCREL r.Add += int64(r.Siz) - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { addpltsym(ctxt, targ) r.Sym = ctxt.Syms.Lookup(".plt", 0) r.Add += int64(targ.Plt) @@ -186,7 +187,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { return false case 256 + ld.R_390_GOTOFF: - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { ld.Errorf(s, "unexpected R_390_GOTOFF relocation for dynamic symbol %s", targ.Name) } r.Type = objabi.R_GOTOFF @@ -201,16 +202,16 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { case 256 + ld.R_390_PC16DBL, 256 + ld.R_390_PC32DBL: r.Type = objabi.R_PCREL - r.Variant = ld.RV_390_DBL + r.Variant = sym.RV_390_DBL r.Add += int64(r.Siz) - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { ld.Errorf(s, "unexpected R_390_PCnnDBL relocation for dynamic symbol %s", targ.Name) } return true case 256 + ld.R_390_GOTPCDBL: r.Type = objabi.R_PCREL - r.Variant = ld.RV_390_DBL + r.Variant = sym.RV_390_DBL r.Sym = ctxt.Syms.Lookup(".got", 0) r.Add += int64(r.Siz) return true @@ -219,21 +220,21 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { addgotsym(ctxt, targ) r.Type = objabi.R_PCREL - r.Variant = ld.RV_390_DBL + r.Variant = sym.RV_390_DBL r.Sym = ctxt.Syms.Lookup(".got", 0) r.Add += int64(targ.Got) r.Add += int64(r.Siz) return true } // Handle references to ELF symbols from our own object files. - if targ.Type != ld.SDYNIMPORT { + if targ.Type != sym.SDYNIMPORT { return true } return false } -func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool { +func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ctxt.Out.Write64(uint64(sectoff)) elfsym := r.Xsym.ElfsymForReloc() @@ -275,14 +276,14 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool { } case objabi.R_PCREL, objabi.R_PCRELDBL, objabi.R_CALL: elfrel := ld.R_390_NONE - isdbl := r.Variant&ld.RV_TYPE_MASK == ld.RV_390_DBL + isdbl := r.Variant&sym.RV_TYPE_MASK == sym.RV_390_DBL // TODO(mundaym): all DBL style relocations should be // signalled using the variant - see issue 14218. switch r.Type { case objabi.R_PCRELDBL, objabi.R_CALL: isdbl = true } - if r.Xsym.Type == ld.SDYNIMPORT && (r.Xsym.ElfType == elf.STT_FUNC || r.Type == objabi.R_CALL) { + if r.Xsym.Type == sym.SDYNIMPORT && (r.Xsym.ElfType == elf.STT_FUNC || r.Type == objabi.R_CALL) { if isdbl { switch r.Siz { case 2: @@ -377,11 +378,11 @@ func elfsetupplt(ctxt *ld.Link) { } } -func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool { +func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { return false } -func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { +func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool { if ld.Linkmode == ld.LinkExternal { return false } @@ -398,16 +399,16 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { return false } -func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 { - switch r.Variant & ld.RV_TYPE_MASK { +func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { + switch r.Variant & sym.RV_TYPE_MASK { default: ld.Errorf(s, "unexpected relocation variant %d", r.Variant) return t - case ld.RV_NONE: + case sym.RV_NONE: return t - case ld.RV_390_DBL: + case sym.RV_390_DBL: if (t & 1) != 0 { ld.Errorf(s, "%s+%v is not 2-byte aligned", r.Sym.Name, r.Sym.Value) } @@ -415,7 +416,7 @@ func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 { } } -func addpltsym(ctxt *ld.Link, s *ld.Symbol) { +func addpltsym(ctxt *ld.Link, s *sym.Symbol) { if s.Plt >= 0 { return } @@ -478,7 +479,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) { } } -func addgotsym(ctxt *ld.Link, s *ld.Symbol) { +func addgotsym(ctxt *ld.Link, s *sym.Symbol) { if s.Got >= 0 { return } diff --git a/src/cmd/link/internal/sym/attribute.go b/src/cmd/link/internal/sym/attribute.go new file mode 100644 index 0000000000..1293e890a4 --- /dev/null +++ b/src/cmd/link/internal/sym/attribute.go @@ -0,0 +1,83 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package sym + +// Attribute is a set of common symbol attributes. +type Attribute int16 + +const ( + // AttrDuplicateOK marks a symbol that can be present in multiple object + // files. + AttrDuplicateOK Attribute = 1 << iota + // AttrExternal marks function symbols loaded from host object files. + AttrExternal + // AttrNoSplit marks functions that cannot split the stack; the linker + // cares because it checks that there are no call chains of nosplit + // functions that require more than StackLimit bytes (see + // lib.go:dostkcheck) + AttrNoSplit + // AttrReachable marks symbols that are transitively referenced from the + // entry points. Unreachable symbols are not written to the output. + AttrReachable + // AttrCgoExportDynamic and AttrCgoExportStatic mark symbols referenced + // by directives written by cgo (in response to //export directives in + // the source). + AttrCgoExportDynamic + AttrCgoExportStatic + // AttrSpecial marks symbols that do not have their address (i.e. Value) + // computed by the usual mechanism of data.go:dodata() & + // data.go:address(). + AttrSpecial + // AttrStackCheck is used by dostkcheck to only check each NoSplit + // function's stack usage once. + AttrStackCheck + // AttrNotInSymbolTable marks symbols that are not written to the symbol table. + AttrNotInSymbolTable + // AttrOnList marks symbols that are on some list (such as the list of + // all text symbols, or one of the lists of data symbols) and is + // consulted to avoid bugs where a symbol is put on a list twice. + AttrOnList + // AttrLocal marks symbols that are only visible within the module + // (executable or shared library) being linked. Only relevant when + // dynamically linking Go code. + AttrLocal + // AttrReflectMethod marks certain methods from the reflect package that + // can be used to call arbitrary methods. If no symbol with this bit set + // is marked as reachable, more dead code elimination can be done. + AttrReflectMethod + // AttrMakeTypelink Amarks types that should be added to the typelink + // table. See typelinks.go:typelinks(). + AttrMakeTypelink + // AttrShared marks symbols compiled with the -shared option. + AttrShared + // 14 attributes defined so far. +) + +func (a Attribute) DuplicateOK() bool { return a&AttrDuplicateOK != 0 } +func (a Attribute) External() bool { return a&AttrExternal != 0 } +func (a Attribute) NoSplit() bool { return a&AttrNoSplit != 0 } +func (a Attribute) Reachable() bool { return a&AttrReachable != 0 } +func (a Attribute) CgoExportDynamic() bool { return a&AttrCgoExportDynamic != 0 } +func (a Attribute) CgoExportStatic() bool { return a&AttrCgoExportStatic != 0 } +func (a Attribute) Special() bool { return a&AttrSpecial != 0 } +func (a Attribute) StackCheck() bool { return a&AttrStackCheck != 0 } +func (a Attribute) NotInSymbolTable() bool { return a&AttrNotInSymbolTable != 0 } +func (a Attribute) OnList() bool { return a&AttrOnList != 0 } +func (a Attribute) Local() bool { return a&AttrLocal != 0 } +func (a Attribute) ReflectMethod() bool { return a&AttrReflectMethod != 0 } +func (a Attribute) MakeTypelink() bool { return a&AttrMakeTypelink != 0 } +func (a Attribute) Shared() bool { return a&AttrShared != 0 } + +func (a Attribute) CgoExport() bool { + return a.CgoExportDynamic() || a.CgoExportStatic() +} + +func (a *Attribute) Set(flag Attribute, value bool) { + if value { + *a |= flag + } else { + *a &^= flag + } +} diff --git a/src/cmd/link/internal/sym/reloc.go b/src/cmd/link/internal/sym/reloc.go new file mode 100644 index 0000000000..e55fd27f22 --- /dev/null +++ b/src/cmd/link/internal/sym/reloc.go @@ -0,0 +1,97 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package sym + +import ( + "cmd/internal/objabi" + "cmd/internal/sys" + "debug/elf" +) + +// Reloc is a relocation. +// +// The typical Reloc rewrites part of a symbol at offset Off to address Sym. +// A Reloc is stored in a slice on the Symbol it rewrites. +// +// Relocations are generated by the compiler as the type +// cmd/internal/obj.Reloc, which is encoded into the object file wire +// format and decoded by the linker into this type. A separate type is +// used to hold linker-specific state about the relocation. +// +// Some relocations are created by cmd/link. +type Reloc struct { + Off int32 // offset to rewrite + Siz uint8 // number of bytes to rewrite, 1, 2, or 4 + Done bool // set to true when relocation is complete + Variant RelocVariant // variation on Type + Type objabi.RelocType // the relocation type + Add int64 // addend + Xadd int64 // addend passed to external linker + Sym *Symbol // symbol the relocation addresses + Xsym *Symbol // symbol passed to external linker +} + +// RelocVariant is a linker-internal variation on a relocation. +type RelocVariant uint8 + +const ( + RV_NONE RelocVariant = iota + RV_POWER_LO + RV_POWER_HI + RV_POWER_HA + RV_POWER_DS + + // RV_390_DBL is a s390x-specific relocation variant that indicates that + // the value to be placed into the relocatable field should first be + // divided by 2. + RV_390_DBL + + RV_CHECK_OVERFLOW RelocVariant = 1 << 7 + RV_TYPE_MASK RelocVariant = RV_CHECK_OVERFLOW - 1 +) + +func RelocName(arch *sys.Arch, r objabi.RelocType) string { + // We didn't have some relocation types at Go1.4. + // Uncomment code when we include those in bootstrap code. + + switch { + case r >= 512: // Mach-O + // nr := (r - 512)>>1 + // switch ctxt.Arch.Family { + // case sys.AMD64: + // return macho.RelocTypeX86_64(nr).String() + // case sys.ARM: + // return macho.RelocTypeARM(nr).String() + // case sys.ARM64: + // return macho.RelocTypeARM64(nr).String() + // case sys.I386: + // return macho.RelocTypeGeneric(nr).String() + // default: + // panic("unreachable") + // } + case r >= 256: // ELF + nr := r - 256 + switch arch.Family { + case sys.AMD64: + return elf.R_X86_64(nr).String() + case sys.ARM: + return elf.R_ARM(nr).String() + case sys.ARM64: + return elf.R_AARCH64(nr).String() + case sys.I386: + return elf.R_386(nr).String() + case sys.MIPS, sys.MIPS64: + // return elf.R_MIPS(nr).String() + case sys.PPC64: + // return elf.R_PPC64(nr).String() + case sys.S390X: + // return elf.R_390(nr).String() + default: + panic("unreachable") + } + } + + return r.String() +} diff --git a/src/cmd/link/internal/sym/segment.go b/src/cmd/link/internal/sym/segment.go new file mode 100644 index 0000000000..d5255bf142 --- /dev/null +++ b/src/cmd/link/internal/sym/segment.go @@ -0,0 +1,58 @@ +// Inferno utils/8l/asm.c +// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/8l/asm.c +// +// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. +// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) +// Portions Copyright © 1997-1999 Vita Nuova Limited +// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) +// Portions Copyright © 2004,2006 Bruce Ellis +// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) +// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others +// Portions Copyright © 2009 The Go Authors. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package sym + +// Terrible but standard terminology. +// A segment describes a block of file to load into memory. +// A section further describes the pieces of that block for +// use in debuggers and such. + +type Segment struct { + Rwx uint8 // permission as usual unix bits (5 = r-x etc) + Vaddr uint64 // virtual address + Length uint64 // length in memory + Fileoff uint64 // file offset + Filelen uint64 // length on disk + Sections []*Section +} + +type Section struct { + Rwx uint8 + Extnum int16 + Align int32 + Name string + Vaddr uint64 + Length uint64 + Seg *Segment + Elfsect interface{} // an *ld.ElfShdr + Reloff uint64 + Rellen uint64 +} diff --git a/src/cmd/link/internal/ld/symbol.go b/src/cmd/link/internal/sym/symbol.go similarity index 84% rename from src/cmd/link/internal/ld/symbol.go rename to src/cmd/link/internal/sym/symbol.go index 746c544bb7..4691e3055b 100644 --- a/src/cmd/link/internal/ld/symbol.go +++ b/src/cmd/link/internal/sym/symbol.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package ld +package sym import ( "cmd/internal/objabi" @@ -105,19 +105,19 @@ func (s *Symbol) AddUint8(v uint8) int64 { } func (s *Symbol) AddUint16(arch *sys.Arch, v uint16) int64 { - return s.addUintXX(arch, uint64(v), 2) + return s.AddUintXX(arch, uint64(v), 2) } func (s *Symbol) AddUint32(arch *sys.Arch, v uint32) int64 { - return s.addUintXX(arch, uint64(v), 4) + return s.AddUintXX(arch, uint64(v), 4) } func (s *Symbol) AddUint64(arch *sys.Arch, v uint64) int64 { - return s.addUintXX(arch, v, 8) + return s.AddUintXX(arch, v, 8) } func (s *Symbol) AddUint(arch *sys.Arch, v uint64) int64 { - return s.addUintXX(arch, v, arch.PtrSize) + return s.AddUintXX(arch, v, arch.PtrSize) } func (s *Symbol) SetUint8(arch *sys.Arch, r int64, v uint8) int64 { @@ -234,7 +234,7 @@ func (s *Symbol) AddRel() *Reloc { return &s.R[len(s.R)-1] } -func (s *Symbol) addUintXX(arch *sys.Arch, v uint64, wid int) int64 { +func (s *Symbol) AddUintXX(arch *sys.Arch, v uint64, wid int) int64 { off := s.Size s.setUintXX(arch, off, v, int64(wid)) return off @@ -263,3 +263,37 @@ func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64 return off + wid } + +type FuncInfo struct { + Args int32 + Locals int32 + Autom []Auto + Pcsp Pcdata + Pcfile Pcdata + Pcline Pcdata + Pcinline Pcdata + Pcdata []Pcdata + Funcdata []*Symbol + Funcdataoff []int64 + File []*Symbol + InlTree []InlinedCall +} + +// InlinedCall is a node in a local inlining tree (FuncInfo.InlTree). +type InlinedCall struct { + Parent int32 // index of parent in InlTree + File *Symbol // file of the inlined call + Line int32 // line number of the inlined call + Func *Symbol // function that was inlined +} + +type Pcdata struct { + P []byte +} + +type Auto struct { + Asym *Symbol + Gotype *Symbol + Aoffset int32 + Name int16 +} diff --git a/src/cmd/link/internal/ld/symbols.go b/src/cmd/link/internal/sym/symbols.go similarity index 90% rename from src/cmd/link/internal/ld/symbols.go rename to src/cmd/link/internal/sym/symbols.go index 8708fc8aae..98a5ae67b8 100644 --- a/src/cmd/link/internal/ld/symbols.go +++ b/src/cmd/link/internal/sym/symbols.go @@ -28,7 +28,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -package ld +package sym type Symbols struct { symbolBatch []Symbol @@ -39,7 +39,18 @@ type Symbols struct { Allsym []*Symbol } -func (syms *Symbols) newsym(name string, v int) *Symbol { +func NewSymbols() *Symbols { + return &Symbols{ + hash: []map[string]*Symbol{ + // preallocate about 2mb for hash of + // non static symbols + make(map[string]*Symbol, 100000), + }, + Allsym: make([]*Symbol, 0, 100000), + } +} + +func (syms *Symbols) Newsym(name string, v int) *Symbol { batch := syms.symbolBatch if len(batch) == 0 { batch = make([]Symbol, 1000) @@ -65,7 +76,7 @@ func (syms *Symbols) Lookup(name string, v int) *Symbol { if s != nil { return s } - s = syms.newsym(name, v) + s = syms.Newsym(name, v) s.Extname = s.Name m[name] = s return s diff --git a/src/cmd/link/internal/ld/symkind.go b/src/cmd/link/internal/sym/symkind.go similarity index 93% rename from src/cmd/link/internal/ld/symkind.go rename to src/cmd/link/internal/sym/symkind.go index f8565e3a2e..619c26d069 100644 --- a/src/cmd/link/internal/ld/symkind.go +++ b/src/cmd/link/internal/sym/symkind.go @@ -28,7 +28,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -package ld +package sym // A SymKind describes the kind of memory represented by a symbol. type SymKind int16 @@ -111,9 +111,9 @@ const ( SCONTAINER = SymKind(1 << 10) // has a sub-symbol ) -// abiSymKindToSymKind maps values read from object files (which are +// AbiSymKindToSymKind maps values read from object files (which are // of type cmd/internal/objabi.SymKind) to values of type SymKind. -var abiSymKindToSymKind = [...]SymKind{ +var AbiSymKindToSymKind = [...]SymKind{ Sxxx, STEXT, SRODATA, @@ -127,10 +127,10 @@ var abiSymKindToSymKind = [...]SymKind{ SDWARFLOC, } -// readOnly are the symbol kinds that form read-only sections. In some +// ReadOnly are the symbol kinds that form read-only sections. In some // cases, if they will require relocations, they are transformed into // rel-ro sections using relROMap. -var readOnly = []SymKind{ +var ReadOnly = []SymKind{ STYPE, SSTRING, SGOSTRING, @@ -140,9 +140,9 @@ var readOnly = []SymKind{ SFUNCTAB, } -// relROMap describes the transformation of read-only symbols to rel-ro +// RelROMap describes the transformation of read-only symbols to rel-ro // symbols. -var relROMap = map[SymKind]SymKind{ +var RelROMap = map[SymKind]SymKind{ STYPE: STYPERELRO, SSTRING: SSTRINGRELRO, SGOSTRING: SGOSTRINGRELRO, diff --git a/src/cmd/link/internal/ld/symkind_string.go b/src/cmd/link/internal/sym/symkind_string.go similarity index 98% rename from src/cmd/link/internal/ld/symkind_string.go rename to src/cmd/link/internal/sym/symkind_string.go index cd14f59786..716eabd850 100644 --- a/src/cmd/link/internal/ld/symkind_string.go +++ b/src/cmd/link/internal/sym/symkind_string.go @@ -1,6 +1,6 @@ // Code generated by "stringer -type=SymKind"; DO NOT EDIT. -package ld +package sym import "fmt" diff --git a/src/cmd/link/internal/x86/asm.go b/src/cmd/link/internal/x86/asm.go index 0b7b7a22fa..d97a0fc91d 100644 --- a/src/cmd/link/internal/x86/asm.go +++ b/src/cmd/link/internal/x86/asm.go @@ -34,12 +34,13 @@ import ( "cmd/internal/objabi" "cmd/internal/sys" "cmd/link/internal/ld" + "cmd/link/internal/sym" "log" ) // Append 4 bytes to s and create a R_CALL relocation targeting t to fill them in. -func addcall(ctxt *ld.Link, s *ld.Symbol, t *ld.Symbol) { - s.Attr |= ld.AttrReachable +func addcall(ctxt *ld.Link, s *sym.Symbol, t *sym.Symbol) { + s.Attr |= sym.AttrReachable i := s.Size s.Size += 4 s.Grow(s.Size) @@ -67,7 +68,7 @@ func gentext(ctxt *ld.Link) { } // Generate little thunks that load the PC of the next instruction into a register. - thunks := make([]*ld.Symbol, 0, 7+len(ctxt.Textp)) + thunks := make([]*sym.Symbol, 0, 7+len(ctxt.Textp)) for _, r := range [...]struct { name string num uint8 @@ -82,9 +83,9 @@ func gentext(ctxt *ld.Link) { {"di", 7}, } { thunkfunc := ctxt.Syms.Lookup("__x86.get_pc_thunk."+r.name, 0) - thunkfunc.Type = ld.STEXT - thunkfunc.Attr |= ld.AttrLocal - thunkfunc.Attr |= ld.AttrReachable //TODO: remove? + thunkfunc.Type = sym.STEXT + thunkfunc.Attr |= sym.AttrLocal + thunkfunc.Attr |= sym.AttrReachable //TODO: remove? o := func(op ...uint8) { for _, op1 := range op { thunkfunc.AddUint8(op1) @@ -101,18 +102,18 @@ func gentext(ctxt *ld.Link) { ctxt.Textp = append(thunks, ctxt.Textp...) // keep Textp in dependency order addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0) - if addmoduledata.Type == ld.STEXT && ld.Buildmode != ld.BuildmodePlugin { + if addmoduledata.Type == sym.STEXT && ld.Buildmode != ld.BuildmodePlugin { // we're linking a module containing the runtime -> no need for // an init function return } - addmoduledata.Attr |= ld.AttrReachable + addmoduledata.Attr |= sym.AttrReachable initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0) - initfunc.Type = ld.STEXT - initfunc.Attr |= ld.AttrLocal - initfunc.Attr |= ld.AttrReachable + initfunc.Type = sym.STEXT + initfunc.Attr |= sym.AttrLocal + initfunc.Attr |= sym.AttrReachable o := func(op ...uint8) { for _, op1 := range op { initfunc.AddUint8(op1) @@ -159,28 +160,28 @@ func gentext(ctxt *ld.Link) { } ctxt.Textp = append(ctxt.Textp, initfunc) initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0) - initarray_entry.Attr |= ld.AttrReachable - initarray_entry.Attr |= ld.AttrLocal - initarray_entry.Type = ld.SINITARR + initarray_entry.Attr |= sym.AttrReachable + initarray_entry.Attr |= sym.AttrLocal + initarray_entry.Type = sym.SINITARR initarray_entry.AddAddr(ctxt.Arch, initfunc) } -func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { +func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { targ := r.Sym switch r.Type { default: if r.Type >= 256 { - ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, ld.RelocName(ctxt.Arch, r.Type)) + ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type)) return false } // Handle relocations found in ELF object files. case 256 + ld.R_386_PC32: - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { ld.Errorf(s, "unexpected R_386_PC32 relocation for dynamic symbol %s", targ.Name) } - if targ.Type == 0 || targ.Type == ld.SXREF { + if targ.Type == 0 || targ.Type == sym.SXREF { ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name) } r.Type = objabi.R_PCREL @@ -190,7 +191,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { case 256 + ld.R_386_PLT32: r.Type = objabi.R_PCREL r.Add += 4 - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { addpltsym(ctxt, targ) r.Sym = ctxt.Syms.Lookup(".plt", 0) r.Add += int64(targ.Plt) @@ -199,7 +200,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { return true case 256 + ld.R_386_GOT32, 256 + ld.R_386_GOT32X: - if targ.Type != ld.SDYNIMPORT { + if targ.Type != sym.SDYNIMPORT { // have symbol if r.Off >= 2 && s.P[r.Off-2] == 0x8b { // turn MOVL of GOT entry into LEAL of symbol address, relative to GOT. @@ -240,7 +241,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { return true case 256 + ld.R_386_32: - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { ld.Errorf(s, "unexpected R_386_32 relocation for dynamic symbol %s", targ.Name) } r.Type = objabi.R_ADDR @@ -248,13 +249,13 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { case 512 + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 0: r.Type = objabi.R_ADDR - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { ld.Errorf(s, "unexpected reloc for dynamic symbol %s", targ.Name) } return true case 512 + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 1: - if targ.Type == ld.SDYNIMPORT { + if targ.Type == sym.SDYNIMPORT { addpltsym(ctxt, targ) r.Sym = ctxt.Syms.Lookup(".plt", 0) r.Add = int64(targ.Plt) @@ -266,7 +267,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { return true case 512 + ld.MACHO_FAKE_GOTPCREL: - if targ.Type != ld.SDYNIMPORT { + if targ.Type != sym.SDYNIMPORT { // have symbol // turn MOVL of GOT entry into LEAL of symbol itself if r.Off < 2 || s.P[r.Off-2] != 0x8b { @@ -287,7 +288,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { } // Handle references to ELF symbols from our own object files. - if targ.Type != ld.SDYNIMPORT { + if targ.Type != sym.SDYNIMPORT { return true } switch r.Type { @@ -299,7 +300,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { return true case objabi.R_ADDR: - if s.Type != ld.SDATA { + if s.Type != sym.SDATA { break } if ld.Iself { @@ -326,7 +327,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { ld.Adddynsym(ctxt, targ) got := ctxt.Syms.Lookup(".got", 0) - s.Type = got.Type | ld.SSUB + s.Type = got.Type | sym.SSUB s.Outer = got s.Sub = got.Sub got.Sub = s @@ -341,7 +342,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { return false } -func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool { +func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ctxt.Out.Write32(uint32(sectoff)) elfsym := r.Xsym.ElfsymForReloc() @@ -366,7 +367,7 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool { } case objabi.R_CALL: if r.Siz == 4 { - if r.Xsym.Type == ld.SDYNIMPORT { + if r.Xsym.Type == sym.SDYNIMPORT { ctxt.Out.Write32(ld.R_386_PLT32 | uint32(elfsym)<<8) } else { ctxt.Out.Write32(ld.R_386_PC32 | uint32(elfsym)<<8) @@ -399,14 +400,14 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool { return true } -func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool { +func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { var v uint32 rs := r.Xsym - if rs.Type == ld.SHOSTOBJ { + if rs.Type == sym.SHOSTOBJ { if rs.Dynid < 0 { - ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type) + ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type) return false } @@ -415,7 +416,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect } else { v = uint32(rs.Sect.Extnum) if v == 0 { - ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type) + ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type) return false } } @@ -449,13 +450,13 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect return true } -func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool { +func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { var v uint32 rs := r.Xsym if rs.Dynid < 0 { - ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type) + ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type) return false } @@ -482,7 +483,7 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff return true } -func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { +func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool { if ld.Linkmode == ld.LinkExternal { return false } @@ -498,7 +499,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { return false } -func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 { +func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { log.Fatalf("unexpected relocation variant") return t } @@ -530,7 +531,7 @@ func elfsetupplt(ctxt *ld.Link) { } } -func addpltsym(ctxt *ld.Link, s *ld.Symbol) { +func addpltsym(ctxt *ld.Link, s *sym.Symbol) { if s.Plt >= 0 { return } @@ -590,7 +591,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) { } } -func addgotsym(ctxt *ld.Link, s *ld.Symbol) { +func addgotsym(ctxt *ld.Link, s *sym.Symbol) { if s.Got >= 0 { return }