github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/debug/macho/macho.go (about) 1 // Copyright 2009 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 // Mach-O header data structures 6 // Originally at: 7 // http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html (since deleted by Apple) 8 // Archived copy at: 9 // https://web.archive.org/web/20090819232456/http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachORuntime/index.html 10 // For cloned PDF see: 11 // https://github.com/aidansteele/osx-abi-macho-file-format-reference 12 13 package macho 14 15 import "strconv" 16 17 // A FileHeader represents a Mach-O file header. 18 type FileHeader struct { 19 Magic uint32 20 Cpu Cpu 21 SubCpu uint32 22 Type Type 23 Ncmd uint32 24 Cmdsz uint32 25 Flags uint32 26 } 27 28 const ( 29 fileHeaderSize32 = 7 * 4 30 fileHeaderSize64 = 8 * 4 31 ) 32 33 const ( 34 Magic32 uint32 = 0xfeedface 35 Magic64 uint32 = 0xfeedfacf 36 MagicFat uint32 = 0xcafebabe 37 ) 38 39 // A Type is the Mach-O file type, e.g. an object file, executable, or dynamic library. 40 type Type uint32 41 42 const ( 43 TypeObj Type = 1 44 TypeExec Type = 2 45 TypeDylib Type = 6 46 TypeBundle Type = 8 47 ) 48 49 var typeStrings = []intName{ 50 {uint32(TypeObj), "Obj"}, 51 {uint32(TypeExec), "Exec"}, 52 {uint32(TypeDylib), "Dylib"}, 53 {uint32(TypeBundle), "Bundle"}, 54 } 55 56 func (t Type) String() string { return stringName(uint32(t), typeStrings, false) } 57 func (t Type) GoString() string { return stringName(uint32(t), typeStrings, true) } 58 59 // A Cpu is a Mach-O cpu type. 60 type Cpu uint32 61 62 const cpuArch64 = 0x01000000 63 64 const ( 65 Cpu386 Cpu = 7 66 CpuAmd64 Cpu = Cpu386 | cpuArch64 67 CpuArm Cpu = 12 68 CpuArm64 Cpu = CpuArm | cpuArch64 69 CpuPpc Cpu = 18 70 CpuPpc64 Cpu = CpuPpc | cpuArch64 71 ) 72 73 var cpuStrings = []intName{ 74 {uint32(Cpu386), "Cpu386"}, 75 {uint32(CpuAmd64), "CpuAmd64"}, 76 {uint32(CpuArm), "CpuArm"}, 77 {uint32(CpuArm64), "CpuArm64"}, 78 {uint32(CpuPpc), "CpuPpc"}, 79 {uint32(CpuPpc64), "CpuPpc64"}, 80 } 81 82 func (i Cpu) String() string { return stringName(uint32(i), cpuStrings, false) } 83 func (i Cpu) GoString() string { return stringName(uint32(i), cpuStrings, true) } 84 85 // A LoadCmd is a Mach-O load command. 86 type LoadCmd uint32 87 88 const ( 89 LoadCmdSegment LoadCmd = 0x1 90 LoadCmdSymtab LoadCmd = 0x2 91 LoadCmdThread LoadCmd = 0x4 92 LoadCmdUnixThread LoadCmd = 0x5 // thread+stack 93 LoadCmdDysymtab LoadCmd = 0xb 94 LoadCmdDylib LoadCmd = 0xc // load dylib command 95 LoadCmdDylinker LoadCmd = 0xf // id dylinker command (not load dylinker command) 96 LoadCmdSegment64 LoadCmd = 0x19 97 LoadCmdRpath LoadCmd = 0x8000001c 98 ) 99 100 var cmdStrings = []intName{ 101 {uint32(LoadCmdSegment), "LoadCmdSegment"}, 102 {uint32(LoadCmdThread), "LoadCmdThread"}, 103 {uint32(LoadCmdUnixThread), "LoadCmdUnixThread"}, 104 {uint32(LoadCmdDylib), "LoadCmdDylib"}, 105 {uint32(LoadCmdSegment64), "LoadCmdSegment64"}, 106 {uint32(LoadCmdRpath), "LoadCmdRpath"}, 107 } 108 109 func (i LoadCmd) String() string { return stringName(uint32(i), cmdStrings, false) } 110 func (i LoadCmd) GoString() string { return stringName(uint32(i), cmdStrings, true) } 111 112 type ( 113 // A Segment32 is a 32-bit Mach-O segment load command. 114 Segment32 struct { 115 Cmd LoadCmd 116 Len uint32 117 Name [16]byte 118 Addr uint32 119 Memsz uint32 120 Offset uint32 121 Filesz uint32 122 Maxprot uint32 123 Prot uint32 124 Nsect uint32 125 Flag uint32 126 } 127 128 // A Segment64 is a 64-bit Mach-O segment load command. 129 Segment64 struct { 130 Cmd LoadCmd 131 Len uint32 132 Name [16]byte 133 Addr uint64 134 Memsz uint64 135 Offset uint64 136 Filesz uint64 137 Maxprot uint32 138 Prot uint32 139 Nsect uint32 140 Flag uint32 141 } 142 143 // A SymtabCmd is a Mach-O symbol table command. 144 SymtabCmd struct { 145 Cmd LoadCmd 146 Len uint32 147 Symoff uint32 148 Nsyms uint32 149 Stroff uint32 150 Strsize uint32 151 } 152 153 // A DysymtabCmd is a Mach-O dynamic symbol table command. 154 DysymtabCmd struct { 155 Cmd LoadCmd 156 Len uint32 157 Ilocalsym uint32 158 Nlocalsym uint32 159 Iextdefsym uint32 160 Nextdefsym uint32 161 Iundefsym uint32 162 Nundefsym uint32 163 Tocoffset uint32 164 Ntoc uint32 165 Modtaboff uint32 166 Nmodtab uint32 167 Extrefsymoff uint32 168 Nextrefsyms uint32 169 Indirectsymoff uint32 170 Nindirectsyms uint32 171 Extreloff uint32 172 Nextrel uint32 173 Locreloff uint32 174 Nlocrel uint32 175 } 176 177 // A DylibCmd is a Mach-O load dynamic library command. 178 DylibCmd struct { 179 Cmd LoadCmd 180 Len uint32 181 Name uint32 182 Time uint32 183 CurrentVersion uint32 184 CompatVersion uint32 185 } 186 187 // A RpathCmd is a Mach-O rpath command. 188 RpathCmd struct { 189 Cmd LoadCmd 190 Len uint32 191 Path uint32 192 } 193 194 // A Thread is a Mach-O thread state command. 195 Thread struct { 196 Cmd LoadCmd 197 Len uint32 198 Type uint32 199 Data []uint32 200 } 201 ) 202 203 const ( 204 FlagNoUndefs uint32 = 0x1 205 FlagIncrLink uint32 = 0x2 206 FlagDyldLink uint32 = 0x4 207 FlagBindAtLoad uint32 = 0x8 208 FlagPrebound uint32 = 0x10 209 FlagSplitSegs uint32 = 0x20 210 FlagLazyInit uint32 = 0x40 211 FlagTwoLevel uint32 = 0x80 212 FlagForceFlat uint32 = 0x100 213 FlagNoMultiDefs uint32 = 0x200 214 FlagNoFixPrebinding uint32 = 0x400 215 FlagPrebindable uint32 = 0x800 216 FlagAllModsBound uint32 = 0x1000 217 FlagSubsectionsViaSymbols uint32 = 0x2000 218 FlagCanonical uint32 = 0x4000 219 FlagWeakDefines uint32 = 0x8000 220 FlagBindsToWeak uint32 = 0x10000 221 FlagAllowStackExecution uint32 = 0x20000 222 FlagRootSafe uint32 = 0x40000 223 FlagSetuidSafe uint32 = 0x80000 224 FlagNoReexportedDylibs uint32 = 0x100000 225 FlagPIE uint32 = 0x200000 226 FlagDeadStrippableDylib uint32 = 0x400000 227 FlagHasTLVDescriptors uint32 = 0x800000 228 FlagNoHeapExecution uint32 = 0x1000000 229 FlagAppExtensionSafe uint32 = 0x2000000 230 ) 231 232 // A Section32 is a 32-bit Mach-O section header. 233 type Section32 struct { 234 Name [16]byte 235 Seg [16]byte 236 Addr uint32 237 Size uint32 238 Offset uint32 239 Align uint32 240 Reloff uint32 241 Nreloc uint32 242 Flags uint32 243 Reserve1 uint32 244 Reserve2 uint32 245 } 246 247 // A Section64 is a 64-bit Mach-O section header. 248 type Section64 struct { 249 Name [16]byte 250 Seg [16]byte 251 Addr uint64 252 Size uint64 253 Offset uint32 254 Align uint32 255 Reloff uint32 256 Nreloc uint32 257 Flags uint32 258 Reserve1 uint32 259 Reserve2 uint32 260 Reserve3 uint32 261 } 262 263 // An Nlist32 is a Mach-O 32-bit symbol table entry. 264 type Nlist32 struct { 265 Name uint32 266 Type uint8 267 Sect uint8 268 Desc uint16 269 Value uint32 270 } 271 272 // An Nlist64 is a Mach-O 64-bit symbol table entry. 273 type Nlist64 struct { 274 Name uint32 275 Type uint8 276 Sect uint8 277 Desc uint16 278 Value uint64 279 } 280 281 // Regs386 is the Mach-O 386 register structure. 282 type Regs386 struct { 283 AX uint32 284 BX uint32 285 CX uint32 286 DX uint32 287 DI uint32 288 SI uint32 289 BP uint32 290 SP uint32 291 SS uint32 292 FLAGS uint32 293 IP uint32 294 CS uint32 295 DS uint32 296 ES uint32 297 FS uint32 298 GS uint32 299 } 300 301 // RegsAMD64 is the Mach-O AMD64 register structure. 302 type RegsAMD64 struct { 303 AX uint64 304 BX uint64 305 CX uint64 306 DX uint64 307 DI uint64 308 SI uint64 309 BP uint64 310 SP uint64 311 R8 uint64 312 R9 uint64 313 R10 uint64 314 R11 uint64 315 R12 uint64 316 R13 uint64 317 R14 uint64 318 R15 uint64 319 IP uint64 320 FLAGS uint64 321 CS uint64 322 FS uint64 323 GS uint64 324 } 325 326 type intName struct { 327 i uint32 328 s string 329 } 330 331 func stringName(i uint32, names []intName, goSyntax bool) string { 332 for _, n := range names { 333 if n.i == i { 334 if goSyntax { 335 return "macho." + n.s 336 } 337 return n.s 338 } 339 } 340 return strconv.FormatUint(uint64(i), 10) 341 }