diff options
Diffstat (limited to 'src/cmd/link/internal/s390x/asm.go')
-rw-r--r-- | src/cmd/link/internal/s390x/asm.go | 110 |
1 files changed, 55 insertions, 55 deletions
diff --git a/src/cmd/link/internal/s390x/asm.go b/src/cmd/link/internal/s390x/asm.go index 94a5a2f86c..7750da21cd 100644 --- a/src/cmd/link/internal/s390x/asm.go +++ b/src/cmd/link/internal/s390x/asm.go @@ -34,9 +34,11 @@ import ( "cmd/internal/objabi" "cmd/internal/sys" "cmd/link/internal/ld" + "cmd/link/internal/loader" "cmd/link/internal/sym" "debug/elf" "fmt" + "sync" ) // gentext generates assembly to append the local moduledata to the global @@ -104,7 +106,7 @@ func gentext(ctxt *ld.Link) { initarray_entry.AddAddr(ctxt.Arch, initfunc) } -func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { +func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { targ := r.Sym r.InitExt() @@ -158,8 +160,8 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { r.Variant = sym.RV_390_DBL r.Add += int64(r.Siz) if targ.Type == sym.SDYNIMPORT { - addpltsym(ctxt, targ) - r.Sym = ctxt.Syms.Lookup(".plt", 0) + addpltsym(target, syms, targ) + r.Sym = syms.PLT r.Add += int64(targ.Plt()) } return true @@ -169,8 +171,8 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { r.Type = objabi.R_PCREL r.Add += int64(r.Siz) if targ.Type == sym.SDYNIMPORT { - addpltsym(ctxt, targ) - r.Sym = ctxt.Syms.Lookup(".plt", 0) + addpltsym(target, syms, targ) + r.Sym = syms.PLT r.Add += int64(targ.Plt()) } return true @@ -200,7 +202,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTPC): r.Type = objabi.R_PCREL - r.Sym = ctxt.Syms.Lookup(".got", 0) + r.Sym = syms.GOT r.Add += int64(r.Siz) return true @@ -217,16 +219,16 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTPCDBL): r.Type = objabi.R_PCREL r.Variant = sym.RV_390_DBL - r.Sym = ctxt.Syms.Lookup(".got", 0) + r.Sym = syms.GOT r.Add += int64(r.Siz) return true case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTENT): - addgotsym(ctxt, targ) + addgotsym(target, syms, targ) r.Type = objabi.R_PCREL r.Variant = sym.RV_390_DBL - r.Sym = ctxt.Syms.Lookup(".got", 0) + r.Sym = syms.GOT r.Add += int64(targ.Got()) r.Add += int64(r.Siz) return true @@ -333,10 +335,8 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { return true } -func elfsetupplt(ctxt *ld.Link) { - plt := ctxt.Syms.Lookup(".plt", 0) - got := ctxt.Syms.Lookup(".got", 0) - if plt.Size == 0 { +func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.Sym) { + if plt.Size() == 0 { // stg %r1,56(%r15) plt.AddUint8(0xe3) plt.AddUint8(0x10) @@ -347,7 +347,7 @@ func elfsetupplt(ctxt *ld.Link) { // larl %r1,_GLOBAL_OFFSET_TABLE_ plt.AddUint8(0xc0) plt.AddUint8(0x10) - plt.AddPCRelPlus(ctxt.Arch, got, 6) + plt.AddSymRef(ctxt.Arch, got.Sym(), 6, objabi.R_PCRELDBL, 4) // mvc 48(8,%r15),8(%r1) plt.AddUint8(0xd2) plt.AddUint8(0x07) @@ -376,7 +376,7 @@ func elfsetupplt(ctxt *ld.Link) { plt.AddUint8(0x00) // assume got->size == 0 too - got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0) + got.AddAddrPlus(ctxt.Arch, dynamic, 0) got.AddUint64(ctxt.Arch, 0) got.AddUint64(ctxt.Arch, 0) @@ -387,8 +387,8 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se return false } -func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) { - if ctxt.LinkMode == ld.LinkExternal { +func archreloc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) { + if target.IsExternal() { return val, false } @@ -396,13 +396,13 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo case objabi.R_CONST: return r.Add, true case objabi.R_GOTOFF: - return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true + return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(syms.GOT), true } return val, false } -func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { +func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 { switch r.Variant & sym.RV_TYPE_MASK { default: ld.Errorf(s, "unexpected relocation variant %d", r.Variant) @@ -419,28 +419,28 @@ func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 } } -func addpltsym(ctxt *ld.Link, s *sym.Symbol) { +func addpltsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) { if s.Plt() >= 0 { return } - ld.Adddynsym(ctxt, s) + ld.Adddynsym(target, syms, s) - if ctxt.IsELF { - plt := ctxt.Syms.Lookup(".plt", 0) - got := ctxt.Syms.Lookup(".got", 0) - rela := ctxt.Syms.Lookup(".rela.plt", 0) + if target.IsElf() { + plt := syms.PLT + got := syms.GOT + rela := syms.RelaPLT if plt.Size == 0 { - elfsetupplt(ctxt) + panic("plt is not set up") } // larl %r1,_GLOBAL_OFFSET_TABLE_+index plt.AddUint8(0xc0) plt.AddUint8(0x10) - plt.AddPCRelPlus(ctxt.Arch, got, got.Size+6) // need variant? + plt.AddPCRelPlus(target.Arch, got, got.Size+6) // need variant? // add to got: pointer to current pos in plt - got.AddAddrPlus(ctxt.Arch, plt, plt.Size+8) // weird but correct + got.AddAddrPlus(target.Arch, plt, plt.Size+8) // weird but correct // lg %r1,0(%r1) plt.AddUint8(0xe3) plt.AddUint8(0x10) @@ -465,15 +465,15 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) { plt.AddUint8(0xc0) plt.AddUint8(0xf4) - plt.AddUint32(ctxt.Arch, uint32(-((plt.Size - 2) >> 1))) // roll-your-own relocation + plt.AddUint32(target.Arch, uint32(-((plt.Size - 2) >> 1))) // roll-your-own relocation //.plt index - plt.AddUint32(ctxt.Arch, uint32(rela.Size)) // rela size before current entry + plt.AddUint32(target.Arch, uint32(rela.Size)) // rela size before current entry // rela - rela.AddAddrPlus(ctxt.Arch, got, got.Size-8) + rela.AddAddrPlus(target.Arch, got, got.Size-8) - rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_JMP_SLOT))) - rela.AddUint64(ctxt.Arch, 0) + rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_JMP_SLOT))) + rela.AddUint64(target.Arch, 0) s.SetPlt(int32(plt.Size - 32)) @@ -482,21 +482,21 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) { } } -func addgotsym(ctxt *ld.Link, s *sym.Symbol) { +func addgotsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) { if s.Got() >= 0 { return } - ld.Adddynsym(ctxt, s) - got := ctxt.Syms.Lookup(".got", 0) + ld.Adddynsym(target, syms, s) + got := syms.GOT s.SetGot(int32(got.Size)) - got.AddUint64(ctxt.Arch, 0) + got.AddUint64(target.Arch, 0) - if ctxt.IsELF { - rela := ctxt.Syms.Lookup(".rela", 0) - rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got())) - rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_GLOB_DAT))) - rela.AddUint64(ctxt.Arch, 0) + if target.IsElf() { + rela := syms.Rela + rela.AddAddrPlus(target.Arch, got, int64(s.Got())) + rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_GLOB_DAT))) + rela.AddUint64(target.Arch, 0) } else { ld.Errorf(s, "addgotsym: unsupported binary format") } @@ -507,28 +507,28 @@ func asmb(ctxt *ld.Link) { ld.Asmbelfsetup() } + var wg sync.WaitGroup sect := ld.Segtext.Sections[0] - ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff)) - ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length)) - for _, sect = range ld.Segtext.Sections[1:] { - ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff)) - ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length)) + offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff + ld.WriteParallel(&wg, ld.Codeblk, ctxt, offset, sect.Vaddr, sect.Length) + + for _, sect := range ld.Segtext.Sections[1:] { + offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff + ld.WriteParallel(&wg, ld.Datblk, ctxt, offset, sect.Vaddr, sect.Length) } if ld.Segrodata.Filelen > 0 { - ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff)) - ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen)) + ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrodata.Fileoff, ld.Segrodata.Vaddr, ld.Segrodata.Filelen) } + if ld.Segrelrodata.Filelen > 0 { - ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff)) - ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen)) + ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrelrodata.Fileoff, ld.Segrelrodata.Vaddr, ld.Segrelrodata.Filelen) } - ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff)) - ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen)) + ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segdata.Fileoff, ld.Segdata.Vaddr, ld.Segdata.Filelen) - ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff)) - ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen)) + ld.WriteParallel(&wg, ld.Dwarfblk, ctxt, ld.Segdwarf.Fileoff, ld.Segdwarf.Vaddr, ld.Segdwarf.Filelen) + wg.Wait() } func asmb2(ctxt *ld.Link) { |