Source file src/cmd/internal/objabi/reloctype.go

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

View as plain text