1
2
3
4
5 package loong64
6
7 import (
8 "cmd/internal/objabi"
9 "cmd/internal/sys"
10 "cmd/link/internal/ld"
11 "cmd/link/internal/loader"
12 "cmd/link/internal/sym"
13 "debug/elf"
14 "log"
15 )
16
17 func gentext(ctxt *ld.Link, ldr *loader.Loader) {
18 initfunc, addmoduledata := ld.PrepareAddmoduledata(ctxt)
19 if initfunc == nil {
20 return
21 }
22
23 o := func(op uint32) {
24 initfunc.AddUint32(ctxt.Arch, op)
25 }
26
27
28
29
30
31
32
33
34
35
36 o(0x1a000004)
37 rel, _ := initfunc.AddRel(objabi.R_LOONG64_ADDR_HI)
38 rel.SetOff(0)
39 rel.SetSiz(4)
40 rel.SetSym(ctxt.Moduledata)
41
42
43
44 o(0x02c00084)
45 rel2, _ := initfunc.AddRel(objabi.R_LOONG64_ADDR_LO)
46 rel2.SetOff(4)
47 rel2.SetSiz(4)
48 rel2.SetSym(ctxt.Moduledata)
49
50
51
52 o(0x50000000)
53 rel3, _ := initfunc.AddRel(objabi.R_CALLLOONG64)
54 rel3.SetOff(8)
55 rel3.SetSiz(4)
56 rel3.SetSym(addmoduledata)
57 }
58
59 func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc, rIdx int) bool {
60 log.Fatalf("adddynrel not implemented")
61 return false
62 }
63
64 func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtReloc, ri int, sectoff int64) bool {
65
66
67
68
69
70 elfsym := ld.ElfSymForReloc(ctxt, r.Xsym)
71 switch r.Type {
72 default:
73 return false
74 case objabi.R_ADDR, objabi.R_DWARFSECREF:
75 switch r.Size {
76 case 4:
77 out.Write64(uint64(sectoff))
78 out.Write64(uint64(elf.R_LARCH_32) | uint64(elfsym)<<32)
79 out.Write64(uint64(r.Xadd))
80 case 8:
81 out.Write64(uint64(sectoff))
82 out.Write64(uint64(elf.R_LARCH_64) | uint64(elfsym)<<32)
83 out.Write64(uint64(r.Xadd))
84 default:
85 return false
86 }
87 case objabi.R_LOONG64_TLS_LE_LO:
88 out.Write64(uint64(sectoff))
89 out.Write64(uint64(elf.R_LARCH_TLS_LE_LO12) | uint64(elfsym)<<32)
90 out.Write64(uint64(r.Xadd))
91
92 case objabi.R_LOONG64_TLS_LE_HI:
93 out.Write64(uint64(sectoff))
94 out.Write64(uint64(elf.R_LARCH_TLS_LE_HI20) | uint64(elfsym)<<32)
95 out.Write64(uint64(r.Xadd))
96
97 case objabi.R_CALLLOONG64:
98 out.Write64(uint64(sectoff))
99 out.Write64(uint64(elf.R_LARCH_B26) | uint64(elfsym)<<32)
100 out.Write64(uint64(r.Xadd))
101
102 case objabi.R_LOONG64_TLS_IE_HI:
103 out.Write64(uint64(sectoff))
104 out.Write64(uint64(elf.R_LARCH_TLS_IE_PC_HI20) | uint64(elfsym)<<32)
105 out.Write64(uint64(0x0))
106
107 case objabi.R_LOONG64_TLS_IE_LO:
108 out.Write64(uint64(sectoff))
109 out.Write64(uint64(elf.R_LARCH_TLS_IE_PC_LO12) | uint64(elfsym)<<32)
110 out.Write64(uint64(0x0))
111
112 case objabi.R_LOONG64_ADDR_LO:
113 out.Write64(uint64(sectoff))
114 out.Write64(uint64(elf.R_LARCH_PCALA_LO12) | uint64(elfsym)<<32)
115 out.Write64(uint64(r.Xadd))
116
117 case objabi.R_LOONG64_ADDR_HI:
118 out.Write64(uint64(sectoff))
119 out.Write64(uint64(elf.R_LARCH_PCALA_HI20) | uint64(elfsym)<<32)
120 out.Write64(uint64(r.Xadd))
121
122 case objabi.R_LOONG64_GOT_HI:
123 out.Write64(uint64(sectoff))
124 out.Write64(uint64(elf.R_LARCH_GOT_PC_HI20) | uint64(elfsym)<<32)
125 out.Write64(uint64(0x0))
126
127 case objabi.R_LOONG64_GOT_LO:
128 out.Write64(uint64(sectoff))
129 out.Write64(uint64(elf.R_LARCH_GOT_PC_LO12) | uint64(elfsym)<<32)
130 out.Write64(uint64(0x0))
131 }
132
133 return true
134 }
135
136 func elfsetupplt(ctxt *ld.Link, ldr *loader.Loader, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) {
137 return
138 }
139
140 func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int64) bool {
141 return false
142 }
143
144 func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc, s loader.Sym, val int64) (o int64, nExtReloc int, ok bool) {
145 rs := r.Sym()
146 if target.IsExternal() {
147 switch r.Type() {
148 default:
149 return val, 0, false
150 case objabi.R_LOONG64_ADDR_HI,
151 objabi.R_LOONG64_ADDR_LO:
152
153 rs, _ := ld.FoldSubSymbolOffset(ldr, rs)
154 rst := ldr.SymType(rs)
155 if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && ldr.SymSect(rs) == nil {
156 ldr.Errorf(s, "missing section for %s", ldr.SymName(rs))
157 }
158 return val, 1, true
159 case objabi.R_LOONG64_TLS_LE_HI,
160 objabi.R_LOONG64_TLS_LE_LO,
161 objabi.R_CALLLOONG64,
162 objabi.R_JMPLOONG64,
163 objabi.R_LOONG64_TLS_IE_HI,
164 objabi.R_LOONG64_TLS_IE_LO,
165 objabi.R_LOONG64_GOT_HI,
166 objabi.R_LOONG64_GOT_LO:
167 return val, 1, true
168 }
169 }
170
171 const isOk = true
172 const noExtReloc = 0
173
174 switch r.Type() {
175 case objabi.R_CONST:
176 return r.Add(), noExtReloc, isOk
177 case objabi.R_GOTOFF:
178 return ldr.SymValue(r.Sym()) + r.Add() - ldr.SymValue(syms.GOT), noExtReloc, isOk
179 case objabi.R_LOONG64_ADDR_HI,
180 objabi.R_LOONG64_ADDR_LO:
181 pc := ldr.SymValue(s) + int64(r.Off())
182 t := calculatePCAlignedReloc(r.Type(), ldr.SymAddr(rs)+r.Add(), pc)
183 if r.Type() == objabi.R_LOONG64_ADDR_LO {
184 return int64(val&0xffc003ff | (t << 10)), noExtReloc, isOk
185 }
186 return int64(val&0xfe00001f | (t << 5)), noExtReloc, isOk
187 case objabi.R_LOONG64_TLS_LE_HI,
188 objabi.R_LOONG64_TLS_LE_LO:
189 t := ldr.SymAddr(rs) + r.Add()
190 if r.Type() == objabi.R_LOONG64_TLS_LE_LO {
191 return int64(val&0xffc003ff | ((t & 0xfff) << 10)), noExtReloc, isOk
192 }
193 return int64(val&0xfe00001f | (((t) >> 12 << 5) & 0x1ffffe0)), noExtReloc, isOk
194 case objabi.R_CALLLOONG64,
195 objabi.R_JMPLOONG64:
196 pc := ldr.SymValue(s) + int64(r.Off())
197 t := ldr.SymAddr(rs) + r.Add() - pc
198 return int64(val&0xfc000000 | (((t >> 2) & 0xffff) << 10) | (((t >> 2) & 0x3ff0000) >> 16)), noExtReloc, isOk
199 }
200
201 return val, 0, false
202 }
203
204 func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant, loader.Sym, int64, []byte) int64 {
205 return -1
206 }
207
208 func extreloc(target *ld.Target, ldr *loader.Loader, r loader.Reloc, s loader.Sym) (loader.ExtReloc, bool) {
209 switch r.Type() {
210 case objabi.R_LOONG64_ADDR_HI,
211 objabi.R_LOONG64_ADDR_LO,
212 objabi.R_LOONG64_GOT_HI,
213 objabi.R_LOONG64_GOT_LO:
214 return ld.ExtrelocViaOuterSym(ldr, r, s), true
215
216 case objabi.R_LOONG64_TLS_LE_HI,
217 objabi.R_LOONG64_TLS_LE_LO,
218 objabi.R_CONST,
219 objabi.R_GOTOFF,
220 objabi.R_CALLLOONG64,
221 objabi.R_JMPLOONG64,
222 objabi.R_LOONG64_TLS_IE_HI,
223 objabi.R_LOONG64_TLS_IE_LO:
224 return ld.ExtrelocSimple(ldr, r), true
225 }
226 return loader.ExtReloc{}, false
227 }
228
229 func isRequestingLowPageBits(t objabi.RelocType) bool {
230 switch t {
231 case objabi.R_LOONG64_ADDR_LO:
232 return true
233 }
234 return false
235 }
236
237
238
239
240
241
242
243
244 func calculatePCAlignedReloc(t objabi.RelocType, tgt int64, pc int64) int64 {
245 if isRequestingLowPageBits(t) {
246
247 return tgt & 0xfff
248 }
249
250 pageDelta := (tgt >> 12) - (pc >> 12)
251 if tgt&0xfff >= 0x800 {
252
253 pageDelta += 1
254 }
255
256 return pageDelta & 0xfffff
257 }
258
View as plain text