Source file src/pkg/debug/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 "strconv"
11
12 // A FileHeader represents a Mach-O file header.
13 type FileHeader struct {
14 Magic uint32
15 Cpu Cpu
16 SubCpu uint32
17 Type Type
18 Ncmd uint32
19 Cmdsz uint32
20 Flags uint32
21 }
22
23 const (
24 fileHeaderSize32 = 7 * 4
25 fileHeaderSize64 = 8 * 4
26 )
27
28 const (
29 Magic32 uint32 = 0xfeedface
30 Magic64 uint32 = 0xfeedfacf
31 )
32
33 // A Type is a Mach-O file type, either an object or an executable.
34 type Type uint32
35
36 const (
37 TypeObj Type = 1
38 TypeExec Type = 2
39 )
40
41 // A Cpu is a Mach-O cpu type.
42 type Cpu uint32
43
44 const (
45 Cpu386 Cpu = 7
46 CpuAmd64 Cpu = Cpu386 + 1<<24
47 )
48
49 var cpuStrings = []intName{
50 {uint32(Cpu386), "Cpu386"},
51 {uint32(CpuAmd64), "CpuAmd64"},
52 }
53
54 func (i Cpu) String() string { return stringName(uint32(i), cpuStrings, false) }
55 func (i Cpu) GoString() string { return stringName(uint32(i), cpuStrings, true) }
56
57 // A LoadCmd is a Mach-O load command.
58 type LoadCmd uint32
59
60 const (
61 LoadCmdSegment LoadCmd = 1
62 LoadCmdSymtab LoadCmd = 2
63 LoadCmdThread LoadCmd = 4
64 LoadCmdUnixThread LoadCmd = 5 // thread+stack
65 LoadCmdDysymtab LoadCmd = 11
66 LoadCmdDylib LoadCmd = 12
67 LoadCmdDylinker LoadCmd = 15
68 LoadCmdSegment64 LoadCmd = 25
69 )
70
71 var cmdStrings = []intName{
72 {uint32(LoadCmdSegment), "LoadCmdSegment"},
73 {uint32(LoadCmdThread), "LoadCmdThread"},
74 {uint32(LoadCmdUnixThread), "LoadCmdUnixThread"},
75 {uint32(LoadCmdDylib), "LoadCmdDylib"},
76 {uint32(LoadCmdSegment64), "LoadCmdSegment64"},
77 }
78
79 func (i LoadCmd) String() string { return stringName(uint32(i), cmdStrings, false) }
80 func (i LoadCmd) GoString() string { return stringName(uint32(i), cmdStrings, true) }
81
82 // A Segment64 is a 64-bit Mach-O segment load command.
83 type Segment64 struct {
84 Cmd LoadCmd
85 Len uint32
86 Name [16]byte
87 Addr uint64
88 Memsz uint64
89 Offset uint64
90 Filesz uint64
91 Maxprot uint32
92 Prot uint32
93 Nsect uint32
94 Flag uint32
95 }
96
97 // A Segment32 is a 32-bit Mach-O segment load command.
98 type Segment32 struct {
99 Cmd LoadCmd
100 Len uint32
101 Name [16]byte
102 Addr uint32
103 Memsz uint32
104 Offset uint32
105 Filesz uint32
106 Maxprot uint32
107 Prot uint32
108 Nsect uint32
109 Flag uint32
110 }
111
112 // A DylibCmd is a Mach-O load dynamic library command.
113 type DylibCmd struct {
114 Cmd LoadCmd
115 Len uint32
116 Name uint32
117 Time uint32
118 CurrentVersion uint32
119 CompatVersion uint32
120 }
121
122 // A Section32 is a 32-bit Mach-O section header.
123 type Section32 struct {
124 Name [16]byte
125 Seg [16]byte
126 Addr uint32
127 Size uint32
128 Offset uint32
129 Align uint32
130 Reloff uint32
131 Nreloc uint32
132 Flags uint32
133 Reserve1 uint32
134 Reserve2 uint32
135 }
136
137 // A Section32 is a 64-bit Mach-O section header.
138 type Section64 struct {
139 Name [16]byte
140 Seg [16]byte
141 Addr uint64
142 Size uint64
143 Offset uint32
144 Align uint32
145 Reloff uint32
146 Nreloc uint32
147 Flags uint32
148 Reserve1 uint32
149 Reserve2 uint32
150 Reserve3 uint32
151 }
152
153 // A SymtabCmd is a Mach-O symbol table command.
154 type SymtabCmd struct {
155 Cmd LoadCmd
156 Len uint32
157 Symoff uint32
158 Nsyms uint32
159 Stroff uint32
160 Strsize uint32
161 }
162
163 // A DysymtabCmd is a Mach-O dynamic symbol table command.
164 type DysymtabCmd struct {
165 Cmd LoadCmd
166 Len uint32
167 Ilocalsym uint32
168 Nlocalsym uint32
169 Iextdefsym uint32
170 Nextdefsym uint32
171 Iundefsym uint32
172 Nundefsym uint32
173 Tocoffset uint32
174 Ntoc uint32
175 Modtaboff uint32
176 Nmodtab uint32
177 Extrefsymoff uint32
178 Nextrefsyms uint32
179 Indirectsymoff uint32
180 Nindirectsyms uint32
181 Extreloff uint32
182 Nextrel uint32
183 Locreloff uint32
184 Nlocrel uint32
185 }
186
187 // An Nlist32 is a Mach-O 32-bit symbol table entry.
188 type Nlist32 struct {
189 Name uint32
190 Type uint8
191 Sect uint8
192 Desc uint16
193 Value uint32
194 }
195
196 // An Nlist64 is a Mach-O 64-bit symbol table entry.
197 type Nlist64 struct {
198 Name uint32
199 Type uint8
200 Sect uint8
201 Desc uint16
202 Value uint64
203 }
204
205 // A Symbol is a Mach-O 32-bit or 64-bit symbol table entry.
206 type Symbol struct {
207 Name string
208 Type uint8
209 Sect uint8
210 Desc uint16
211 Value uint64
212 }
213
214 // A Thread is a Mach-O thread state command.
215 type Thread struct {
216 Cmd LoadCmd
217 Len uint32
218 Type uint32
219 Data []uint32
220 }
221
222 // Regs386 is the Mach-O 386 register structure.
223 type Regs386 struct {
224 AX uint32
225 BX uint32
226 CX uint32
227 DX uint32
228 DI uint32
229 SI uint32
230 BP uint32
231 SP uint32
232 SS uint32
233 FLAGS uint32
234 IP uint32
235 CS uint32
236 DS uint32
237 ES uint32
238 FS uint32
239 GS uint32
240 }
241
242 // RegsAMD64 is the Mach-O AMD64 register structure.
243 type RegsAMD64 struct {
244 AX uint64
245 BX uint64
246 CX uint64
247 DX uint64
248 DI uint64
249 SI uint64
250 BP uint64
251 SP uint64
252 R8 uint64
253 R9 uint64
254 R10 uint64
255 R11 uint64
256 R12 uint64
257 R13 uint64
258 R14 uint64
259 R15 uint64
260 IP uint64
261 FLAGS uint64
262 CS uint64
263 FS uint64
264 GS uint64
265 }
266
267 type intName struct {
268 i uint32
269 s string
270 }
271
272 func stringName(i uint32, names []intName, goSyntax bool) string {
273 for _, n := range names {
274 if n.i == i {
275 if goSyntax {
276 return "macho." + n.s
277 }
278 return n.s
279 }
280 }
281 return strconv.FormatUint(uint64(i), 10)
282 }
283
284 func flagName(i uint32, names []intName, goSyntax bool) string {
285 s := ""
286 for _, n := range names {
287 if n.i&i == n.i {
288 if len(s) > 0 {
289 s += "+"
290 }
291 if goSyntax {
292 s += "macho."
293 }
294 s += n.s
295 i -= n.i
296 }
297 }
298 if len(s) == 0 {
299 return "0x" + strconv.FormatUint(uint64(i), 16)
300 }
301 if i != 0 {
302 s += "+0x" + strconv.FormatUint(uint64(i), 16)
303 }
304 return s
305 }