-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreloctype.go
525 lines (448 loc) · 20.9 KB
/
reloctype.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
// Derived from Inferno utils/6l/l.h and related files.
// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6l/l.h
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package objabi
type RelocType int16
//go:generate stringer -type=RelocType
const (
R_ADDR RelocType = 1 + iota
// R_ADDRPOWER relocates a pair of "D-form" instructions (instructions with 16-bit
// immediates in the low half of the instruction word), usually addis followed by
// another add or a load, inserting the "high adjusted" 16 bits of the address of
// the referenced symbol into the immediate field of the first instruction and the
// low 16 bits into that of the second instruction.
R_ADDRPOWER
// R_ADDRARM64 relocates an adrp, add pair to compute the address of the
// referenced symbol.
R_ADDRARM64
// R_ADDRMIPS (only used on mips/mips64) resolves to the low 16 bits of an external
// address, by encoding it into the instruction.
R_ADDRMIPS
// R_ADDROFF resolves to a 32-bit offset from the beginning of the section
// holding the data being relocated to the referenced symbol.
R_ADDROFF
R_SIZE
R_CALL
R_CALLARM
R_CALLARM64
R_CALLIND
R_CALLPOWER
// R_CALLMIPS (only used on mips64) resolves to non-PC-relative target address
// of a CALL (JAL) instruction, by encoding the address into the instruction.
R_CALLMIPS
R_CONST
R_PCREL
// R_TLS_LE, used on 386, amd64, and ARM, resolves to the offset of the
// thread-local symbol from the thread local base and is used to implement the
// "local exec" model for tls access (r.Sym is not set on intel platforms but is
// set to a TLS symbol -- runtime.tlsg -- in the linker when externally linking).
R_TLS_LE
// R_TLS_IE, used 386, amd64, and ARM resolves to the PC-relative offset to a GOT
// slot containing the offset from the thread-local symbol from the thread local
// base and is used to implemented the "initial exec" model for tls access (r.Sym
// is not set on intel platforms but is set to a TLS symbol -- runtime.tlsg -- in
// the linker when externally linking).
R_TLS_IE
R_GOTOFF
R_PLT0
R_PLT1
R_PLT2
R_USEFIELD
// R_USETYPE resolves to an *rtype, but no relocation is created. The
// linker uses this as a signal that the pointed-to type information
// should be linked into the final binary, even if there are no other
// direct references. (This is used for types reachable by reflection.)
R_USETYPE
// R_USEIFACE marks a type is converted to an interface in the function this
// relocation is applied to. The target is a type descriptor or an itab
// (in the latter case it refers to the concrete type contained in the itab).
// This is a marker relocation (0-sized), for the linker's reachabililty
// analysis.
R_USEIFACE
// R_USEIFACEMETHOD marks an interface method that is used in the function
// this relocation is applied to. The target is an interface type descriptor.
// The addend is the offset of the method in the type descriptor.
// This is a marker relocation (0-sized), for the linker's reachabililty
// analysis.
R_USEIFACEMETHOD
// R_USENAMEDMETHOD marks that methods with a specific name must not be eliminated.
// The target is a symbol containing the name of a method called via a generic
// interface or looked up via MethodByName("F").
R_USENAMEDMETHOD
// R_METHODOFF resolves to a 32-bit offset from the beginning of the section
// holding the data being relocated to the referenced symbol.
// It is a variant of R_ADDROFF used when linking from the uncommonType of a
// *rtype, and may be set to zero by the linker if it determines the method
// text is unreachable by the linked program.
R_METHODOFF
// R_KEEP tells the linker to keep the referred-to symbol in the final binary
// if the symbol containing the R_KEEP relocation is in the final binary.
R_KEEP
R_POWER_TOC
R_GOTPCREL
// R_JMPMIPS (only used on mips64) resolves to non-PC-relative target address
// of a JMP instruction, by encoding the address into the instruction.
// The stack nosplit check ignores this since it is not a function call.
R_JMPMIPS
// R_DWARFSECREF resolves to the offset of the symbol from its section.
// Target of relocation must be size 4 (in current implementation).
R_DWARFSECREF
// Platform dependent relocations. Architectures with fixed width instructions
// have the inherent issue that a 32-bit (or 64-bit!) displacement cannot be
// stuffed into a 32-bit instruction, so an address needs to be spread across
// several instructions, and in turn this requires a sequence of relocations, each
// updating a part of an instruction. This leads to relocation codes that are
// inherently processor specific.
// Arm64.
// Set a MOV[NZ] immediate field to bits [15:0] of the offset from the thread
// local base to the thread local variable defined by the referenced (thread
// local) symbol. Error if the offset does not fit into 16 bits.
R_ARM64_TLS_LE
// Relocates an ADRP; LD64 instruction sequence to load the offset between
// the thread local base and the thread local variable defined by the
// referenced (thread local) symbol from the GOT.
R_ARM64_TLS_IE
// R_ARM64_GOTPCREL relocates an adrp, ld64 pair to compute the address of the GOT
// slot of the referenced symbol.
R_ARM64_GOTPCREL
// R_ARM64_GOT resolves a GOT-relative instruction sequence, usually an adrp
// followed by another ld instruction.
R_ARM64_GOT
// R_ARM64_PCREL resolves a PC-relative addresses instruction sequence, usually an
// adrp followed by another add instruction.
R_ARM64_PCREL
// R_ARM64_PCREL_LDST8 resolves a PC-relative addresses instruction sequence, usually an
// adrp followed by a LD8 or ST8 instruction.
R_ARM64_PCREL_LDST8
// R_ARM64_PCREL_LDST16 resolves a PC-relative addresses instruction sequence, usually an
// adrp followed by a LD16 or ST16 instruction.
R_ARM64_PCREL_LDST16
// R_ARM64_PCREL_LDST32 resolves a PC-relative addresses instruction sequence, usually an
// adrp followed by a LD32 or ST32 instruction.
R_ARM64_PCREL_LDST32
// R_ARM64_PCREL_LDST64 resolves a PC-relative addresses instruction sequence, usually an
// adrp followed by a LD64 or ST64 instruction.
R_ARM64_PCREL_LDST64
// R_ARM64_LDST8 sets a LD/ST immediate value to bits [11:0] of a local address.
R_ARM64_LDST8
// R_ARM64_LDST16 sets a LD/ST immediate value to bits [11:1] of a local address.
R_ARM64_LDST16
// R_ARM64_LDST32 sets a LD/ST immediate value to bits [11:2] of a local address.
R_ARM64_LDST32
// R_ARM64_LDST64 sets a LD/ST immediate value to bits [11:3] of a local address.
R_ARM64_LDST64
// R_ARM64_LDST128 sets a LD/ST immediate value to bits [11:4] of a local address.
R_ARM64_LDST128
// PPC64.
// R_POWER_TLS_LE is used to implement the "local exec" model for tls
// access. It resolves to the offset of the thread-local symbol from the
// thread pointer (R13) and is split against a pair of instructions to
// support a 32 bit displacement.
R_POWER_TLS_LE
// R_POWER_TLS_IE is used to implement the "initial exec" model for tls access. It
// relocates a D-form, DS-form instruction sequence like R_ADDRPOWER_DS. It
// inserts to the offset of GOT slot for the thread-local symbol from the TOC (the
// GOT slot is filled by the dynamic linker with the offset of the thread-local
// symbol from the thread pointer (R13)).
R_POWER_TLS_IE
// R_POWER_TLS marks an X-form instruction such as "ADD R3,R13,R4" as completing
// a sequence of GOT-relative relocations to compute a TLS address. This can be
// used by the system linker to rewrite the GOT-relative TLS relocation into a
// simpler thread-pointer relative relocation. See table 3.26 and 3.28 in the
// ppc64 elfv2 1.4 ABI on this transformation. Likewise, the second argument
// (usually called RB in X-form instructions) is assumed to be R13.
R_POWER_TLS
// R_POWER_TLS_IE_PCREL34 is similar to R_POWER_TLS_IE, but marks a single MOVD
// which has been assembled as a single prefixed load doubleword without using the
// TOC.
R_POWER_TLS_IE_PCREL34
// R_POWER_TLS_LE_TPREL34 is similar to R_POWER_TLS_LE, but computes an offset from
// the thread pointer in one prefixed instruction.
R_POWER_TLS_LE_TPREL34
// R_ADDRPOWER_DS is similar to R_ADDRPOWER above, but assumes the second
// instruction is a "DS-form" instruction, which has an immediate field occupying
// bits [15:2] of the instruction word. Bits [15:2] of the address of the
// relocated symbol are inserted into this field; it is an error if the last two
// bits of the address are not 0.
R_ADDRPOWER_DS
// R_ADDRPOWER_GOT relocates a D-form + DS-form instruction sequence by inserting
// a relative displacement of referenced symbol's GOT entry to the TOC pointer.
R_ADDRPOWER_GOT
// R_ADDRPOWER_GOT_PCREL34 is identical to R_ADDRPOWER_GOT, but uses a PC relative
// sequence to generate a GOT symbol addresses.
R_ADDRPOWER_GOT_PCREL34
// R_ADDRPOWER_PCREL relocates two D-form instructions like R_ADDRPOWER, but
// inserts the displacement from the place being relocated to the address of the
// relocated symbol instead of just its address.
R_ADDRPOWER_PCREL
// R_ADDRPOWER_TOCREL relocates two D-form instructions like R_ADDRPOWER, but
// inserts the offset from the TOC to the address of the relocated symbol
// rather than the symbol's address.
R_ADDRPOWER_TOCREL
// R_ADDRPOWER_TOCREL_DS relocates a D-form, DS-form instruction sequence like
// R_ADDRPOWER_DS but inserts the offset from the TOC to the address of the
// relocated symbol rather than the symbol's address.
R_ADDRPOWER_TOCREL_DS
// R_ADDRPOWER_D34 relocates a single prefixed D-form load/store operation. All
// prefixed forms are D form. The high 18 bits are stored in the prefix,
// and the low 16 are stored in the suffix. The address is absolute.
R_ADDRPOWER_D34
// R_ADDRPOWER_PCREL34 relates a single prefixed D-form load/store/add operation.
// All prefixed forms are D form. The resulting address is relative to the
// PC. It is a signed 34 bit offset.
R_ADDRPOWER_PCREL34
// RISC-V.
// R_RISCV_JAL resolves a 20 bit offset for a J-type instruction.
R_RISCV_JAL
// R_RISCV_JAL_TRAMP is the same as R_RISCV_JAL but denotes the use of a
// trampoline, which we may be able to avoid during relocation. These are
// only used by the linker and are not emitted by the compiler or assembler.
R_RISCV_JAL_TRAMP
// R_RISCV_CALL resolves a 32 bit PC-relative address for an AUIPC + JALR
// instruction pair.
R_RISCV_CALL
// R_RISCV_PCREL_ITYPE resolves a 32 bit PC-relative address for an
// AUIPC + I-type instruction pair.
R_RISCV_PCREL_ITYPE
// R_RISCV_PCREL_STYPE resolves a 32 bit PC-relative address for an
// AUIPC + S-type instruction pair.
R_RISCV_PCREL_STYPE
// R_RISCV_TLS_IE resolves a 32 bit TLS initial-exec address for an
// AUIPC + I-type instruction pair.
R_RISCV_TLS_IE
// R_RISCV_TLS_LE resolves a 32 bit TLS local-exec address for a
// LUI + I-type instruction sequence.
R_RISCV_TLS_LE
// R_RISCV_GOT_HI20 resolves the high 20 bits of a 32-bit PC-relative GOT
// address.
R_RISCV_GOT_HI20
// R_RISCV_GOT_PCREL_ITYPE resolves a 32-bit PC-relative GOT entry
// address for an AUIPC + I-type instruction pair.
R_RISCV_GOT_PCREL_ITYPE
// R_RISCV_PCREL_HI20 resolves the high 20 bits of a 32-bit PC-relative
// address.
R_RISCV_PCREL_HI20
// R_RISCV_PCREL_LO12_I resolves the low 12 bits of a 32-bit PC-relative
// address using an I-type instruction.
R_RISCV_PCREL_LO12_I
// R_RISCV_PCREL_LO12_S resolves the low 12 bits of a 32-bit PC-relative
// address using an S-type instruction.
R_RISCV_PCREL_LO12_S
// R_RISCV_BRANCH resolves a 12-bit PC-relative branch offset.
R_RISCV_BRANCH
// R_RISCV_RVC_BRANCH resolves an 8-bit PC-relative offset for a CB-type
// instruction.
R_RISCV_RVC_BRANCH
// R_RISCV_RVC_JUMP resolves an 11-bit PC-relative offset for a CJ-type
// instruction.
R_RISCV_RVC_JUMP
// R_PCRELDBL relocates s390x 2-byte aligned PC-relative addresses.
// TODO(mundaym): remove once variants can be serialized - see issue 14218.
R_PCRELDBL
// Loong64.
// R_LOONG64_ADDR_HI resolves to the sign-adjusted "upper" 20 bits (bit 5-24) of an
// external address, by encoding it into the instruction.
// R_LOONG64_ADDR_LO resolves to the low 12 bits of an external address, by encoding
// it into the instruction.
R_LOONG64_ADDR_HI
R_LOONG64_ADDR_LO
// R_LOONG64_TLS_LE_HI resolves to the high 20 bits of a TLS address (offset from
// thread pointer), by encoding it into the instruction.
// R_LOONG64_TLS_LE_LO resolves to the low 12 bits of a TLS address (offset from
// thread pointer), by encoding it into the instruction.
R_LOONG64_TLS_LE_HI
R_LOONG64_TLS_LE_LO
// R_CALLLOONG64 resolves to non-PC-relative target address of a CALL (BL/JIRL)
// instruction, by encoding the address into the instruction.
R_CALLLOONG64
// R_LOONG64_TLS_IE_HI and R_LOONG64_TLS_IE_LO relocates a pcalau12i, ld.d
// pair to compute the address of the GOT slot of the tls symbol.
R_LOONG64_TLS_IE_HI
R_LOONG64_TLS_IE_LO
// R_LOONG64_GOT_HI and R_LOONG64_GOT_LO resolves a GOT-relative instruction sequence,
// usually an pcalau12i followed by another ld or addi instruction.
R_LOONG64_GOT_HI
R_LOONG64_GOT_LO
// 64-bit in-place addition.
R_LOONG64_ADD64
// 64-bit in-place subtraction.
R_LOONG64_SUB64
// R_JMP16LOONG64 resolves to 18-bit PC-relative target address of a JMP instructions.
R_JMP16LOONG64
// R_JMP21LOONG64 resolves to 23-bit PC-relative target address of a JMP instructions.
R_JMP21LOONG64
// R_JMPLOONG64 resolves to non-PC-relative target address of a JMP instruction,
// by encoding the address into the instruction.
R_JMPLOONG64
// R_ADDRMIPSU (only used on mips/mips64) resolves to the sign-adjusted "upper" 16
// bits (bit 16-31) of an external address, by encoding it into the instruction.
R_ADDRMIPSU
// R_ADDRMIPSTLS (only used on mips64) resolves to the low 16 bits of a TLS
// address (offset from thread pointer), by encoding it into the instruction.
R_ADDRMIPSTLS
// R_ADDRCUOFF resolves to a pointer-sized offset from the start of the
// symbol's DWARF compile unit.
R_ADDRCUOFF
// R_WASMIMPORT resolves to the index of the WebAssembly function import.
R_WASMIMPORT
// R_XCOFFREF (only used on aix/ppc64) prevents garbage collection by ld
// of a symbol. This isn't a real relocation, it can be placed in anywhere
// in a symbol and target any symbols.
R_XCOFFREF
// R_PEIMAGEOFF resolves to a 32-bit offset from the start address of where
// the executable file is mapped in memory.
R_PEIMAGEOFF
// R_INITORDER specifies an ordering edge between two inittask records.
// (From one p..inittask record to another one.)
// This relocation does not apply any changes to the actual data, it is
// just used in the linker to order the inittask records appropriately.
R_INITORDER
// The R_DWTXTADDR_* family of relocations are effectively
// references to the .debug_addr entry for a given TEXT symbol
// corresponding to a Go function. Given a R_DWTXTADDR_* reloc
// applied to dwarf section S at offset O against sym F, the linker
// locates the .debug_addr entry for F (within its package) and
// writes the index of that entry to section S at offset O, using
// ULEB encoding, writing a number of bytes controlled by the
// suffix (e.g. for R_DWTXTADDR_U2 we write two bytes). Note
// also that .debug_addr indices are not finalized until link time;
// when the compiler creates a R_DWTXTADDR_* relocation the
// index payload will be left as zero (to be filled in later).
R_DWTXTADDR_U1
R_DWTXTADDR_U2
R_DWTXTADDR_U3
R_DWTXTADDR_U4
// R_WEAK marks the relocation as a weak reference.
// A weak relocation does not make the symbol it refers to reachable,
// and is only honored by the linker if the symbol is in some other way
// reachable.
R_WEAK = -1 << 15
R_WEAKADDR = R_WEAK | R_ADDR
R_WEAKADDROFF = R_WEAK | R_ADDROFF
)
// IsDirectCall reports whether r is a relocation for a direct call.
// A direct call is a CALL instruction that takes the target address
// as an immediate. The address is embedded into the instruction(s), possibly
// with limited width. An indirect call is a CALL instruction that takes
// the target address in register or memory.
func (r RelocType) IsDirectCall() bool {
switch r {
case R_CALL, R_CALLARM, R_CALLARM64, R_CALLLOONG64, R_CALLMIPS, R_CALLPOWER,
R_RISCV_CALL, R_RISCV_JAL, R_RISCV_JAL_TRAMP:
return true
}
return false
}
// IsDirectJump reports whether r is a relocation for a direct jump.
// A direct jump is a JMP instruction that takes the target address
// as an immediate. The address is embedded into the instruction, possibly
// with limited width. An indirect jump is a JMP instruction that takes
// the target address in register or memory.
func (r RelocType) IsDirectJump() bool {
switch r {
case R_JMPMIPS:
return true
case R_JMPLOONG64:
return true
}
return false
}
// IsDirectCallOrJump reports whether r is a relocation for a direct
// call or a direct jump.
func (r RelocType) IsDirectCallOrJump() bool {
return r.IsDirectCall() || r.IsDirectJump()
}
// IsDwTxtAddr reports whether r is one of the several DWARF
// .debug_addr section indirect relocations.
func (r RelocType) IsDwTxtAddr() bool {
switch r {
case R_DWTXTADDR_U1, R_DWTXTADDR_U2, R_DWTXTADDR_U3, R_DWTXTADDR_U4:
return true
default:
return false
}
}
// FuncCountToDwTxtAddrFlavor returns the correct DWARF .debug_addr
// section relocation to use when compiling a package with a total of
// fncount functions, along with the size of the ULEB128-encoded blob
// needed to store the the eventual .debug_addr index.
func FuncCountToDwTxtAddrFlavor(fncount int) (RelocType, int) {
switch {
case fncount <= 127:
return R_DWTXTADDR_U1, 1
case fncount <= 16383:
return R_DWTXTADDR_U2, 2
case fncount <= 2097151:
return R_DWTXTADDR_U3, 3
case fncount <= 268435455:
return R_DWTXTADDR_U4, 4
default:
panic("package has more than 268435455 functions")
}
}
// DummyDwarfFunctionCountForAssembler returns a dummy value to be
// used for "total number of functions in the package" for use in the
// assembler (compiler does not call this function).
//
// Background/motivation: let's say we have a package P with some
// assembly functions (in "a.s") and some Go functions (in
// "b.go"). The compilation sequence used by the Go commmand will be:
//
// 1. run the assembler on a.s to generate a "symabis" file
// 2. run the compiler on b.go passing it the symabis file and generating a "go_defs.h" asm header
// 3. run the assembler on a.s passing it an include dir with the generated "go_defs.h" file
//
// When the compiler runs, it can easily determine the total function
// count for the package (for use with FuncCountToDwTxtAddrFlavor
// above) by counting defined Go funcs and looking at the symabis
// file. With the assembler however there is no easy way for it to
// figure out the total number of Go source funcs. To keep things
// simple, we instead just use a dummy total function count while
// running the assembler that will guarantee we pick a relocation
// flavor that will work for any package size.
func DummyDwarfFunctionCountForAssembler() int {
return 9999999
}
// DwTxtAddrRelocParams returns the maximum number of functions per
// package supported for the DWARF .debug_addr relocation variant r,
// along with the number of bytes it takes up in encoded form.
func (r RelocType) DwTxtAddrRelocParams() (int, int) {
switch r {
case R_DWTXTADDR_U1:
return 0x7f, 1
case R_DWTXTADDR_U2:
return 0x3fff, 2
case R_DWTXTADDR_U3:
return 0x1fffff, 3
case R_DWTXTADDR_U4:
return 0xfffffff, 4
default:
panic("not a dwtxtaddr relocation")
}
}