Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / cmd / splitdwarf / internal / macho / macho.go
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 // http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html
7
8 package macho
9
10 import (
11         "encoding/binary"
12         "strconv"
13 )
14
15 // A FileHeader represents a Mach-O file header.
16 type FileHeader struct {
17         Magic        uint32
18         Cpu          Cpu
19         SubCpu       uint32
20         Type         HdrType
21         NCommands    uint32 // number of load commands
22         SizeCommands uint32 // size of all the load commands, not including this header.
23         Flags        HdrFlags
24 }
25
26 func (h *FileHeader) Put(b []byte, o binary.ByteOrder) int {
27         o.PutUint32(b[0:], h.Magic)
28         o.PutUint32(b[4:], uint32(h.Cpu))
29         o.PutUint32(b[8:], h.SubCpu)
30         o.PutUint32(b[12:], uint32(h.Type))
31         o.PutUint32(b[16:], h.NCommands)
32         o.PutUint32(b[20:], h.SizeCommands)
33         o.PutUint32(b[24:], uint32(h.Flags))
34         if h.Magic == Magic32 {
35                 return 28
36         }
37         o.PutUint32(b[28:], 0)
38         return 32
39 }
40
41 const (
42         fileHeaderSize32 = 7 * 4
43         fileHeaderSize64 = 8 * 4
44 )
45
46 const (
47         Magic32  uint32 = 0xfeedface
48         Magic64  uint32 = 0xfeedfacf
49         MagicFat uint32 = 0xcafebabe
50 )
51
52 type HdrFlags uint32
53 type SegFlags uint32
54 type SecFlags uint32
55
56 // A HdrType is the Mach-O file type, e.g. an object file, executable, or dynamic library.
57 type HdrType uint32
58
59 const ( // SNAKE_CASE to CamelCase translation from C names
60         MhObject  HdrType = 1
61         MhExecute HdrType = 2
62         MhCore    HdrType = 4
63         MhDylib   HdrType = 6
64         MhBundle  HdrType = 8
65         MhDsym    HdrType = 0xa
66 )
67
68 var typeStrings = []intName{
69         {uint32(MhObject), "Obj"},
70         {uint32(MhExecute), "Exec"},
71         {uint32(MhDylib), "Dylib"},
72         {uint32(MhBundle), "Bundle"},
73         {uint32(MhDsym), "Dsym"},
74 }
75
76 func (t HdrType) String() string   { return stringName(uint32(t), typeStrings, false) }
77 func (t HdrType) GoString() string { return stringName(uint32(t), typeStrings, true) }
78
79 // A Cpu is a Mach-O cpu type.
80 type Cpu uint32
81
82 const cpuArch64 = 0x01000000
83
84 const (
85         Cpu386   Cpu = 7
86         CpuAmd64 Cpu = Cpu386 | cpuArch64
87         CpuArm   Cpu = 12
88         CpuArm64 Cpu = CpuArm | cpuArch64
89         CpuPpc   Cpu = 18
90         CpuPpc64 Cpu = CpuPpc | cpuArch64
91 )
92
93 var cpuStrings = []intName{
94         {uint32(Cpu386), "Cpu386"},
95         {uint32(CpuAmd64), "CpuAmd64"},
96         {uint32(CpuArm), "CpuArm"},
97         {uint32(CpuArm64), "CpuArm64"},
98         {uint32(CpuPpc), "CpuPpc"},
99         {uint32(CpuPpc64), "CpuPpc64"},
100 }
101
102 func (i Cpu) String() string   { return stringName(uint32(i), cpuStrings, false) }
103 func (i Cpu) GoString() string { return stringName(uint32(i), cpuStrings, true) }
104
105 // A LoadCmd is a Mach-O load command.
106 type LoadCmd uint32
107
108 func (c LoadCmd) Command() LoadCmd { return c }
109
110 const ( // SNAKE_CASE to CamelCase translation from C names
111         // Note 3 and 8 are obsolete
112         LcSegment            LoadCmd = 0x1
113         LcSymtab             LoadCmd = 0x2
114         LcThread             LoadCmd = 0x4
115         LcUnixthread         LoadCmd = 0x5 // thread+stack
116         LcDysymtab           LoadCmd = 0xb
117         LcDylib              LoadCmd = 0xc // load dylib command
118         LcIdDylib            LoadCmd = 0xd // dynamically linked shared lib ident
119         LcLoadDylinker       LoadCmd = 0xe // load a dynamic linker
120         LcIdDylinker         LoadCmd = 0xf // id dylinker command (not load dylinker command)
121         LcSegment64          LoadCmd = 0x19
122         LcUuid               LoadCmd = 0x1b
123         LcCodeSignature      LoadCmd = 0x1d
124         LcSegmentSplitInfo   LoadCmd = 0x1e
125         LcRpath              LoadCmd = 0x8000001c
126         LcEncryptionInfo     LoadCmd = 0x21
127         LcDyldInfo           LoadCmd = 0x22
128         LcDyldInfoOnly       LoadCmd = 0x80000022
129         LcVersionMinMacosx   LoadCmd = 0x24
130         LcVersionMinIphoneos LoadCmd = 0x25
131         LcFunctionStarts     LoadCmd = 0x26
132         LcDyldEnvironment    LoadCmd = 0x27
133         LcMain               LoadCmd = 0x80000028 // replacement for UnixThread
134         LcDataInCode         LoadCmd = 0x29       // There are non-instructions in text
135         LcSourceVersion      LoadCmd = 0x2a       // Source version used to build binary
136         LcDylibCodeSignDrs   LoadCmd = 0x2b
137         LcEncryptionInfo64   LoadCmd = 0x2c
138         LcVersionMinTvos     LoadCmd = 0x2f
139         LcVersionMinWatchos  LoadCmd = 0x30
140 )
141
142 var cmdStrings = []intName{
143         {uint32(LcSegment), "LoadCmdSegment"},
144         {uint32(LcThread), "LoadCmdThread"},
145         {uint32(LcUnixthread), "LoadCmdUnixThread"},
146         {uint32(LcDylib), "LoadCmdDylib"},
147         {uint32(LcIdDylib), "LoadCmdIdDylib"},
148         {uint32(LcLoadDylinker), "LoadCmdLoadDylinker"},
149         {uint32(LcIdDylinker), "LoadCmdIdDylinker"},
150         {uint32(LcSegment64), "LoadCmdSegment64"},
151         {uint32(LcUuid), "LoadCmdUuid"},
152         {uint32(LcRpath), "LoadCmdRpath"},
153         {uint32(LcDyldEnvironment), "LoadCmdDyldEnv"},
154         {uint32(LcMain), "LoadCmdMain"},
155         {uint32(LcDataInCode), "LoadCmdDataInCode"},
156         {uint32(LcSourceVersion), "LoadCmdSourceVersion"},
157         {uint32(LcDyldInfo), "LoadCmdDyldInfo"},
158         {uint32(LcDyldInfoOnly), "LoadCmdDyldInfoOnly"},
159         {uint32(LcVersionMinMacosx), "LoadCmdMinOsx"},
160         {uint32(LcFunctionStarts), "LoadCmdFunctionStarts"},
161 }
162
163 func (i LoadCmd) String() string   { return stringName(uint32(i), cmdStrings, false) }
164 func (i LoadCmd) GoString() string { return stringName(uint32(i), cmdStrings, true) }
165
166 type (
167         // A Segment32 is a 32-bit Mach-O segment load command.
168         Segment32 struct {
169                 LoadCmd
170                 Len     uint32
171                 Name    [16]byte
172                 Addr    uint32
173                 Memsz   uint32
174                 Offset  uint32
175                 Filesz  uint32
176                 Maxprot uint32
177                 Prot    uint32
178                 Nsect   uint32
179                 Flag    SegFlags
180         }
181
182         // A Segment64 is a 64-bit Mach-O segment load command.
183         Segment64 struct {
184                 LoadCmd
185                 Len     uint32
186                 Name    [16]byte
187                 Addr    uint64
188                 Memsz   uint64
189                 Offset  uint64
190                 Filesz  uint64
191                 Maxprot uint32
192                 Prot    uint32
193                 Nsect   uint32
194                 Flag    SegFlags
195         }
196
197         // A SymtabCmd is a Mach-O symbol table command.
198         SymtabCmd struct {
199                 LoadCmd
200                 Len     uint32
201                 Symoff  uint32
202                 Nsyms   uint32
203                 Stroff  uint32
204                 Strsize uint32
205         }
206
207         // A DysymtabCmd is a Mach-O dynamic symbol table command.
208         DysymtabCmd struct {
209                 LoadCmd
210                 Len            uint32
211                 Ilocalsym      uint32
212                 Nlocalsym      uint32
213                 Iextdefsym     uint32
214                 Nextdefsym     uint32
215                 Iundefsym      uint32
216                 Nundefsym      uint32
217                 Tocoffset      uint32
218                 Ntoc           uint32
219                 Modtaboff      uint32
220                 Nmodtab        uint32
221                 Extrefsymoff   uint32
222                 Nextrefsyms    uint32
223                 Indirectsymoff uint32
224                 Nindirectsyms  uint32
225                 Extreloff      uint32
226                 Nextrel        uint32
227                 Locreloff      uint32
228                 Nlocrel        uint32
229         }
230
231         // A DylibCmd is a Mach-O load dynamic library command.
232         DylibCmd struct {
233                 LoadCmd
234                 Len            uint32
235                 Name           uint32
236                 Time           uint32
237                 CurrentVersion uint32
238                 CompatVersion  uint32
239         }
240
241         // A DylinkerCmd is a Mach-O load dynamic linker or environment command.
242         DylinkerCmd struct {
243                 LoadCmd
244                 Len  uint32
245                 Name uint32
246         }
247
248         // A RpathCmd is a Mach-O rpath command.
249         RpathCmd struct {
250                 LoadCmd
251                 Len  uint32
252                 Path uint32
253         }
254
255         // A Thread is a Mach-O thread state command.
256         Thread struct {
257                 LoadCmd
258                 Len  uint32
259                 Type uint32
260                 Data []uint32
261         }
262
263         // LC_DYLD_INFO, LC_DYLD_INFO_ONLY
264         DyldInfoCmd struct {
265                 LoadCmd
266                 Len                      uint32
267                 RebaseOff, RebaseLen     uint32 // file offset and length; data contains segment indices
268                 BindOff, BindLen         uint32 // file offset and length; data contains segment indices
269                 WeakBindOff, WeakBindLen uint32 // file offset and length
270                 LazyBindOff, LazyBindLen uint32 // file offset and length
271                 ExportOff, ExportLen     uint32 // file offset and length
272         }
273
274         // LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO, LC_FUNCTION_STARTS, LC_DATA_IN_CODE, LC_DYLIB_CODE_SIGN_DRS
275         LinkEditDataCmd struct {
276                 LoadCmd
277                 Len              uint32
278                 DataOff, DataLen uint32 // file offset and length
279         }
280
281         // LC_ENCRYPTION_INFO, LC_ENCRYPTION_INFO_64
282         EncryptionInfoCmd struct {
283                 LoadCmd
284                 Len                uint32
285                 CryptOff, CryptLen uint32 // file offset and length
286                 CryptId            uint32
287         }
288
289         UuidCmd struct {
290                 LoadCmd
291                 Len uint32
292                 Id  [16]byte
293         }
294
295         // TODO Commands below not fully supported yet.
296
297         EntryPointCmd struct {
298                 LoadCmd
299                 Len       uint32
300                 EntryOff  uint64 // file offset
301                 StackSize uint64 // if not zero, initial stack size
302         }
303
304         NoteCmd struct {
305                 LoadCmd
306                 Len            uint32
307                 Name           [16]byte
308                 Offset, Filesz uint64 // file offset and length
309         }
310 )
311
312 const (
313         FlagNoUndefs              HdrFlags = 0x1
314         FlagIncrLink              HdrFlags = 0x2
315         FlagDyldLink              HdrFlags = 0x4
316         FlagBindAtLoad            HdrFlags = 0x8
317         FlagPrebound              HdrFlags = 0x10
318         FlagSplitSegs             HdrFlags = 0x20
319         FlagLazyInit              HdrFlags = 0x40
320         FlagTwoLevel              HdrFlags = 0x80
321         FlagForceFlat             HdrFlags = 0x100
322         FlagNoMultiDefs           HdrFlags = 0x200
323         FlagNoFixPrebinding       HdrFlags = 0x400
324         FlagPrebindable           HdrFlags = 0x800
325         FlagAllModsBound          HdrFlags = 0x1000
326         FlagSubsectionsViaSymbols HdrFlags = 0x2000
327         FlagCanonical             HdrFlags = 0x4000
328         FlagWeakDefines           HdrFlags = 0x8000
329         FlagBindsToWeak           HdrFlags = 0x10000
330         FlagAllowStackExecution   HdrFlags = 0x20000
331         FlagRootSafe              HdrFlags = 0x40000
332         FlagSetuidSafe            HdrFlags = 0x80000
333         FlagNoReexportedDylibs    HdrFlags = 0x100000
334         FlagPIE                   HdrFlags = 0x200000
335         FlagDeadStrippableDylib   HdrFlags = 0x400000
336         FlagHasTLVDescriptors     HdrFlags = 0x800000
337         FlagNoHeapExecution       HdrFlags = 0x1000000
338         FlagAppExtensionSafe      HdrFlags = 0x2000000
339 )
340
341 // A Section32 is a 32-bit Mach-O section header.
342 type Section32 struct {
343         Name     [16]byte
344         Seg      [16]byte
345         Addr     uint32
346         Size     uint32
347         Offset   uint32
348         Align    uint32
349         Reloff   uint32
350         Nreloc   uint32
351         Flags    SecFlags
352         Reserve1 uint32
353         Reserve2 uint32
354 }
355
356 // A Section64 is a 64-bit Mach-O section header.
357 type Section64 struct {
358         Name     [16]byte
359         Seg      [16]byte
360         Addr     uint64
361         Size     uint64
362         Offset   uint32
363         Align    uint32
364         Reloff   uint32
365         Nreloc   uint32
366         Flags    SecFlags
367         Reserve1 uint32
368         Reserve2 uint32
369         Reserve3 uint32
370 }
371
372 // An Nlist32 is a Mach-O 32-bit symbol table entry.
373 type Nlist32 struct {
374         Name  uint32
375         Type  uint8
376         Sect  uint8
377         Desc  uint16
378         Value uint32
379 }
380
381 // An Nlist64 is a Mach-O 64-bit symbol table entry.
382 type Nlist64 struct {
383         Name  uint32
384         Type  uint8
385         Sect  uint8
386         Desc  uint16
387         Value uint64
388 }
389
390 func (n *Nlist64) Put64(b []byte, o binary.ByteOrder) uint32 {
391         o.PutUint32(b[0:], n.Name)
392         b[4] = byte(n.Type)
393         b[5] = byte(n.Sect)
394         o.PutUint16(b[6:], n.Desc)
395         o.PutUint64(b[8:], n.Value)
396         return 8 + 8
397 }
398
399 func (n *Nlist64) Put32(b []byte, o binary.ByteOrder) uint32 {
400         o.PutUint32(b[0:], n.Name)
401         b[4] = byte(n.Type)
402         b[5] = byte(n.Sect)
403         o.PutUint16(b[6:], n.Desc)
404         o.PutUint32(b[8:], uint32(n.Value))
405         return 8 + 4
406 }
407
408 // Regs386 is the Mach-O 386 register structure.
409 type Regs386 struct {
410         AX    uint32
411         BX    uint32
412         CX    uint32
413         DX    uint32
414         DI    uint32
415         SI    uint32
416         BP    uint32
417         SP    uint32
418         SS    uint32
419         FLAGS uint32
420         IP    uint32
421         CS    uint32
422         DS    uint32
423         ES    uint32
424         FS    uint32
425         GS    uint32
426 }
427
428 // RegsAMD64 is the Mach-O AMD64 register structure.
429 type RegsAMD64 struct {
430         AX    uint64
431         BX    uint64
432         CX    uint64
433         DX    uint64
434         DI    uint64
435         SI    uint64
436         BP    uint64
437         SP    uint64
438         R8    uint64
439         R9    uint64
440         R10   uint64
441         R11   uint64
442         R12   uint64
443         R13   uint64
444         R14   uint64
445         R15   uint64
446         IP    uint64
447         FLAGS uint64
448         CS    uint64
449         FS    uint64
450         GS    uint64
451 }
452
453 type intName struct {
454         i uint32
455         s string
456 }
457
458 func stringName(i uint32, names []intName, goSyntax bool) string {
459         for _, n := range names {
460                 if n.i == i {
461                         if goSyntax {
462                                 return "macho." + n.s
463                         }
464                         return n.s
465                 }
466         }
467         return "0x" + strconv.FormatUint(uint64(i), 16)
468 }