OLD | NEW |
1 // Copyright (c) 2006, Google Inc. | 1 // Copyright (c) 2006, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 15 matching lines...) Expand all Loading... |
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | 29 |
30 // macho_id.cc: Functions to gather identifying information from a macho file | 30 // macho_id.cc: Functions to gather identifying information from a macho file |
31 // | 31 // |
32 // See macho_id.h for documentation | 32 // See macho_id.h for documentation |
33 // | 33 // |
34 // Author: Dan Waylonis | 34 // Author: Dan Waylonis |
35 | 35 |
36 extern "C" { // necessary for Leopard | 36 |
37 #include <fcntl.h> | 37 #include <fcntl.h> |
38 #include <mach-o/loader.h> | 38 #include <mach-o/loader.h> |
39 #include <mach-o/swap.h> | 39 #include <stdio.h> |
40 #include <stdio.h> | 40 #include <stdlib.h> |
41 #include <stdlib.h> | 41 #include <string.h> |
42 #include <string.h> | 42 #include <sys/time.h> |
43 #include <sys/time.h> | 43 #include <sys/types.h> |
44 #include <sys/types.h> | 44 #include <unistd.h> |
45 #include <unistd.h> | |
46 } | |
47 | 45 |
48 #include "common/mac/macho_id.h" | 46 #include "common/mac/macho_id.h" |
49 #include "common/mac/macho_walker.h" | 47 #include "common/mac/macho_walker.h" |
50 #include "common/mac/macho_utilities.h" | 48 #include "common/mac/macho_utilities.h" |
51 | 49 |
52 namespace MacFileUtilities { | 50 namespace MacFileUtilities { |
53 | 51 |
54 using google_breakpad::MD5Init; | 52 using google_breakpad::MD5Init; |
55 using google_breakpad::MD5Update; | 53 using google_breakpad::MD5Update; |
56 using google_breakpad::MD5Final; | 54 using google_breakpad::MD5Final; |
57 | 55 |
58 MachoID::MachoID(const char *path) | 56 MachoID::MachoID(const char *path) |
59 : memory_(0), | 57 : memory_(0), |
60 memory_size_(0), | 58 memory_size_(0), |
61 crc_(0), | 59 crc_(0), |
62 md5_context_(), | 60 md5_context_(), |
63 update_function_(NULL) { | 61 update_function_(NULL) { |
64 strlcpy(path_, path, sizeof(path_)); | 62 snprintf(path_, sizeof(path_), "%s", path); |
65 } | 63 } |
66 | 64 |
67 MachoID::MachoID(const char *path, void *memory, size_t size) | 65 MachoID::MachoID(const char *path, void *memory, size_t size) |
68 : memory_(memory), | 66 : memory_(memory), |
69 memory_size_(size), | 67 memory_size_(size), |
70 crc_(0), | 68 crc_(0), |
71 md5_context_(), | 69 md5_context_(), |
72 update_function_(NULL) { | 70 update_function_(NULL) { |
73 strlcpy(path_, path, sizeof(path_)); | 71 snprintf(path_, sizeof(path_), "%s", path); |
74 } | 72 } |
75 | 73 |
76 MachoID::~MachoID() { | 74 MachoID::~MachoID() { |
77 } | 75 } |
78 | 76 |
79 // The CRC info is from http://en.wikipedia.org/wiki/Adler-32 | 77 // The CRC info is from http://en.wikipedia.org/wiki/Adler-32 |
80 // With optimizations from http://www.zlib.net/ | 78 // With optimizations from http://www.zlib.net/ |
81 | 79 |
82 // The largest prime smaller than 65536 | 80 // The largest prime smaller than 65536 |
83 #define MOD_ADLER 65521 | 81 #define MOD_ADLER 65521 |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 bool swap, void *context) { | 252 bool swap, void *context) { |
255 MachoID *macho_id = (MachoID *)context; | 253 MachoID *macho_id = (MachoID *)context; |
256 | 254 |
257 if (cmd->cmd == LC_SEGMENT) { | 255 if (cmd->cmd == LC_SEGMENT) { |
258 struct segment_command seg; | 256 struct segment_command seg; |
259 | 257 |
260 if (!walker->ReadBytes(&seg, sizeof(seg), offset)) | 258 if (!walker->ReadBytes(&seg, sizeof(seg), offset)) |
261 return false; | 259 return false; |
262 | 260 |
263 if (swap) | 261 if (swap) |
264 swap_segment_command(&seg, NXHostByteOrder()); | 262 breakpad_swap_segment_command(&seg); |
265 | 263 |
266 struct mach_header_64 header; | 264 struct mach_header_64 header; |
267 off_t header_offset; | 265 off_t header_offset; |
268 | 266 |
269 if (!walker->CurrentHeader(&header, &header_offset)) | 267 if (!walker->CurrentHeader(&header, &header_offset)) |
270 return false; | 268 return false; |
271 | 269 |
272 // Process segments that have sections: | 270 // Process segments that have sections: |
273 // (e.g., __TEXT, __DATA, __IMPORT, __OBJC) | 271 // (e.g., __TEXT, __DATA, __IMPORT, __OBJC) |
274 offset += sizeof(struct segment_command); | 272 offset += sizeof(struct segment_command); |
275 struct section sec; | 273 struct section sec; |
276 for (unsigned long i = 0; i < seg.nsects; ++i) { | 274 for (unsigned long i = 0; i < seg.nsects; ++i) { |
277 if (!walker->ReadBytes(&sec, sizeof(sec), offset)) | 275 if (!walker->ReadBytes(&sec, sizeof(sec), offset)) |
278 return false; | 276 return false; |
279 | 277 |
280 if (swap) | 278 if (swap) |
281 swap_section(&sec, 1, NXHostByteOrder()); | 279 breakpad_swap_section(&sec, 1); |
282 | 280 |
283 // sections of type S_ZEROFILL are "virtual" and contain no data | 281 // sections of type S_ZEROFILL are "virtual" and contain no data |
284 // in the file itself | 282 // in the file itself |
285 if ((sec.flags & SECTION_TYPE) != S_ZEROFILL && sec.offset != 0) | 283 if ((sec.flags & SECTION_TYPE) != S_ZEROFILL && sec.offset != 0) |
286 macho_id->Update(walker, header_offset + sec.offset, sec.size); | 284 macho_id->Update(walker, header_offset + sec.offset, sec.size); |
287 | 285 |
288 offset += sizeof(struct section); | 286 offset += sizeof(struct section); |
289 } | 287 } |
290 } else if (cmd->cmd == LC_SEGMENT_64) { | 288 } else if (cmd->cmd == LC_SEGMENT_64) { |
291 struct segment_command_64 seg64; | 289 struct segment_command_64 seg64; |
292 | 290 |
293 if (!walker->ReadBytes(&seg64, sizeof(seg64), offset)) | 291 if (!walker->ReadBytes(&seg64, sizeof(seg64), offset)) |
294 return false; | 292 return false; |
295 | 293 |
296 if (swap) | 294 if (swap) |
297 breakpad_swap_segment_command_64(&seg64, NXHostByteOrder()); | 295 breakpad_swap_segment_command_64(&seg64); |
298 | 296 |
299 struct mach_header_64 header; | 297 struct mach_header_64 header; |
300 off_t header_offset; | 298 off_t header_offset; |
301 | 299 |
302 if (!walker->CurrentHeader(&header, &header_offset)) | 300 if (!walker->CurrentHeader(&header, &header_offset)) |
303 return false; | 301 return false; |
304 | 302 |
305 // Process segments that have sections: | 303 // Process segments that have sections: |
306 // (e.g., __TEXT, __DATA, __IMPORT, __OBJC) | 304 // (e.g., __TEXT, __DATA, __IMPORT, __OBJC) |
307 offset += sizeof(struct segment_command_64); | 305 offset += sizeof(struct segment_command_64); |
308 struct section_64 sec64; | 306 struct section_64 sec64; |
309 for (unsigned long i = 0; i < seg64.nsects; ++i) { | 307 for (unsigned long i = 0; i < seg64.nsects; ++i) { |
310 if (!walker->ReadBytes(&sec64, sizeof(sec64), offset)) | 308 if (!walker->ReadBytes(&sec64, sizeof(sec64), offset)) |
311 return false; | 309 return false; |
312 | 310 |
313 if (swap) | 311 if (swap) |
314 breakpad_swap_section_64(&sec64, 1, NXHostByteOrder()); | 312 breakpad_swap_section_64(&sec64, 1); |
315 | 313 |
316 // sections of type S_ZEROFILL are "virtual" and contain no data | 314 // sections of type S_ZEROFILL are "virtual" and contain no data |
317 // in the file itself | 315 // in the file itself |
318 if ((sec64.flags & SECTION_TYPE) != S_ZEROFILL && sec64.offset != 0) | 316 if ((sec64.flags & SECTION_TYPE) != S_ZEROFILL && sec64.offset != 0) |
319 macho_id->Update(walker, | 317 macho_id->Update(walker, |
320 header_offset + sec64.offset, | 318 header_offset + sec64.offset, |
321 (size_t)sec64.size); | 319 (size_t)sec64.size); |
322 | 320 |
323 offset += sizeof(struct section_64); | 321 offset += sizeof(struct section_64); |
324 } | 322 } |
325 } | 323 } |
326 | 324 |
327 // Continue processing | 325 // Continue processing |
328 return true; | 326 return true; |
329 } | 327 } |
330 | 328 |
331 // static | 329 // static |
332 bool MachoID::UUIDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset, | 330 bool MachoID::UUIDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset, |
333 bool swap, void *context) { | 331 bool swap, void *context) { |
334 if (cmd->cmd == LC_UUID) { | 332 if (cmd->cmd == LC_UUID) { |
335 struct breakpad_uuid_command *uuid_cmd = | 333 struct breakpad_uuid_command *uuid_cmd = |
336 (struct breakpad_uuid_command *)context; | 334 (struct breakpad_uuid_command *)context; |
337 | 335 |
338 if (!walker->ReadBytes(uuid_cmd, sizeof(struct breakpad_uuid_command), | 336 if (!walker->ReadBytes(uuid_cmd, sizeof(struct breakpad_uuid_command), |
339 offset)) | 337 offset)) |
340 return false; | 338 return false; |
341 | 339 |
342 if (swap) | 340 if (swap) |
343 breakpad_swap_uuid_command(uuid_cmd, NXHostByteOrder()); | 341 breakpad_swap_uuid_command(uuid_cmd); |
344 | 342 |
345 return false; | 343 return false; |
346 } | 344 } |
347 | 345 |
348 // Continue processing | 346 // Continue processing |
349 return true; | 347 return true; |
350 } | 348 } |
351 | 349 |
352 // static | 350 // static |
353 bool MachoID::IDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset, | 351 bool MachoID::IDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset, |
354 bool swap, void *context) { | 352 bool swap, void *context) { |
355 if (cmd->cmd == LC_ID_DYLIB) { | 353 if (cmd->cmd == LC_ID_DYLIB) { |
356 struct dylib_command *dylib_cmd = (struct dylib_command *)context; | 354 struct dylib_command *dylib_cmd = (struct dylib_command *)context; |
357 | 355 |
358 if (!walker->ReadBytes(dylib_cmd, sizeof(struct dylib_command), offset)) | 356 if (!walker->ReadBytes(dylib_cmd, sizeof(struct dylib_command), offset)) |
359 return false; | 357 return false; |
360 | 358 |
361 if (swap) | 359 if (swap) |
362 swap_dylib_command(dylib_cmd, NXHostByteOrder()); | 360 breakpad_swap_dylib_command(dylib_cmd); |
363 | 361 |
364 return false; | 362 return false; |
365 } | 363 } |
366 | 364 |
367 // Continue processing | 365 // Continue processing |
368 return true; | 366 return true; |
369 } | 367 } |
370 | 368 |
371 } // namespace MacFileUtilities | 369 } // namespace MacFileUtilities |
OLD | NEW |