diff options
Diffstat (limited to 'src/cmd/oldlink/internal/riscv64/asm.go')
| -rw-r--r-- | src/cmd/oldlink/internal/riscv64/asm.go | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/src/cmd/oldlink/internal/riscv64/asm.go b/src/cmd/oldlink/internal/riscv64/asm.go new file mode 100644 index 0000000000..f4db32df8a --- /dev/null +++ b/src/cmd/oldlink/internal/riscv64/asm.go @@ -0,0 +1,168 @@ +// Copyright 2019 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 riscv64 + +import ( + "cmd/internal/obj/riscv" + "cmd/internal/objabi" + "cmd/internal/sys" + "cmd/oldlink/internal/ld" + "cmd/oldlink/internal/sym" + "fmt" + "log" +) + +func gentext(ctxt *ld.Link) { +} + +func adddynrela(ctxt *ld.Link, rel *sym.Symbol, s *sym.Symbol, r *sym.Reloc) { + log.Fatalf("adddynrela not implemented") +} + +func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { + log.Fatalf("adddynrel not implemented") + return false +} + +func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { + log.Fatalf("elfreloc1") + return false +} + +func elfsetupplt(ctxt *ld.Link) { + log.Fatalf("elfsetuplt") +} + +func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { + log.Fatalf("machoreloc1 not implemented") + return false +} + +func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) { + switch r.Type { + case objabi.R_CALLRISCV: + // Nothing to do. + return val, true + + case objabi.R_RISCV_PCREL_ITYPE, objabi.R_RISCV_PCREL_STYPE: + pc := s.Value + int64(r.Off) + off := ld.Symaddr(r.Sym) + r.Add - pc + + // Generate AUIPC and second instruction immediates. + low, high, err := riscv.Split32BitImmediate(off) + if err != nil { + ld.Errorf(s, "R_RISCV_PCREL_ relocation does not fit in 32-bits: %d", off) + } + + auipcImm, err := riscv.EncodeUImmediate(high) + if err != nil { + ld.Errorf(s, "cannot encode R_RISCV_PCREL_ AUIPC relocation offset for %s: %v", r.Sym.Name, err) + } + + var secondImm, secondImmMask int64 + switch r.Type { + case objabi.R_RISCV_PCREL_ITYPE: + secondImmMask = riscv.ITypeImmMask + secondImm, err = riscv.EncodeIImmediate(low) + if err != nil { + ld.Errorf(s, "cannot encode R_RISCV_PCREL_ITYPE I-type instruction relocation offset for %s: %v", r.Sym.Name, err) + } + case objabi.R_RISCV_PCREL_STYPE: + secondImmMask = riscv.STypeImmMask + secondImm, err = riscv.EncodeSImmediate(low) + if err != nil { + ld.Errorf(s, "cannot encode R_RISCV_PCREL_STYPE S-type instruction relocation offset for %s: %v", r.Sym.Name, err) + } + default: + panic(fmt.Sprintf("Unknown relocation type: %v", r.Type)) + } + + auipc := int64(uint32(val)) + second := int64(uint32(val >> 32)) + + auipc = (auipc &^ riscv.UTypeImmMask) | int64(uint32(auipcImm)) + second = (second &^ secondImmMask) | int64(uint32(secondImm)) + + return second<<32 | auipc, true + } + + return val, false +} + +func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { + log.Fatalf("archrelocvariant") + return -1 +} + +func asmb(ctxt *ld.Link) { + if ctxt.IsELF { + ld.Asmbelfsetup() + } + + 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)) + } + + if ld.Segrodata.Filelen > 0 { + ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff)) + ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(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)) + } + + ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff)) + ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen)) + + ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff)) + ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen)) +} + +func asmb2(ctxt *ld.Link) { + ld.Symsize = 0 + ld.Lcsize = 0 + symo := uint32(0) + + if !*ld.FlagS { + if !ctxt.IsELF { + ld.Errorf(nil, "unsupported executable format") + } + + symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen) + symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound))) + ctxt.Out.SeekSet(int64(symo)) + + ld.Asmelfsym(ctxt) + ctxt.Out.Flush() + ctxt.Out.Write(ld.Elfstrdat) + + if ctxt.LinkMode == ld.LinkExternal { + ld.Elfemitreloc(ctxt) + } + } + + ctxt.Out.SeekSet(0) + switch ctxt.HeadType { + case objabi.Hlinux: + ld.Asmbelf(ctxt, int64(symo)) + default: + ld.Errorf(nil, "unsupported operating system") + } + ctxt.Out.Flush() + + if *ld.FlagC { + fmt.Printf("textsize=%d\n", ld.Segtext.Filelen) + fmt.Printf("datsize=%d\n", ld.Segdata.Filelen) + fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen) + fmt.Printf("symsize=%d\n", ld.Symsize) + fmt.Printf("lcsize=%d\n", ld.Lcsize) + fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize)) + } +} |
