github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/link/internal/riscv64/asm.go (about) 1 // Copyright 2019 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package riscv64 6 7 import ( 8 "github.com/gagliardetto/golang-go/cmd/internal/obj/riscv" 9 "github.com/gagliardetto/golang-go/cmd/internal/objabi" 10 "github.com/gagliardetto/golang-go/cmd/internal/sys" 11 "github.com/gagliardetto/golang-go/cmd/link/internal/ld" 12 "github.com/gagliardetto/golang-go/cmd/link/internal/sym" 13 "fmt" 14 "log" 15 ) 16 17 func gentext(ctxt *ld.Link) { 18 } 19 20 func adddynrela(ctxt *ld.Link, rel *sym.Symbol, s *sym.Symbol, r *sym.Reloc) { 21 log.Fatalf("adddynrela not implemented") 22 } 23 24 func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { 25 log.Fatalf("adddynrel not implemented") 26 return false 27 } 28 29 func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { 30 log.Fatalf("elfreloc1") 31 return false 32 } 33 34 func elfsetupplt(ctxt *ld.Link) { 35 log.Fatalf("elfsetuplt") 36 } 37 38 func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { 39 log.Fatalf("machoreloc1 not implemented") 40 return false 41 } 42 43 func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) { 44 switch r.Type { 45 case objabi.R_CALLRISCV: 46 // Nothing to do. 47 return val, true 48 49 case objabi.R_RISCV_PCREL_ITYPE, objabi.R_RISCV_PCREL_STYPE: 50 pc := s.Value + int64(r.Off) 51 off := ld.Symaddr(r.Sym) + r.Add - pc 52 53 // Generate AUIPC and second instruction immediates. 54 low, high, err := riscv.Split32BitImmediate(off) 55 if err != nil { 56 ld.Errorf(s, "R_RISCV_PCREL_ relocation does not fit in 32-bits: %d", off) 57 } 58 59 auipcImm, err := riscv.EncodeUImmediate(high) 60 if err != nil { 61 ld.Errorf(s, "cannot encode R_RISCV_PCREL_ AUIPC relocation offset for %s: %v", r.Sym.Name, err) 62 } 63 64 var secondImm, secondImmMask int64 65 switch r.Type { 66 case objabi.R_RISCV_PCREL_ITYPE: 67 secondImmMask = riscv.ITypeImmMask 68 secondImm, err = riscv.EncodeIImmediate(low) 69 if err != nil { 70 ld.Errorf(s, "cannot encode R_RISCV_PCREL_ITYPE I-type instruction relocation offset for %s: %v", r.Sym.Name, err) 71 } 72 case objabi.R_RISCV_PCREL_STYPE: 73 secondImmMask = riscv.STypeImmMask 74 secondImm, err = riscv.EncodeSImmediate(low) 75 if err != nil { 76 ld.Errorf(s, "cannot encode R_RISCV_PCREL_STYPE S-type instruction relocation offset for %s: %v", r.Sym.Name, err) 77 } 78 default: 79 panic(fmt.Sprintf("Unknown relocation type: %v", r.Type)) 80 } 81 82 auipc := int64(uint32(val)) 83 second := int64(uint32(val >> 32)) 84 85 auipc = (auipc &^ riscv.UTypeImmMask) | int64(uint32(auipcImm)) 86 second = (second &^ secondImmMask) | int64(uint32(secondImm)) 87 88 return second<<32 | auipc, true 89 } 90 91 return val, false 92 } 93 94 func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { 95 log.Fatalf("archrelocvariant") 96 return -1 97 } 98 99 func asmb(ctxt *ld.Link) { 100 if ctxt.IsELF { 101 ld.Asmbelfsetup() 102 } 103 104 sect := ld.Segtext.Sections[0] 105 ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff)) 106 ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length)) 107 for _, sect = range ld.Segtext.Sections[1:] { 108 ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff)) 109 ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length)) 110 } 111 112 if ld.Segrodata.Filelen > 0 { 113 ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff)) 114 ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen)) 115 } 116 if ld.Segrelrodata.Filelen > 0 { 117 ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff)) 118 ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen)) 119 } 120 121 ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff)) 122 ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen)) 123 124 ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff)) 125 ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen)) 126 } 127 128 func asmb2(ctxt *ld.Link) { 129 ld.Symsize = 0 130 ld.Lcsize = 0 131 symo := uint32(0) 132 133 if !*ld.FlagS { 134 if !ctxt.IsELF { 135 ld.Errorf(nil, "unsupported executable format") 136 } 137 138 symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen) 139 symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound))) 140 ctxt.Out.SeekSet(int64(symo)) 141 142 ld.Asmelfsym(ctxt) 143 ctxt.Out.Flush() 144 ctxt.Out.Write(ld.Elfstrdat) 145 146 if ctxt.LinkMode == ld.LinkExternal { 147 ld.Elfemitreloc(ctxt) 148 } 149 } 150 151 ctxt.Out.SeekSet(0) 152 switch ctxt.HeadType { 153 case objabi.Hlinux: 154 ld.Asmbelf(ctxt, int64(symo)) 155 default: 156 ld.Errorf(nil, "unsupported operating system") 157 } 158 ctxt.Out.Flush() 159 160 if *ld.FlagC { 161 fmt.Printf("textsize=%d\n", ld.Segtext.Filelen) 162 fmt.Printf("datsize=%d\n", ld.Segdata.Filelen) 163 fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen) 164 fmt.Printf("symsize=%d\n", ld.Symsize) 165 fmt.Printf("lcsize=%d\n", ld.Lcsize) 166 fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize)) 167 } 168 }