diff options
| author | Cherry Zhang <cherryyz@google.com> | 2020-01-31 14:45:52 -0500 |
|---|---|---|
| committer | Cherry Zhang <cherryyz@google.com> | 2020-01-31 14:45:52 -0500 |
| commit | ee04d45b8f380c2e3b3b26bc4771cd97fbd9d260 (patch) | |
| tree | 5db2e0ca22bb7d54f7c6d8a8d4acc96224b2e85c /src/cmd/link/internal | |
| parent | 23c96e9bbd29e3a815e6faabbc40af0d4c4d4353 (diff) | |
| parent | 96002cd25c343edfb6c06d2bf1f31ae1e345b81f (diff) | |
| download | go-ee04d45b8f380c2e3b3b26bc4771cd97fbd9d260.tar.xz | |
[dev.link] all: merge branch 'master' into dev.link
It has been a while we have not done this.
Merge conflict resolution:
- deleted/rewritten code modified on master
- CL 214286, ported in CL 217317
(cmd/internal/obj/objfile.go)
- CL 210678, it already includes a fix to new code
(cmd/link/internal/ld/deadcode.go)
- CL 209317, applied in this CL
(cmd/link/internal/loadelf/ldelf.go)
Change-Id: Ie927ea6a1d69ce49e8d03e56148cb2725e377876
Diffstat (limited to 'src/cmd/link/internal')
| -rw-r--r-- | src/cmd/link/internal/ld/data.go | 46 | ||||
| -rw-r--r-- | src/cmd/link/internal/ld/deadcode2.go | 2 | ||||
| -rw-r--r-- | src/cmd/link/internal/ld/pcln.go | 7 | ||||
| -rw-r--r-- | src/cmd/link/internal/loadelf/ldelf.go | 65 |
4 files changed, 82 insertions, 38 deletions
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index 32d1111ea3..7ca01c8c25 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -1625,29 +1625,27 @@ func (ctxt *Link) dodata() { } if ctxt.UseRelro() { + segrelro := &Segrelrodata + if ctxt.LinkMode == LinkExternal && ctxt.HeadType != objabi.Haix { + // Using a separate segment with an external + // linker results in some programs moving + // their data sections unexpectedly, which + // corrupts the moduledata. So we use the + // rodata segment and let the external linker + // sort out a rel.ro segment. + segrelro = segro + } else { + // Reset datsize for new segment. + datsize = 0 + } + addrelrosection = func(suffix string) *sym.Section { - seg := &Segrelrodata - if ctxt.LinkMode == LinkExternal && ctxt.HeadType != objabi.Haix { - // Using a separate segment with an external - // linker results in some programs moving - // their data sections unexpectedly, which - // corrupts the moduledata. So we use the - // rodata segment and let the external linker - // sort out a rel.ro segment. - seg = &Segrodata - } - return addsection(ctxt.Arch, seg, ".data.rel.ro"+suffix, 06) + return addsection(ctxt.Arch, segrelro, ".data.rel.ro"+suffix, 06) } + /* data only written by relocations */ sect = addrelrosection("") - sect.Vaddr = 0 - if ctxt.HeadType == objabi.Haix { - // datsize must be reset because relro datas will end up - // in data segment. - datsize = 0 - } - ctxt.Syms.Lookup("runtime.types", 0).Sect = sect ctxt.Syms.Lookup("runtime.etypes", 0).Sect = sect @@ -1659,7 +1657,17 @@ func (ctxt *Link) dodata() { } } datsize = Rnd(datsize, int64(sect.Align)) - for _, symnro := range sym.ReadOnly { + sect.Vaddr = uint64(datsize) + + for i, symnro := range sym.ReadOnly { + if i == 0 && symnro == sym.STYPE && ctxt.HeadType != objabi.Haix { + // Skip forward so that no type + // reference uses a zero offset. + // This is unlikely but possible in small + // programs with no other read-only data. + datsize++ + } + symn := sym.RelROMap[symnro] symnStartValue := datsize for _, s := range data[symn] { diff --git a/src/cmd/link/internal/ld/deadcode2.go b/src/cmd/link/internal/ld/deadcode2.go index 915ad1d944..3d3a03215e 100644 --- a/src/cmd/link/internal/ld/deadcode2.go +++ b/src/cmd/link/internal/ld/deadcode2.go @@ -113,7 +113,7 @@ func (d *deadcodePass2) init() { } for _, name := range names { - // Mark symbol as an data/ABI0 symbol. + // Mark symbol as a data/ABI0 symbol. d.mark(d.ldr.Lookup(name, 0), 0) // Also mark any Go functions (internal ABI). d.mark(d.ldr.Lookup(name, sym.SymVerABIInternal), 0) diff --git a/src/cmd/link/internal/ld/pcln.go b/src/cmd/link/internal/ld/pcln.go index ab703e94ee..db44c0292e 100644 --- a/src/cmd/link/internal/ld/pcln.go +++ b/src/cmd/link/internal/ld/pcln.go @@ -266,8 +266,13 @@ func (ctxt *Link) pclntab() { switch ctxt.Arch.Family { case sys.AMD64, sys.I386: deferreturn-- - case sys.PPC64, sys.ARM, sys.ARM64, sys.MIPS, sys.MIPS64, sys.RISCV64: + case sys.PPC64, sys.ARM, sys.ARM64, sys.MIPS, sys.MIPS64: // no change + case sys.RISCV64: + // TODO(jsing): The JALR instruction is marked with + // R_CALLRISCV, whereas the actual reloc is currently + // one instruction earlier starting with the AUIPC. + deferreturn -= 4 case sys.S390X: deferreturn -= 2 default: diff --git a/src/cmd/link/internal/loadelf/ldelf.go b/src/cmd/link/internal/loadelf/ldelf.go index 7d613c7a6d..b1e420cc30 100644 --- a/src/cmd/link/internal/loadelf/ldelf.go +++ b/src/cmd/link/internal/loadelf/ldelf.go @@ -901,14 +901,26 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, p := rsect.base for j := 0; j < n; j++ { var add uint64 + var symIdx int + var relocType uint64 + rp := &r[j] - var info uint64 if is64 != 0 { // 64-bit rel/rela rp.Off = int32(e.Uint64(p)) p = p[8:] - info = e.Uint64(p) + switch arch.Family { + case sys.MIPS64: + // https://www.linux-mips.org/pub/linux/mips/doc/ABI/elf64-2.4.pdf + // The doc shows it's different with general Linux ELF + symIdx = int(e.Uint32(p)) + relocType = uint64(p[7]) + default: + info := e.Uint64(p) + relocType = info & 0xffffffff + symIdx = int(info >> 32) + } p = p[8:] if rela != 0 { add = e.Uint64(p) @@ -919,8 +931,9 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, rp.Off = int32(e.Uint32(p)) p = p[4:] - info = uint64(e.Uint32(p)) - info = info>>8<<32 | info&0xff // convert to 64-bit info + info := e.Uint32(p) + relocType = uint64(info & 0xff) + symIdx = int(info >> 8) p = p[4:] if rela != 0 { add = uint64(e.Uint32(p)) @@ -928,29 +941,29 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, } } - if info&0xffffffff == 0 { // skip R_*_NONE relocation + if relocType == 0 { // skip R_*_NONE relocation j-- n-- continue } - if info>>32 == 0 { // absolute relocation, don't bother reading the null symbol + if symIdx == 0 { // absolute relocation, don't bother reading the null symbol rp.Sym = 0 } else { var elfsym ElfSym - if err := readelfsym(newSym, lookup, l, arch, elfobj, int(info>>32), &elfsym, 0, 0); err != nil { + if err := readelfsym(newSym, lookup, l, arch, elfobj, int(symIdx), &elfsym, 0, 0); err != nil { return errorf("malformed elf file: %v", err) } - elfsym.sym = symbols[info>>32] + elfsym.sym = symbols[symIdx] if elfsym.sym == 0 { - return errorf("malformed elf file: %s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", l.SymName(sect.sym), j, int(info>>32), elfsym.name, elfsym.shndx, elfsym.type_) + return errorf("malformed elf file: %s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", l.SymName(sect.sym), j, int(symIdx), elfsym.name, elfsym.shndx, elfsym.type_) } rp.Sym = elfsym.sym } - rp.Type = objabi.ElfRelocOffset + objabi.RelocType(info) - rp.Size, err = relSize(arch, pn, uint32(info)) + rp.Type = objabi.ElfRelocOffset + objabi.RelocType(relocType) + rp.Size, err = relSize(arch, pn, uint32(relocType)) if err != nil { return nil, 0, err } @@ -1148,18 +1161,36 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) { // performance. const ( - AMD64 = uint32(sys.AMD64) - ARM = uint32(sys.ARM) - ARM64 = uint32(sys.ARM64) - I386 = uint32(sys.I386) - PPC64 = uint32(sys.PPC64) - S390X = uint32(sys.S390X) + AMD64 = uint32(sys.AMD64) + ARM = uint32(sys.ARM) + ARM64 = uint32(sys.ARM64) + I386 = uint32(sys.I386) + PPC64 = uint32(sys.PPC64) + S390X = uint32(sys.S390X) + MIPS = uint32(sys.MIPS) + MIPS64 = uint32(sys.MIPS64) ) switch uint32(arch.Family) | elftype<<16 { default: return 0, fmt.Errorf("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype) + case MIPS | uint32(elf.R_MIPS_HI16)<<16, + MIPS | uint32(elf.R_MIPS_LO16)<<16, + MIPS | uint32(elf.R_MIPS_GOT16)<<16, + MIPS | uint32(elf.R_MIPS_GPREL16)<<16, + MIPS | uint32(elf.R_MIPS_GOT_PAGE)<<16, + MIPS | uint32(elf.R_MIPS_JALR)<<16, + MIPS | uint32(elf.R_MIPS_GOT_OFST)<<16, + MIPS64 | uint32(elf.R_MIPS_HI16)<<16, + MIPS64 | uint32(elf.R_MIPS_LO16)<<16, + MIPS64 | uint32(elf.R_MIPS_GOT16)<<16, + MIPS64 | uint32(elf.R_MIPS_GPREL16)<<16, + MIPS64 | uint32(elf.R_MIPS_GOT_PAGE)<<16, + MIPS64 | uint32(elf.R_MIPS_JALR)<<16, + MIPS64 | uint32(elf.R_MIPS_GOT_OFST)<<16: + return 4, nil + case S390X | uint32(elf.R_390_8)<<16: return 1, nil |
