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)
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
Trampoline: trampoline,
Asmb: asmb,
Asmb2: asmb2,
- Elfreloc1: elfreloc1,
+ Elfreloc2: elfreloc2,
Elfsetupplt: elfsetupplt,
Gentext2: gentext2,
Machoreloc1: machoreloc1,
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:
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)
Archrelocvariant: archrelocvariant,
Asmb: asmb,
Asmb2: asmb2,
- Elfreloc1: elfreloc1,
+ Elfreloc2: elfreloc2,
Elfsetupplt: elfsetupplt,
Gentext2: gentext2,
Machoreloc1: machoreloc1,
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
}
}
-// 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.
}
func Elfemitreloc(ctxt *Link) {
- if !ctxt.IsAMD64() {
- Elfemitreloc2(ctxt)
- return
- }
for ctxt.Out.Offset()&7 != 0 {
ctxt.Out.Write8(0)
}
func Asmbelf(ctxt *Link, symo int64) {
- if !ctxt.IsAMD64() {
- Asmbelf2(ctxt, symo)
- return
- }
ldr := ctxt.loader
eh := getElfEhdr()
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.
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
-}
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)
+++ /dev/null
-// 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))
- }
-}
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.
}
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)
+++ /dev/null
-// 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++
-}
+++ /dev/null
-// 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
-}
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)
Archrelocvariant: archrelocvariant,
Asmb: asmb,
Asmb2: asmb2,
- Elfreloc1: elfreloc1,
+ Elfreloc2: elfreloc2,
Elfsetupplt: elfsetupplt,
Gentext2: gentext2,
Machoreloc1: machoreloc1,
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
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:
Archrelocvariant: archrelocvariant,
Asmb: asmb,
Asmb2: asmb2,
- Elfreloc1: elfreloc1,
+ Elfreloc2: elfreloc2,
Elfsetupplt: elfsetupplt,
Gentext2: gentext2,
Machoreloc1: machoreloc1,
}
-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
}
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:
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)
Archrelocvariant: archrelocvariant,
Asmb: asmb,
Asmb2: asmb2,
- Elfreloc1: elfreloc1,
+ Elfreloc2: elfreloc2,
Elfsetupplt: elfsetupplt,
Gentext2: gentext2,
Trampoline: trampoline,
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
}
Archrelocvariant: archrelocvariant,
Asmb: asmb,
Asmb2: asmb2,
- Elfreloc1: elfreloc1,
+ Elfreloc2: elfreloc2,
Elfsetupplt: elfsetupplt,
Gentext2: gentext2,
Machoreloc1: machoreloc1,
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:
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:
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:
}
} 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:
Archrelocvariant: archrelocvariant,
Asmb: asmb,
Asmb2: asmb2,
- Elfreloc1: elfreloc1,
+ Elfreloc2: elfreloc2,
Elfsetupplt: elfsetupplt,
Gentext2: gentext2,
Machoreloc1: machoreloc1,
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)
}
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)
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)
Archrelocvariant: archrelocvariant,
Asmb: asmb,
Asmb2: asmb2,
- Elfreloc1: elfreloc1,
+ Elfreloc2: elfreloc2,
Elfsetupplt: elfsetupplt,
Gentext2: gentext2,
Machoreloc1: machoreloc1,