github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/link/internal/sym/reloc.go (about) 1 // Copyright 2017 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 sym 6 7 import ( 8 "github.com/gagliardetto/golang-go/cmd/internal/objabi" 9 "github.com/gagliardetto/golang-go/cmd/internal/sys" 10 "debug/elf" 11 ) 12 13 // Reloc is a relocation. 14 // 15 // The typical Reloc rewrites part of a symbol at offset Off to address Sym. 16 // A Reloc is stored in a slice on the Symbol it rewrites. 17 // 18 // Relocations are generated by the compiler as the type 19 // cmd/internal/obj.Reloc, which is encoded into the object file wire 20 // format and decoded by the linker into this type. A separate type is 21 // used to hold linker-specific state about the relocation. 22 // 23 // Some relocations are created by cmd/link. 24 type Reloc struct { 25 Off int32 // offset to rewrite 26 Siz uint8 // number of bytes to rewrite, 1, 2, or 4 27 Done bool // set to true when relocation is complete 28 Type objabi.RelocType // the relocation type 29 Add int64 // addend 30 Sym *Symbol // symbol the relocation addresses 31 *relocExt // extra fields (see below), may be nil, call InitExt before use 32 } 33 34 // relocExt contains extra fields in Reloc that are used only in 35 // certain cases. 36 type relocExt struct { 37 Xadd int64 // addend passed to external linker 38 Xsym *Symbol // symbol passed to external linker 39 Variant RelocVariant // variation on Type, currently used only on PPC64 and S390X 40 } 41 42 func (r *Reloc) InitExt() { 43 if r.relocExt == nil { 44 r.relocExt = new(relocExt) 45 } 46 } 47 48 // RelocVariant is a linker-internal variation on a relocation. 49 type RelocVariant uint8 50 51 const ( 52 RV_NONE RelocVariant = iota 53 RV_POWER_LO 54 RV_POWER_HI 55 RV_POWER_HA 56 RV_POWER_DS 57 58 // RV_390_DBL is a s390x-specific relocation variant that indicates that 59 // the value to be placed into the relocatable field should first be 60 // divided by 2. 61 RV_390_DBL 62 63 RV_CHECK_OVERFLOW RelocVariant = 1 << 7 64 RV_TYPE_MASK RelocVariant = RV_CHECK_OVERFLOW - 1 65 ) 66 67 func RelocName(arch *sys.Arch, r objabi.RelocType) string { 68 // We didn't have some relocation types at Go1.4. 69 // Uncomment code when we include those in bootstrap code. 70 71 switch { 72 case r >= objabi.MachoRelocOffset: // Mach-O 73 // nr := (r - objabi.MachoRelocOffset)>>1 74 // switch ctxt.Arch.Family { 75 // case sys.AMD64: 76 // return macho.RelocTypeX86_64(nr).String() 77 // case sys.ARM: 78 // return macho.RelocTypeARM(nr).String() 79 // case sys.ARM64: 80 // return macho.RelocTypeARM64(nr).String() 81 // case sys.I386: 82 // return macho.RelocTypeGeneric(nr).String() 83 // default: 84 // panic("unreachable") 85 // } 86 case r >= objabi.ElfRelocOffset: // ELF 87 nr := r - objabi.ElfRelocOffset 88 switch arch.Family { 89 case sys.AMD64: 90 return elf.R_X86_64(nr).String() 91 case sys.ARM: 92 return elf.R_ARM(nr).String() 93 case sys.ARM64: 94 return elf.R_AARCH64(nr).String() 95 case sys.I386: 96 return elf.R_386(nr).String() 97 case sys.MIPS, sys.MIPS64: 98 return elf.R_MIPS(nr).String() 99 case sys.PPC64: 100 return elf.R_PPC64(nr).String() 101 case sys.S390X: 102 return elf.R_390(nr).String() 103 default: 104 panic("unreachable") 105 } 106 } 107 108 return r.String() 109 } 110 111 // RelocByOff implements sort.Interface for sorting relocations by offset. 112 type RelocByOff []Reloc 113 114 func (x RelocByOff) Len() int { return len(x) } 115 116 func (x RelocByOff) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 117 118 func (x RelocByOff) Less(i, j int) bool { 119 a := &x[i] 120 b := &x[j] 121 if a.Off < b.Off { 122 return true 123 } 124 if a.Off > b.Off { 125 return false 126 } 127 return false 128 }