From 69261d1f367ae8b14f943c39d7ab80faf80b2e03 Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Mon, 11 May 2020 16:00:13 -0400 Subject: [PATCH] [dev.link] cmd/link: expand architecture support for elf asmb2 path Adds in support for remaining architectures to the linker's ELF asmb2 path, along with deleting most of the older sym.Symbol based code. Change-Id: I67c96525db72b7d6dd3187cf2b9f6faddc296291 Reviewed-on: https://go-review.googlesource.com/c/go/+/233362 Reviewed-by: Cherry Zhang --- src/cmd/link/internal/arm/asm.go | 17 +- src/cmd/link/internal/arm/obj.go | 2 +- src/cmd/link/internal/arm64/asm.go | 11 +- src/cmd/link/internal/arm64/obj.go | 2 +- src/cmd/link/internal/ld/data.go | 8 +- src/cmd/link/internal/ld/dwarf2.go | 28 -- src/cmd/link/internal/ld/elf.go | 8 - src/cmd/link/internal/ld/elf2.go | 643 +-------------------------- src/cmd/link/internal/ld/lib.go | 1 - src/cmd/link/internal/ld/lib2.go | 51 --- src/cmd/link/internal/ld/main.go | 2 +- src/cmd/link/internal/ld/symtab.go | 5 +- src/cmd/link/internal/ld/symtab2.go | 166 ------- src/cmd/link/internal/ld/xcoff2.go | 113 ----- src/cmd/link/internal/mips/asm.go | 8 +- src/cmd/link/internal/mips/obj.go | 2 +- src/cmd/link/internal/mips64/asm.go | 9 +- src/cmd/link/internal/mips64/obj.go | 2 +- src/cmd/link/internal/ppc64/asm.go | 13 +- src/cmd/link/internal/ppc64/obj.go | 2 +- src/cmd/link/internal/riscv64/asm.go | 4 +- src/cmd/link/internal/riscv64/obj.go | 2 +- src/cmd/link/internal/s390x/asm.go | 31 +- src/cmd/link/internal/s390x/obj.go | 2 +- src/cmd/link/internal/x86/asm.go | 23 +- src/cmd/link/internal/x86/obj.go | 2 +- 26 files changed, 76 insertions(+), 1081 deletions(-) delete mode 100644 src/cmd/link/internal/ld/lib2.go delete mode 100644 src/cmd/link/internal/ld/symtab2.go delete mode 100644 src/cmd/link/internal/ld/xcoff2.go diff --git a/src/cmd/link/internal/arm/asm.go b/src/cmd/link/internal/arm/asm.go index e268c15565..0c1f89c6c8 100644 --- a/src/cmd/link/internal/arm/asm.go +++ b/src/cmd/link/internal/arm/asm.go @@ -249,28 +249,29 @@ func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s load return false } -func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { +func elfreloc2(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool { ctxt.Out.Write32(uint32(sectoff)) - elfsym := ld.ElfSymForReloc(ctxt, r.Xsym) - switch r.Type { + elfsym := ld.ElfSymForReloc2(ctxt, r.Xsym) + siz := r.Siz() + switch r.Type() { default: return false case objabi.R_ADDR, objabi.R_DWARFSECREF: - if r.Siz == 4 { + if siz == 4 { ctxt.Out.Write32(uint32(elf.R_ARM_ABS32) | uint32(elfsym)<<8) } else { return false } case objabi.R_PCREL: - if r.Siz == 4 { + if siz == 4 { ctxt.Out.Write32(uint32(elf.R_ARM_REL32) | uint32(elfsym)<<8) } else { return false } case objabi.R_CALLARM: - if r.Siz == 4 { - if r.Add&0xff000000 == 0xeb000000 { // BL + if siz == 4 { + if r.Add()&0xff000000 == 0xeb000000 { // BL ctxt.Out.Write32(uint32(elf.R_ARM_CALL) | uint32(elfsym)<<8) } else { ctxt.Out.Write32(uint32(elf.R_ARM_JUMP24) | uint32(elfsym)<<8) @@ -283,7 +284,7 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { case objabi.R_TLS_IE: ctxt.Out.Write32(uint32(elf.R_ARM_TLS_IE32) | uint32(elfsym)<<8) case objabi.R_GOTPCREL: - if r.Siz == 4 { + if siz == 4 { ctxt.Out.Write32(uint32(elf.R_ARM_GOT_PREL) | uint32(elfsym)<<8) } else { return false diff --git a/src/cmd/link/internal/arm/obj.go b/src/cmd/link/internal/arm/obj.go index 653f16dba1..ecdddb597b 100644 --- a/src/cmd/link/internal/arm/obj.go +++ b/src/cmd/link/internal/arm/obj.go @@ -53,7 +53,7 @@ func Init() (*sys.Arch, ld.Arch) { Trampoline: trampoline, Asmb: asmb, Asmb2: asmb2, - Elfreloc1: elfreloc1, + Elfreloc2: elfreloc2, Elfsetupplt: elfsetupplt, Gentext2: gentext2, Machoreloc1: machoreloc1, diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go index 787851bbd2..bb6a059c46 100644 --- a/src/cmd/link/internal/arm64/asm.go +++ b/src/cmd/link/internal/arm64/asm.go @@ -325,15 +325,16 @@ func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s load return false } -func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { +func elfreloc2(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool { ctxt.Out.Write64(uint64(sectoff)) - elfsym := ld.ElfSymForReloc(ctxt, r.Xsym) - switch r.Type { + elfsym := ld.ElfSymForReloc2(ctxt, r.Xsym) + siz := r.Siz() + switch r.Type() { default: return false case objabi.R_ADDR, objabi.R_DWARFSECREF: - switch r.Siz { + switch siz { case 4: ctxt.Out.Write64(uint64(elf.R_AARCH64_ABS32) | uint64(elfsym)<<32) case 8: @@ -360,7 +361,7 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ctxt.Out.Write64(uint64(sectoff + 4)) ctxt.Out.Write64(uint64(elf.R_AARCH64_LD64_GOT_LO12_NC) | uint64(elfsym)<<32) case objabi.R_CALLARM64: - if r.Siz != 4 { + if siz != 4 { return false } ctxt.Out.Write64(uint64(elf.R_AARCH64_CALL26) | uint64(elfsym)<<32) diff --git a/src/cmd/link/internal/arm64/obj.go b/src/cmd/link/internal/arm64/obj.go index ffce0cb17d..e948273ab9 100644 --- a/src/cmd/link/internal/arm64/obj.go +++ b/src/cmd/link/internal/arm64/obj.go @@ -52,7 +52,7 @@ func Init() (*sys.Arch, ld.Arch) { Archrelocvariant: archrelocvariant, Asmb: asmb, Asmb2: asmb2, - Elfreloc1: elfreloc1, + Elfreloc2: elfreloc2, Elfsetupplt: elfsetupplt, Gentext2: gentext2, Machoreloc1: machoreloc1, diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index f17a9eba63..71e2c30798 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -2104,11 +2104,9 @@ func (ctxt *Link) buildinfo() { ldr := ctxt.loader s := ldr.CreateSymForUpdate(".go.buildinfo", 0) s.SetReachable(true) - if !ctxt.IsAIX() { - // On AIX, .go.buildinfo must be in the symbol table as - // it has relocations. - s.SetNotInSymbolTable(true) - } + // On AIX, .go.buildinfo must be in the symbol table as + // it has relocations. + s.SetNotInSymbolTable(!ctxt.IsAIX()) s.SetType(sym.SBUILDINFO) s.SetAlign(16) // The \xff is invalid UTF-8, meant to make it less likely diff --git a/src/cmd/link/internal/ld/dwarf2.go b/src/cmd/link/internal/ld/dwarf2.go index 02090e1e07..66f8aace0f 100644 --- a/src/cmd/link/internal/ld/dwarf2.go +++ b/src/cmd/link/internal/ld/dwarf2.go @@ -65,34 +65,6 @@ func dwarfaddshstrings(ctxt *Link, shstrtab *loader.SymbolBuilder) { } } -// Add section symbols for DWARF debug info. This is called before -// dwarfaddelfheaders. -func dwarfaddelfsectionsyms2(ctxt *Link) { - if *FlagW { // disable dwarf - return - } - if ctxt.LinkMode != LinkExternal { - return - } - - s := ctxt.Syms.Lookup(".debug_info", 0) - putelfsectionsym2(ctxt, ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum) - s = ctxt.Syms.Lookup(".debug_abbrev", 0) - putelfsectionsym2(ctxt, ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum) - s = ctxt.Syms.Lookup(".debug_line", 0) - putelfsectionsym2(ctxt, ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum) - s = ctxt.Syms.Lookup(".debug_frame", 0) - putelfsectionsym2(ctxt, ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum) - s = ctxt.Syms.Lookup(".debug_loc", 0) - if s.Sect != nil { - putelfsectionsym2(ctxt, ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum) - } - s = ctxt.Syms.Lookup(".debug_ranges", 0) - if s.Sect != nil { - putelfsectionsym2(ctxt, ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum) - } -} - // dwarfcompress compresses the DWARF sections. Relocations are applied // on the fly. After this, dwarfp will contain a different (new) set of // symbols, and sections may have been replaced. diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go index 9cf1339aa4..b6ef555a6b 100644 --- a/src/cmd/link/internal/ld/elf.go +++ b/src/cmd/link/internal/ld/elf.go @@ -1399,10 +1399,6 @@ func elfrelocsect(ctxt *Link, sect *sym.Section, syms []loader.Sym) { } func Elfemitreloc(ctxt *Link) { - if !ctxt.IsAMD64() { - Elfemitreloc2(ctxt) - return - } for ctxt.Out.Offset()&7 != 0 { ctxt.Out.Write8(0) @@ -1785,10 +1781,6 @@ func Asmbelfsetup() { } func Asmbelf(ctxt *Link, symo int64) { - if !ctxt.IsAMD64() { - Asmbelf2(ctxt, symo) - return - } ldr := ctxt.loader eh := getElfEhdr() diff --git a/src/cmd/link/internal/ld/elf2.go b/src/cmd/link/internal/ld/elf2.go index a1f822546c..c7fab6c623 100644 --- a/src/cmd/link/internal/ld/elf2.go +++ b/src/cmd/link/internal/ld/elf2.go @@ -4,12 +4,7 @@ package ld -import ( - "cmd/internal/objabi" - "cmd/internal/sys" - "cmd/link/internal/sym" - "encoding/binary" -) +import "cmd/link/internal/sym" // Temporary dumping around for sym.Symbol version of helper // functions in elf.go, still being used for some archs/oses. @@ -26,639 +21,3 @@ func elfsetstring(s *sym.Symbol, str string, off int) { elfstr[nelfstr].off = off nelfstr++ } - -func Asmbelf2(ctxt *Link, symo int64) { - eh := getElfEhdr() - switch ctxt.Arch.Family { - default: - Exitf("unknown architecture in asmbelf: %v", ctxt.Arch.Family) - case sys.MIPS, sys.MIPS64: - eh.machine = EM_MIPS - case sys.ARM: - eh.machine = EM_ARM - case sys.AMD64: - eh.machine = EM_X86_64 - case sys.ARM64: - eh.machine = EM_AARCH64 - case sys.I386: - eh.machine = EM_386 - case sys.PPC64: - eh.machine = EM_PPC64 - case sys.RISCV64: - eh.machine = EM_RISCV - case sys.S390X: - eh.machine = EM_S390 - } - - elfreserve := int64(ELFRESERVE) - - numtext := int64(0) - for _, sect := range Segtext.Sections { - if sect.Name == ".text" { - numtext++ - } - } - - // If there are multiple text sections, extra space is needed - // in the elfreserve for the additional .text and .rela.text - // section headers. It can handle 4 extra now. Headers are - // 64 bytes. - - if numtext > 4 { - elfreserve += elfreserve + numtext*64*2 - } - - startva := *FlagTextAddr - int64(HEADR) - resoff := elfreserve - - var pph *ElfPhdr - var pnote *ElfPhdr - if *flagRace && ctxt.IsNetbsd() { - sh := elfshname(".note.netbsd.pax") - resoff -= int64(elfnetbsdpax(sh, uint64(startva), uint64(resoff))) - pnote = newElfPhdr() - pnote.type_ = PT_NOTE - pnote.flags = PF_R - phsh(pnote, sh) - } - if ctxt.LinkMode == LinkExternal { - /* skip program headers */ - eh.phoff = 0 - - eh.phentsize = 0 - - if ctxt.BuildMode == BuildModeShared { - sh := elfshname(".note.go.pkg-list") - sh.type_ = SHT_NOTE - sh = elfshname(".note.go.abihash") - sh.type_ = SHT_NOTE - sh.flags = SHF_ALLOC - sh = elfshname(".note.go.deps") - sh.type_ = SHT_NOTE - } - - if *flagBuildid != "" { - sh := elfshname(".note.go.buildid") - sh.type_ = SHT_NOTE - sh.flags = SHF_ALLOC - } - - goto elfobj - } - - /* program header info */ - pph = newElfPhdr() - - pph.type_ = PT_PHDR - pph.flags = PF_R - pph.off = uint64(eh.ehsize) - pph.vaddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.off - pph.paddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.off - pph.align = uint64(*FlagRound) - - /* - * PHDR must be in a loaded segment. Adjust the text - * segment boundaries downwards to include it. - */ - { - o := int64(Segtext.Vaddr - pph.vaddr) - Segtext.Vaddr -= uint64(o) - Segtext.Length += uint64(o) - o = int64(Segtext.Fileoff - pph.off) - Segtext.Fileoff -= uint64(o) - Segtext.Filelen += uint64(o) - } - - if !*FlagD { /* -d suppresses dynamic loader format */ - /* interpreter */ - sh := elfshname(".interp") - - sh.type_ = SHT_PROGBITS - sh.flags = SHF_ALLOC - sh.addralign = 1 - - if interpreter == "" && objabi.GO_LDSO != "" { - interpreter = objabi.GO_LDSO - } - - if interpreter == "" { - switch ctxt.HeadType { - case objabi.Hlinux: - if objabi.GOOS == "android" { - interpreter = thearch.Androiddynld - if interpreter == "" { - Exitf("ELF interpreter not set") - } - } else { - interpreter = thearch.Linuxdynld - } - - case objabi.Hfreebsd: - interpreter = thearch.Freebsddynld - - case objabi.Hnetbsd: - interpreter = thearch.Netbsddynld - - case objabi.Hopenbsd: - interpreter = thearch.Openbsddynld - - case objabi.Hdragonfly: - interpreter = thearch.Dragonflydynld - - case objabi.Hsolaris: - interpreter = thearch.Solarisdynld - } - } - - resoff -= int64(elfinterp(sh, uint64(startva), uint64(resoff), interpreter)) - - ph := newElfPhdr() - ph.type_ = PT_INTERP - ph.flags = PF_R - phsh(ph, sh) - } - - pnote = nil - if ctxt.HeadType == objabi.Hnetbsd || ctxt.HeadType == objabi.Hopenbsd { - var sh *ElfShdr - switch ctxt.HeadType { - case objabi.Hnetbsd: - sh = elfshname(".note.netbsd.ident") - resoff -= int64(elfnetbsdsig(sh, uint64(startva), uint64(resoff))) - - case objabi.Hopenbsd: - sh = elfshname(".note.openbsd.ident") - resoff -= int64(elfopenbsdsig(sh, uint64(startva), uint64(resoff))) - } - - pnote = newElfPhdr() - pnote.type_ = PT_NOTE - pnote.flags = PF_R - phsh(pnote, sh) - } - - if len(buildinfo) > 0 { - sh := elfshname(".note.gnu.build-id") - resoff -= int64(elfbuildinfo(sh, uint64(startva), uint64(resoff))) - - if pnote == nil { - pnote = newElfPhdr() - pnote.type_ = PT_NOTE - pnote.flags = PF_R - } - - phsh(pnote, sh) - } - - if *flagBuildid != "" { - sh := elfshname(".note.go.buildid") - resoff -= int64(elfgobuildid(sh, uint64(startva), uint64(resoff))) - - pnote := newElfPhdr() - pnote.type_ = PT_NOTE - pnote.flags = PF_R - phsh(pnote, sh) - } - - // Additions to the reserved area must be above this line. - - elfphload(&Segtext) - if len(Segrodata.Sections) > 0 { - elfphload(&Segrodata) - } - if len(Segrelrodata.Sections) > 0 { - elfphload(&Segrelrodata) - elfphrelro(&Segrelrodata) - } - elfphload(&Segdata) - - /* Dynamic linking sections */ - if !*FlagD { - sh := elfshname(".dynsym") - sh.type_ = SHT_DYNSYM - sh.flags = SHF_ALLOC - if elf64 { - sh.entsize = ELF64SYMSIZE - } else { - sh.entsize = ELF32SYMSIZE - } - sh.addralign = uint64(ctxt.Arch.RegSize) - sh.link = uint32(elfshname(".dynstr").shnum) - - // sh.info is the index of first non-local symbol (number of local symbols) - s := ctxt.Syms.Lookup(".dynsym", 0) - i := uint32(0) - for sub := s; sub != nil; sub = symSub(ctxt, sub) { - i++ - if !sub.Attr.Local() { - break - } - } - sh.info = i - shsym(sh, s) - - sh = elfshname(".dynstr") - sh.type_ = SHT_STRTAB - sh.flags = SHF_ALLOC - sh.addralign = 1 - shsym(sh, ctxt.Syms.Lookup(".dynstr", 0)) - - if elfverneed != 0 { - sh := elfshname(".gnu.version") - sh.type_ = SHT_GNU_VERSYM - sh.flags = SHF_ALLOC - sh.addralign = 2 - sh.link = uint32(elfshname(".dynsym").shnum) - sh.entsize = 2 - shsym(sh, ctxt.Syms.Lookup(".gnu.version", 0)) - - sh = elfshname(".gnu.version_r") - sh.type_ = SHT_GNU_VERNEED - sh.flags = SHF_ALLOC - sh.addralign = uint64(ctxt.Arch.RegSize) - sh.info = uint32(elfverneed) - sh.link = uint32(elfshname(".dynstr").shnum) - shsym(sh, ctxt.Syms.Lookup(".gnu.version_r", 0)) - } - - if elfRelType == ".rela" { - sh := elfshname(".rela.plt") - sh.type_ = SHT_RELA - sh.flags = SHF_ALLOC - sh.entsize = ELF64RELASIZE - sh.addralign = uint64(ctxt.Arch.RegSize) - sh.link = uint32(elfshname(".dynsym").shnum) - sh.info = uint32(elfshname(".plt").shnum) - shsym(sh, ctxt.Syms.Lookup(".rela.plt", 0)) - - sh = elfshname(".rela") - sh.type_ = SHT_RELA - sh.flags = SHF_ALLOC - sh.entsize = ELF64RELASIZE - sh.addralign = 8 - sh.link = uint32(elfshname(".dynsym").shnum) - shsym(sh, ctxt.Syms.Lookup(".rela", 0)) - } else { - sh := elfshname(".rel.plt") - sh.type_ = SHT_REL - sh.flags = SHF_ALLOC - sh.entsize = ELF32RELSIZE - sh.addralign = 4 - sh.link = uint32(elfshname(".dynsym").shnum) - shsym(sh, ctxt.Syms.Lookup(".rel.plt", 0)) - - sh = elfshname(".rel") - sh.type_ = SHT_REL - sh.flags = SHF_ALLOC - sh.entsize = ELF32RELSIZE - sh.addralign = 4 - sh.link = uint32(elfshname(".dynsym").shnum) - shsym(sh, ctxt.Syms.Lookup(".rel", 0)) - } - - if eh.machine == EM_PPC64 { - sh := elfshname(".glink") - sh.type_ = SHT_PROGBITS - sh.flags = SHF_ALLOC + SHF_EXECINSTR - sh.addralign = 4 - shsym(sh, ctxt.Syms.Lookup(".glink", 0)) - } - - sh = elfshname(".plt") - sh.type_ = SHT_PROGBITS - sh.flags = SHF_ALLOC + SHF_EXECINSTR - if eh.machine == EM_X86_64 { - sh.entsize = 16 - } else if eh.machine == EM_S390 { - sh.entsize = 32 - } else if eh.machine == EM_PPC64 { - // On ppc64, this is just a table of addresses - // filled by the dynamic linker - sh.type_ = SHT_NOBITS - - sh.flags = SHF_ALLOC + SHF_WRITE - sh.entsize = 8 - } else { - sh.entsize = 4 - } - sh.addralign = sh.entsize - shsym(sh, ctxt.Syms.Lookup(".plt", 0)) - - // On ppc64, .got comes from the input files, so don't - // create it here, and .got.plt is not used. - if eh.machine != EM_PPC64 { - sh := elfshname(".got") - sh.type_ = SHT_PROGBITS - sh.flags = SHF_ALLOC + SHF_WRITE - sh.entsize = uint64(ctxt.Arch.RegSize) - sh.addralign = uint64(ctxt.Arch.RegSize) - shsym(sh, ctxt.Syms.Lookup(".got", 0)) - - sh = elfshname(".got.plt") - sh.type_ = SHT_PROGBITS - sh.flags = SHF_ALLOC + SHF_WRITE - sh.entsize = uint64(ctxt.Arch.RegSize) - sh.addralign = uint64(ctxt.Arch.RegSize) - shsym(sh, ctxt.Syms.Lookup(".got.plt", 0)) - } - - sh = elfshname(".hash") - sh.type_ = SHT_HASH - sh.flags = SHF_ALLOC - sh.entsize = 4 - sh.addralign = uint64(ctxt.Arch.RegSize) - sh.link = uint32(elfshname(".dynsym").shnum) - shsym(sh, ctxt.Syms.Lookup(".hash", 0)) - - /* sh and PT_DYNAMIC for .dynamic section */ - sh = elfshname(".dynamic") - - sh.type_ = SHT_DYNAMIC - sh.flags = SHF_ALLOC + SHF_WRITE - sh.entsize = 2 * uint64(ctxt.Arch.RegSize) - sh.addralign = uint64(ctxt.Arch.RegSize) - sh.link = uint32(elfshname(".dynstr").shnum) - shsym(sh, ctxt.Syms.Lookup(".dynamic", 0)) - ph := newElfPhdr() - ph.type_ = PT_DYNAMIC - ph.flags = PF_R + PF_W - phsh(ph, sh) - - /* - * Thread-local storage segment (really just size). - */ - tlssize := uint64(0) - for _, sect := range Segdata.Sections { - if sect.Name == ".tbss" { - tlssize = sect.Length - } - } - if tlssize != 0 { - ph := newElfPhdr() - ph.type_ = PT_TLS - ph.flags = PF_R - ph.memsz = tlssize - ph.align = uint64(ctxt.Arch.RegSize) - } - } - - if ctxt.HeadType == objabi.Hlinux { - ph := newElfPhdr() - ph.type_ = PT_GNU_STACK - ph.flags = PF_W + PF_R - ph.align = uint64(ctxt.Arch.RegSize) - - ph = newElfPhdr() - ph.type_ = PT_PAX_FLAGS - ph.flags = 0x2a00 // mprotect, randexec, emutramp disabled - ph.align = uint64(ctxt.Arch.RegSize) - } else if ctxt.HeadType == objabi.Hsolaris { - ph := newElfPhdr() - ph.type_ = PT_SUNWSTACK - ph.flags = PF_W + PF_R - } - -elfobj: - sh := elfshname(".shstrtab") - sh.type_ = SHT_STRTAB - sh.addralign = 1 - shsym(sh, ctxt.Syms.Lookup(".shstrtab", 0)) - eh.shstrndx = uint16(sh.shnum) - - // put these sections early in the list - if !*FlagS { - elfshname(".symtab") - elfshname(".strtab") - } - - for _, sect := range Segtext.Sections { - elfshbits(ctxt.LinkMode, sect) - } - for _, sect := range Segrodata.Sections { - elfshbits(ctxt.LinkMode, sect) - } - for _, sect := range Segrelrodata.Sections { - elfshbits(ctxt.LinkMode, sect) - } - for _, sect := range Segdata.Sections { - elfshbits(ctxt.LinkMode, sect) - } - for _, sect := range Segdwarf.Sections { - elfshbits(ctxt.LinkMode, sect) - } - - if ctxt.LinkMode == LinkExternal { - for _, sect := range Segtext.Sections { - elfshreloc(ctxt.Arch, sect) - } - for _, sect := range Segrodata.Sections { - elfshreloc(ctxt.Arch, sect) - } - for _, sect := range Segrelrodata.Sections { - elfshreloc(ctxt.Arch, sect) - } - for _, sect := range Segdata.Sections { - elfshreloc(ctxt.Arch, sect) - } - for _, si := range dwarfp { - s := si.secSym() - elfshreloc(ctxt.Arch, s.Sect) - } - // add a .note.GNU-stack section to mark the stack as non-executable - sh := elfshname(".note.GNU-stack") - - sh.type_ = SHT_PROGBITS - sh.addralign = 1 - sh.flags = 0 - } - - if !*FlagS { - sh := elfshname(".symtab") - sh.type_ = SHT_SYMTAB - sh.off = uint64(symo) - sh.size = uint64(Symsize) - sh.addralign = uint64(ctxt.Arch.RegSize) - sh.entsize = 8 + 2*uint64(ctxt.Arch.RegSize) - sh.link = uint32(elfshname(".strtab").shnum) - sh.info = uint32(elfglobalsymndx) - - sh = elfshname(".strtab") - sh.type_ = SHT_STRTAB - sh.off = uint64(symo) + uint64(Symsize) - sh.size = uint64(len(Elfstrdat)) - sh.addralign = 1 - } - - /* Main header */ - eh.ident[EI_MAG0] = '\177' - - eh.ident[EI_MAG1] = 'E' - eh.ident[EI_MAG2] = 'L' - eh.ident[EI_MAG3] = 'F' - if ctxt.HeadType == objabi.Hfreebsd { - eh.ident[EI_OSABI] = ELFOSABI_FREEBSD - } else if ctxt.HeadType == objabi.Hnetbsd { - eh.ident[EI_OSABI] = ELFOSABI_NETBSD - } else if ctxt.HeadType == objabi.Hopenbsd { - eh.ident[EI_OSABI] = ELFOSABI_OPENBSD - } else if ctxt.HeadType == objabi.Hdragonfly { - eh.ident[EI_OSABI] = ELFOSABI_NONE - } - if elf64 { - eh.ident[EI_CLASS] = ELFCLASS64 - } else { - eh.ident[EI_CLASS] = ELFCLASS32 - } - if ctxt.Arch.ByteOrder == binary.BigEndian { - eh.ident[EI_DATA] = ELFDATA2MSB - } else { - eh.ident[EI_DATA] = ELFDATA2LSB - } - eh.ident[EI_VERSION] = EV_CURRENT - - if ctxt.LinkMode == LinkExternal { - eh.type_ = ET_REL - } else if ctxt.BuildMode == BuildModePIE { - eh.type_ = ET_DYN - } else { - eh.type_ = ET_EXEC - } - - if ctxt.LinkMode != LinkExternal { - eh.entry = uint64(Entryvalue(ctxt)) - } - - eh.version = EV_CURRENT - - if pph != nil { - pph.filesz = uint64(eh.phnum) * uint64(eh.phentsize) - pph.memsz = pph.filesz - } - - ctxt.Out.SeekSet(0) - a := int64(0) - a += int64(elfwritehdr(ctxt.Out)) - a += int64(elfwritephdrs(ctxt.Out)) - a += int64(elfwriteshdrs(ctxt.Out)) - if !*FlagD { - a += int64(elfwriteinterp(ctxt.Out)) - } - if ctxt.LinkMode != LinkExternal { - if ctxt.HeadType == objabi.Hnetbsd { - a += int64(elfwritenetbsdsig(ctxt.Out)) - } - if ctxt.HeadType == objabi.Hopenbsd { - a += int64(elfwriteopenbsdsig(ctxt.Out)) - } - if len(buildinfo) > 0 { - a += int64(elfwritebuildinfo(ctxt.Out)) - } - if *flagBuildid != "" { - a += int64(elfwritegobuildid(ctxt.Out)) - } - } - if *flagRace && ctxt.IsNetbsd() { - a += int64(elfwritenetbsdpax(ctxt.Out)) - } - - if a > elfreserve { - Errorf(nil, "ELFRESERVE too small: %d > %d with %d text sections", a, elfreserve, numtext) - } -} - -// Do not write DT_NULL. elfdynhash will finish it. -func shsym(sh *ElfShdr, s *sym.Symbol) { - addr := Symaddr(s) - if sh.flags&SHF_ALLOC != 0 { - sh.addr = uint64(addr) - } - sh.off = uint64(datoff2(s, addr)) - sh.size = uint64(s.Size) -} - -func Elfemitreloc2(ctxt *Link) { - for ctxt.Out.Offset()&7 != 0 { - ctxt.Out.Write8(0) - } - - for _, sect := range Segtext.Sections { - if sect.Name == ".text" { - elfrelocsect2(ctxt, sect, ctxt.Textp) - } else { - elfrelocsect2(ctxt, sect, ctxt.datap) - } - } - - for _, sect := range Segrodata.Sections { - elfrelocsect2(ctxt, sect, ctxt.datap) - } - for _, sect := range Segrelrodata.Sections { - elfrelocsect2(ctxt, sect, ctxt.datap) - } - for _, sect := range Segdata.Sections { - elfrelocsect2(ctxt, sect, ctxt.datap) - } - for i := 0; i < len(Segdwarf.Sections); i++ { - sect := Segdwarf.Sections[i] - si := dwarfp[i] - if si.secSym() != sect.Sym || - si.secSym().Sect != sect { - panic("inconsistency between dwarfp and Segdwarf") - } - elfrelocsect2(ctxt, sect, si.syms) - } -} - -func elfrelocsect2(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 { - return - } - if sect.Name == ".shstrtab" { - return - } - - sect.Reloff = uint64(ctxt.Out.Offset()) - for i, s := range syms { - if !s.Attr.Reachable() { - continue - } - if uint64(s.Value) >= sect.Vaddr { - syms = syms[i:] - break - } - } - - eaddr := int32(sect.Vaddr + sect.Length) - for _, s := range syms { - if !s.Attr.Reachable() { - continue - } - if s.Value >= int64(eaddr) { - break - } - for ri := range s.R { - r := &s.R[ri] - if r.Done { - continue - } - if r.Xsym == nil { - Errorf(s, "missing xsym in relocation %#v %#v", r.Sym.Name, s) - continue - } - esr := ElfSymForReloc(ctxt, r.Xsym) - if esr == 0 { - 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(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(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) - } - } - } - - sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff -} diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 752dbeebf1..34052f1f6b 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -268,7 +268,6 @@ type Arch struct { Asmb func(*Link, *loader.Loader) Asmb2 func(*Link, *loader.Loader) - Elfreloc1 func(*Link, *sym.Reloc, int64) bool Elfreloc2 func(*Link, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool Elfsetupplt func(ctxt *Link, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) Gentext func(*Link) diff --git a/src/cmd/link/internal/ld/lib2.go b/src/cmd/link/internal/ld/lib2.go deleted file mode 100644 index 296d6d2785..0000000000 --- a/src/cmd/link/internal/ld/lib2.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2020 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 ld - -import ( - "cmd/internal/objabi" - "cmd/link/internal/loader" - "cmd/link/internal/sym" -) - -// Temporary dumping around for sym.Symbol version of helper -// functions in lib.go, still being used for some archs/oses. - -func Entryvalue(ctxt *Link) int64 { - a := *flagEntrySymbol - if a[0] >= '0' && a[0] <= '9' { - return atolwhex(a) - } - s := ctxt.Syms.Lookup(a, 0) - if s.Type == 0 { - return *FlagTextAddr - } - if ctxt.HeadType != objabi.Haix && s.Type != sym.STEXT { - Errorf(s, "entry not text") - } - return s.Value -} - -func datoff2(s *sym.Symbol, addr int64) int64 { - if uint64(addr) >= Segdata.Vaddr { - return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff) - } - if uint64(addr) >= Segtext.Vaddr { - return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff) - } - Errorf(s, "invalid datoff %#x", addr) - return 0 -} - -func ElfSymForReloc(ctxt *Link, s *sym.Symbol) int32 { - // If putelfsym created a local version of this symbol, use that in all - // relocations. - les := ctxt.loader.SymLocalElfSym(loader.Sym(s.SymIdx)) - if les != 0 { - return les - } else { - return ctxt.loader.SymElfSym(loader.Sym(s.SymIdx)) - } -} diff --git a/src/cmd/link/internal/ld/main.go b/src/cmd/link/internal/ld/main.go index 6c16785b43..d22657cf93 100644 --- a/src/cmd/link/internal/ld/main.go +++ b/src/cmd/link/internal/ld/main.go @@ -320,7 +320,7 @@ func Main(arch *sys.Arch, theArch Arch) { thearch.Asmb(ctxt, ctxt.loader) bench.Start("reloc") ctxt.reloc() - newasmb2 := ctxt.IsDarwin() || ctxt.IsWindows() || ctxt.IsWasm() || ctxt.IsPlan9() || (ctxt.IsElf() && ctxt.IsAMD64()) + newasmb2 := ctxt.IsDarwin() || ctxt.IsWindows() || ctxt.IsWasm() || ctxt.IsPlan9() || ctxt.IsElf() if !newasmb2 { bench.Start("loadlibfull") // We don't need relocations at this point. diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go index 18036038fa..bc76210be3 100644 --- a/src/cmd/link/internal/ld/symtab.go +++ b/src/cmd/link/internal/ld/symtab.go @@ -230,10 +230,7 @@ func genelfsym(ctxt *Link, elfbind int) { } func Asmelfsym(ctxt *Link) { - if !ctxt.IsAMD64() { - Asmelfsym2(ctxt) - return - } + // the first symbol entry is reserved putelfsyment(ctxt.Out, 0, 0, 0, STB_LOCAL<<4|STT_NOTYPE, 0, 0) diff --git a/src/cmd/link/internal/ld/symtab2.go b/src/cmd/link/internal/ld/symtab2.go deleted file mode 100644 index 8108d723fc..0000000000 --- a/src/cmd/link/internal/ld/symtab2.go +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2020 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 ld - -import ( - "cmd/internal/sys" - "cmd/link/internal/loader" - "cmd/link/internal/sym" - "strings" -) - -// Temporary dumping around for sym.Symbol version of helper -// functions in symtab.go, still being used for some archs/oses. - -func Asmelfsym2(ctxt *Link) { - - // the first symbol entry is reserved - putelfsyment(ctxt.Out, 0, 0, 0, STB_LOCAL<<4|STT_NOTYPE, 0, 0) - - dwarfaddelfsectionsyms2(ctxt) - - // Some linkers will add a FILE sym if one is not present. - // Avoid having the working directory inserted into the symbol table. - // It is added with a name to avoid problems with external linking - // encountered on some versions of Solaris. See issue #14957. - putelfsyment(ctxt.Out, putelfstr("go.go"), 0, 0, STB_LOCAL<<4|STT_FILE, SHN_ABS, 0) - ctxt.numelfsym++ - - ctxt.elfbind = STB_LOCAL - genasmsym(ctxt, putelfsym2) - - ctxt.elfbind = STB_GLOBAL - elfglobalsymndx = ctxt.numelfsym - genasmsym(ctxt, putelfsym2) -} - -func putelfsectionsym2(ctxt *Link, out *OutBuf, s *sym.Symbol, shndx int) { - putelfsyment(out, 0, 0, 0, STB_LOCAL<<4|STT_SECTION, shndx, 0) - ctxt.loader.SetSymElfSym(loader.Sym(s.SymIdx), int32(ctxt.numelfsym)) - ctxt.numelfsym++ -} - -func putelfsym2(ctxt *Link, x *sym.Symbol, s string, t SymbolType, addr int64) { - var typ int - - switch t { - default: - return - - case TextSym: - typ = STT_FUNC - - case DataSym, BSSSym: - typ = STT_OBJECT - - case UndefinedSym: - // ElfType is only set for symbols read from Go shared libraries, but - // for other symbols it is left as STT_NOTYPE which is fine. - typ = int(x.ElfType()) - - case TLSSym: - typ = STT_TLS - } - - size := x.Size - if t == UndefinedSym { - size = 0 - } - - xo := x - if xo.Outer != nil { - xo = xo.Outer - } - - var elfshnum int - if xo.Type == sym.SDYNIMPORT || xo.Type == sym.SHOSTOBJ || xo.Type == sym.SUNDEFEXT { - elfshnum = SHN_UNDEF - } else { - if xo.Sect == nil { - Errorf(x, "missing section in putelfsym") - return - } - if xo.Sect.Elfsect == nil { - Errorf(x, "missing ELF section in putelfsym") - return - } - 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.IsFileLocal() || x.Attr.VisibilityHidden() || x.Attr.Local() { - bind = STB_LOCAL - } - - // In external linking mode, we have to invoke gcc with -rdynamic - // to get the exported symbols put into the dynamic symbol table. - // To avoid filling the dynamic table with lots of unnecessary symbols, - // mark all Go symbols local (not global) in the final executable. - // But when we're dynamically linking, we need all those global symbols. - if !ctxt.DynlinkingGo() && ctxt.LinkMode == LinkExternal && !x.Attr.CgoExportStatic() && elfshnum != SHN_UNDEF { - bind = STB_LOCAL - } - - if ctxt.LinkMode == LinkExternal && elfshnum != SHN_UNDEF { - addr -= int64(xo.Sect.Vaddr) - } - other := STV_DEFAULT - if x.Attr.VisibilityHidden() { - // TODO(mwhudson): We only set AttrVisibilityHidden in ldelf, i.e. when - // internally linking. But STV_HIDDEN visibility only matters in object - // files and shared libraries, and as we are a long way from implementing - // internal linking for shared libraries and only create object files when - // externally linking, I don't think this makes a lot of sense. - other = STV_HIDDEN - } - if ctxt.Arch.Family == sys.PPC64 && typ == STT_FUNC && x.Attr.Shared() && x.Name != "runtime.duffzero" && x.Name != "runtime.duffcopy" { - // On ppc64 the top three bits of the st_other field indicate how - // many instructions separate the global and local entry points. In - // our case it is two instructions, indicated by the value 3. - // The conditions here match those in preprocess in - // cmd/internal/obj/ppc64/obj9.go, which is where the - // instructions are inserted. - other |= 3 << 5 - } - - if s == x.Name { - // We should use Extname for ELF symbol table. - // TODO: maybe genasmsym should have done this. That function is too - // overloaded and I would rather not change it for now. - s = x.Extname() - } - - // When dynamically linking, we create Symbols by reading the names from - // the symbol tables of the shared libraries and so the names need to - // match exactly. Tools like DTrace will have to wait for now. - if !ctxt.DynlinkingGo() { - // Rewrite · to . for ASCII-only tools like DTrace (sigh) - s = strings.Replace(s, "·", ".", -1) - } - - if ctxt.DynlinkingGo() && bind == STB_GLOBAL && ctxt.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 - // (*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) - ctxt.loader.SetSymLocalElfSym(loader.Sym(x.SymIdx), int32(ctxt.numelfsym)) - ctxt.numelfsym++ - return - } else if bind != ctxt.elfbind { - return - } - - putelfsyment(ctxt.Out, putelfstr(s), addr, size, bind<<4|typ&0xf, elfshnum, other) - ctxt.loader.SetSymElfSym(loader.Sym(x.SymIdx), int32(ctxt.numelfsym)) - ctxt.numelfsym++ -} diff --git a/src/cmd/link/internal/ld/xcoff2.go b/src/cmd/link/internal/ld/xcoff2.go deleted file mode 100644 index 27edbcb22d..0000000000 --- a/src/cmd/link/internal/ld/xcoff2.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2020 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 ld - -import ( - "cmd/internal/objabi" - "cmd/link/internal/loader" - "cmd/link/internal/sym" -) - -// Temporary dumping around for sym.Symbol version of helper -// functions in xcoff.go, still being used for some archs/oses. -// FIXME: get rid of this file when dodata() is completely -// converted. - -// xcoffUpdateOuterSize stores the size of outer symbols in order to have it -// in the symbol table. -func xcoffUpdateOuterSize(ctxt *Link, size int64, stype sym.SymKind) { - if size == 0 { - return - } - - switch stype { - default: - Errorf(nil, "unknown XCOFF outer symbol for type %s", stype.String()) - case sym.SRODATA, sym.SRODATARELRO, sym.SFUNCTAB, sym.SSTRING: - // Nothing to do - case sym.STYPERELRO: - if ctxt.UseRelro() && (ctxt.BuildMode == BuildModeCArchive || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE) { - // runtime.types size must be removed, as it's a real symbol. - outerSymSize["typerel.*"] = size - ctxt.Syms.ROLookup("runtime.types", 0).Size - return - } - fallthrough - case sym.STYPE: - if !ctxt.DynlinkingGo() { - // runtime.types size must be removed, as it's a real symbol. - outerSymSize["type.*"] = size - ctxt.Syms.ROLookup("runtime.types", 0).Size - } - case sym.SGOSTRING: - outerSymSize["go.string.*"] = size - case sym.SGOFUNC: - if !ctxt.DynlinkingGo() { - outerSymSize["go.func.*"] = size - } - case sym.SGOFUNCRELRO: - outerSymSize["go.funcrel.*"] = size - case sym.SGCBITS: - outerSymSize["runtime.gcbits.*"] = size - case sym.SITABLINK: - outerSymSize["runtime.itablink"] = size - - } -} - -// Xcoffadddynrel adds a dynamic relocation in a XCOFF file. -// This relocation will be made by the loader. -func Xcoffadddynrel(target *Target, ldr *loader.Loader, s *sym.Symbol, r *sym.Reloc) bool { - if target.IsExternal() { - return true - } - if s.Type <= sym.SPCLNTAB { - Errorf(s, "cannot have a relocation to %s in a text section symbol", r.Sym.Name) - return false - } - - xldr := &xcoffLoaderReloc{ - sym: s, - roff: r.Off, - } - - switch r.Type { - default: - Errorf(s, "unexpected .loader relocation to symbol: %s (type: %s)", r.Sym.Name, r.Type.String()) - return false - case objabi.R_ADDR: - if s.Type == sym.SXCOFFTOC && r.Sym.Type == sym.SDYNIMPORT { - // Imported symbol relocation - for i, dynsym := range xfile.loaderSymbols { - if ldr.Syms[dynsym.sym].Name == r.Sym.Name { - xldr.symndx = int32(i + 3) // +3 because of 3 section symbols - break - } - } - } else if s.Type == sym.SDATA || s.Type == sym.SNOPTRDATA || s.Type == sym.SBUILDINFO || s.Type == sym.SXCOFFTOC { - switch r.Sym.Sect.Seg { - default: - Errorf(s, "unknown segment for .loader relocation with symbol %s", r.Sym.Name) - case &Segtext: - case &Segrodata: - xldr.symndx = 0 // .text - case &Segdata: - if r.Sym.Type == sym.SBSS || r.Sym.Type == sym.SNOPTRBSS { - xldr.symndx = 2 // .bss - } else { - xldr.symndx = 1 // .data - } - - } - - } else { - Errorf(s, "unexpected type for .loader relocation R_ADDR for symbol %s: %s to %s", r.Sym.Name, s.Type, r.Sym.Type) - return false - } - - xldr.rtype = 0x3F<<8 + XCOFF_R_POS - } - - xfile.loaderReloc = append(xfile.loaderReloc, xldr) - return true -} diff --git a/src/cmd/link/internal/mips/asm.go b/src/cmd/link/internal/mips/asm.go index 67b3726271..49002c6dd5 100644 --- a/src/cmd/link/internal/mips/asm.go +++ b/src/cmd/link/internal/mips/asm.go @@ -51,15 +51,15 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s *sym. return false } -func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { +func elfreloc2(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool { ctxt.Out.Write32(uint32(sectoff)) - elfsym := ld.ElfSymForReloc(ctxt, r.Xsym) - switch r.Type { + elfsym := ld.ElfSymForReloc2(ctxt, r.Xsym) + switch r.Type() { default: return false case objabi.R_ADDR, objabi.R_DWARFSECREF: - if r.Siz != 4 { + if r.Siz() != 4 { return false } ctxt.Out.Write32(uint32(elf.R_MIPS_32) | uint32(elfsym)<<8) diff --git a/src/cmd/link/internal/mips/obj.go b/src/cmd/link/internal/mips/obj.go index b646adaf40..7fc14638e5 100644 --- a/src/cmd/link/internal/mips/obj.go +++ b/src/cmd/link/internal/mips/obj.go @@ -55,7 +55,7 @@ func Init() (*sys.Arch, ld.Arch) { Archrelocvariant: archrelocvariant, Asmb: asmb, Asmb2: asmb2, - Elfreloc1: elfreloc1, + Elfreloc2: elfreloc2, Elfsetupplt: elfsetupplt, Gentext2: gentext2, Machoreloc1: machoreloc1, diff --git a/src/cmd/link/internal/mips64/asm.go b/src/cmd/link/internal/mips64/asm.go index 479157cb50..3834d74c66 100644 --- a/src/cmd/link/internal/mips64/asm.go +++ b/src/cmd/link/internal/mips64/asm.go @@ -49,7 +49,8 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s *sym. return false } -func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { +func elfreloc2(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool { + // mips64 ELF relocation (endian neutral) // offset uint64 // sym uint32 @@ -61,16 +62,16 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ctxt.Out.Write64(uint64(sectoff)) - elfsym := ld.ElfSymForReloc(ctxt, r.Xsym) + elfsym := ld.ElfSymForReloc2(ctxt, r.Xsym) ctxt.Out.Write32(uint32(elfsym)) ctxt.Out.Write8(0) ctxt.Out.Write8(0) ctxt.Out.Write8(0) - switch r.Type { + switch r.Type() { default: return false case objabi.R_ADDR, objabi.R_DWARFSECREF: - switch r.Siz { + switch r.Siz() { case 4: ctxt.Out.Write8(uint8(elf.R_MIPS_32)) case 8: diff --git a/src/cmd/link/internal/mips64/obj.go b/src/cmd/link/internal/mips64/obj.go index b5f7ae1405..e56e31f222 100644 --- a/src/cmd/link/internal/mips64/obj.go +++ b/src/cmd/link/internal/mips64/obj.go @@ -54,7 +54,7 @@ func Init() (*sys.Arch, ld.Arch) { Archrelocvariant: archrelocvariant, Asmb: asmb, Asmb2: asmb2, - Elfreloc1: elfreloc1, + Elfreloc2: elfreloc2, Elfsetupplt: elfsetupplt, Gentext2: gentext2, Machoreloc1: machoreloc1, diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go index 7e08e534b3..5d4157c200 100644 --- a/src/cmd/link/internal/ppc64/asm.go +++ b/src/cmd/link/internal/ppc64/asm.go @@ -442,9 +442,10 @@ func xcoffreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se } -func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { +func elfreloc2(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool { // Beware that bit0~bit15 start from the third byte of a instruction in Big-Endian machines. - if r.Type == objabi.R_ADDR || r.Type == objabi.R_POWER_TLS || r.Type == objabi.R_CALLPOWER { + rt := r.Type() + if rt == objabi.R_ADDR || rt == objabi.R_POWER_TLS || rt == objabi.R_CALLPOWER { } else { if ctxt.Arch.ByteOrder == binary.BigEndian { sectoff += 2 @@ -452,12 +453,12 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { } ctxt.Out.Write64(uint64(sectoff)) - elfsym := ld.ElfSymForReloc(ctxt, r.Xsym) - switch r.Type { + elfsym := ld.ElfSymForReloc2(ctxt, r.Xsym) + switch rt { default: return false case objabi.R_ADDR, objabi.R_DWARFSECREF: - switch r.Siz { + switch r.Siz() { case 4: ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR32) | uint64(elfsym)<<32) case 8: @@ -506,7 +507,7 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ctxt.Out.Write64(uint64(sectoff + 4)) ctxt.Out.Write64(uint64(elf.R_PPC64_TOC16_LO_DS) | uint64(elfsym)<<32) case objabi.R_CALLPOWER: - if r.Siz != 4 { + if r.Siz() != 4 { return false } ctxt.Out.Write64(uint64(elf.R_PPC64_REL24) | uint64(elfsym)<<32) diff --git a/src/cmd/link/internal/ppc64/obj.go b/src/cmd/link/internal/ppc64/obj.go index 67002bc719..ffd07d62bd 100644 --- a/src/cmd/link/internal/ppc64/obj.go +++ b/src/cmd/link/internal/ppc64/obj.go @@ -55,7 +55,7 @@ func Init() (*sys.Arch, ld.Arch) { Archrelocvariant: archrelocvariant, Asmb: asmb, Asmb2: asmb2, - Elfreloc1: elfreloc1, + Elfreloc2: elfreloc2, Elfsetupplt: elfsetupplt, Gentext2: gentext2, Trampoline: trampoline, diff --git a/src/cmd/link/internal/riscv64/asm.go b/src/cmd/link/internal/riscv64/asm.go index f76a42b1c0..cd4cd1015d 100644 --- a/src/cmd/link/internal/riscv64/asm.go +++ b/src/cmd/link/internal/riscv64/asm.go @@ -28,8 +28,8 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s *sym. return false } -func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { - log.Fatalf("elfreloc1") +func elfreloc2(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool { + log.Fatalf("elfreloc2") return false } diff --git a/src/cmd/link/internal/riscv64/obj.go b/src/cmd/link/internal/riscv64/obj.go index 4fa0ebe79a..a46b6cefb9 100644 --- a/src/cmd/link/internal/riscv64/obj.go +++ b/src/cmd/link/internal/riscv64/obj.go @@ -26,7 +26,7 @@ func Init() (*sys.Arch, ld.Arch) { Archrelocvariant: archrelocvariant, Asmb: asmb, Asmb2: asmb2, - Elfreloc1: elfreloc1, + Elfreloc2: elfreloc2, Elfsetupplt: elfsetupplt, Gentext2: gentext2, Machoreloc1: machoreloc1, diff --git a/src/cmd/link/internal/s390x/asm.go b/src/cmd/link/internal/s390x/asm.go index 3e7b1ffb14..8c91dd724a 100644 --- a/src/cmd/link/internal/s390x/asm.go +++ b/src/cmd/link/internal/s390x/asm.go @@ -221,15 +221,17 @@ func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s load return false } -func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { +func elfreloc2(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool { ctxt.Out.Write64(uint64(sectoff)) - elfsym := ld.ElfSymForReloc(ctxt, r.Xsym) - switch r.Type { + elfsym := ld.ElfSymForReloc2(ctxt, r.Xsym) + siz := r.Siz() + xst := ldr.SymType(r.Xsym) + switch r.Type() { default: return false case objabi.R_TLS_LE: - switch r.Siz { + switch siz { default: return false case 4: @@ -240,14 +242,14 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ctxt.Out.Write64(uint64(elf.R_390_TLS_LE64) | uint64(elfsym)<<32) } case objabi.R_TLS_IE: - switch r.Siz { + switch siz { default: return false case 4: ctxt.Out.Write64(uint64(elf.R_390_TLS_IEENT) | uint64(elfsym)<<32) } case objabi.R_ADDR, objabi.R_DWARFSECREF: - switch r.Siz { + switch siz { default: return false case 4: @@ -256,30 +258,31 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ctxt.Out.Write64(uint64(elf.R_390_64) | uint64(elfsym)<<32) } case objabi.R_GOTPCREL: - if r.Siz == 4 { + if siz == 4 { ctxt.Out.Write64(uint64(elf.R_390_GOTENT) | uint64(elfsym)<<32) } else { return false } case objabi.R_PCREL, objabi.R_PCRELDBL, objabi.R_CALL: elfrel := elf.R_390_NONE - isdbl := r.Variant&sym.RV_TYPE_MASK == sym.RV_390_DBL + rVariant := ldr.RelocVariant(s, r.Idx) + isdbl := rVariant&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 { + switch r.Type() { case objabi.R_PCRELDBL, objabi.R_CALL: isdbl = true } - if r.Xsym.Type == sym.SDYNIMPORT && (r.Xsym.ElfType() == elf.STT_FUNC || r.Type == objabi.R_CALL) { + if xst == sym.SDYNIMPORT && (ldr.SymElfType(r.Xsym) == elf.STT_FUNC || r.Type() == objabi.R_CALL) { if isdbl { - switch r.Siz { + switch siz { case 2: elfrel = elf.R_390_PLT16DBL case 4: elfrel = elf.R_390_PLT32DBL } } else { - switch r.Siz { + switch siz { case 4: elfrel = elf.R_390_PLT32 case 8: @@ -288,14 +291,14 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { } } else { if isdbl { - switch r.Siz { + switch siz { case 2: elfrel = elf.R_390_PC16DBL case 4: elfrel = elf.R_390_PC32DBL } } else { - switch r.Siz { + switch siz { case 2: elfrel = elf.R_390_PC16 case 4: diff --git a/src/cmd/link/internal/s390x/obj.go b/src/cmd/link/internal/s390x/obj.go index 9a480f118e..72da719ee4 100644 --- a/src/cmd/link/internal/s390x/obj.go +++ b/src/cmd/link/internal/s390x/obj.go @@ -52,7 +52,7 @@ func Init() (*sys.Arch, ld.Arch) { Archrelocvariant: archrelocvariant, Asmb: asmb, Asmb2: asmb2, - Elfreloc1: elfreloc1, + Elfreloc2: elfreloc2, Elfsetupplt: elfsetupplt, Gentext2: gentext2, Machoreloc1: machoreloc1, diff --git a/src/cmd/link/internal/x86/asm.go b/src/cmd/link/internal/x86/asm.go index 5858845475..a058bdb9b3 100644 --- a/src/cmd/link/internal/x86/asm.go +++ b/src/cmd/link/internal/x86/asm.go @@ -340,23 +340,24 @@ func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s load return false } -func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { +func elfreloc2(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool { ctxt.Out.Write32(uint32(sectoff)) - elfsym := ld.ElfSymForReloc(ctxt, r.Xsym) - switch r.Type { + elfsym := ld.ElfSymForReloc2(ctxt, r.Xsym) + siz := r.Siz() + switch r.Type() { default: return false case objabi.R_ADDR, objabi.R_DWARFSECREF: - if r.Siz == 4 { + if siz == 4 { ctxt.Out.Write32(uint32(elf.R_386_32) | uint32(elfsym)<<8) } else { return false } case objabi.R_GOTPCREL: - if r.Siz == 4 { + if siz == 4 { ctxt.Out.Write32(uint32(elf.R_386_GOTPC)) - if r.Xsym.Name != "_GLOBAL_OFFSET_TABLE_" { + if ldr.SymName(r.Xsym) != "_GLOBAL_OFFSET_TABLE_" { ctxt.Out.Write32(uint32(sectoff)) ctxt.Out.Write32(uint32(elf.R_386_GOT32) | uint32(elfsym)<<8) } @@ -364,8 +365,8 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { return false } case objabi.R_CALL: - if r.Siz == 4 { - if r.Xsym.Type == sym.SDYNIMPORT { + if siz == 4 { + if ldr.SymType(r.Xsym) == sym.SDYNIMPORT { ctxt.Out.Write32(uint32(elf.R_386_PLT32) | uint32(elfsym)<<8) } else { ctxt.Out.Write32(uint32(elf.R_386_PC32) | uint32(elfsym)<<8) @@ -374,19 +375,19 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { return false } case objabi.R_PCREL: - if r.Siz == 4 { + if siz == 4 { ctxt.Out.Write32(uint32(elf.R_386_PC32) | uint32(elfsym)<<8) } else { return false } case objabi.R_TLS_LE: - if r.Siz == 4 { + if siz == 4 { ctxt.Out.Write32(uint32(elf.R_386_TLS_LE) | uint32(elfsym)<<8) } else { return false } case objabi.R_TLS_IE: - if r.Siz == 4 { + if siz == 4 { ctxt.Out.Write32(uint32(elf.R_386_GOTPC)) ctxt.Out.Write32(uint32(sectoff)) ctxt.Out.Write32(uint32(elf.R_386_TLS_GOTIE) | uint32(elfsym)<<8) diff --git a/src/cmd/link/internal/x86/obj.go b/src/cmd/link/internal/x86/obj.go index 61e3077b5b..dc1a0021fa 100644 --- a/src/cmd/link/internal/x86/obj.go +++ b/src/cmd/link/internal/x86/obj.go @@ -52,7 +52,7 @@ func Init() (*sys.Arch, ld.Arch) { Archrelocvariant: archrelocvariant, Asmb: asmb, Asmb2: asmb2, - Elfreloc1: elfreloc1, + Elfreloc2: elfreloc2, Elfsetupplt: elfsetupplt, Gentext2: gentext2, Machoreloc1: machoreloc1, -- 2.48.1