1
2
3
4
5
6
7
8 package macho
9
10 import "strconv"
11
12
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
34 type Type uint32
35
36 const (
37 TypeObj Type = 1
38 TypeExec Type = 2
39 )
40
41
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
58 type LoadCmd uint32
59
60 const (
61 LoadCmdSegment LoadCmd = 1
62 LoadCmdSymtab LoadCmd = 2
63 LoadCmdThread LoadCmd = 4
64 LoadCmdUnixThread LoadCmd = 5
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
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
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
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
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
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
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
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
188 type Nlist32 struct {
189 Name uint32
190 Type uint8
191 Sect uint8
192 Desc uint16
193 Value uint32
194 }
195
196
197 type Nlist64 struct {
198 Name uint32
199 Type uint8
200 Sect uint8
201 Desc uint16
202 Value uint64
203 }
204
205
206 type Symbol struct {
207 Name string
208 Type uint8
209 Sect uint8
210 Desc uint16
211 Value uint64
212 }
213
214
215 type Thread struct {
216 Cmd LoadCmd
217 Len uint32
218 Type uint32
219 Data []uint32
220 }
221
222
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
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.Uitoa64(uint64(i))
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.Uitob64(uint64(i), 16)
300 }
301 if i != 0 {
302 s += "+0x" + strconv.Uitob64(uint64(i), 16)
303 }
304 return s
305 }