summaryrefslogtreecommitdiff
path: root/src/cmd/oldlink/internal/riscv64/asm.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/oldlink/internal/riscv64/asm.go')
-rw-r--r--src/cmd/oldlink/internal/riscv64/asm.go168
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))
+ }
+}