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 extern "C" { // necessary for Leopard |
Mark Mentovai
2015/09/11 15:49:50
1. This was probably never true.
2. Nobody cares a
Ted Mielczarek
2015/09/15 12:58:36
Done.
| |
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> | |
40 #include <stdio.h> | 39 #include <stdio.h> |
41 #include <stdlib.h> | 40 #include <stdlib.h> |
42 #include <string.h> | 41 #include <string.h> |
43 #include <sys/time.h> | 42 #include <sys/time.h> |
44 #include <sys/types.h> | 43 #include <sys/types.h> |
45 #include <unistd.h> | 44 #include <unistd.h> |
46 } | 45 } |
47 | 46 |
48 #include "common/mac/macho_id.h" | 47 #include "common/mac/macho_id.h" |
49 #include "common/mac/macho_walker.h" | 48 #include "common/mac/macho_walker.h" |
50 #include "common/mac/macho_utilities.h" | 49 #include "common/mac/macho_utilities.h" |
51 | 50 |
52 namespace MacFileUtilities { | 51 namespace MacFileUtilities { |
53 | 52 |
54 using google_breakpad::MD5Init; | 53 using google_breakpad::MD5Init; |
55 using google_breakpad::MD5Update; | 54 using google_breakpad::MD5Update; |
56 using google_breakpad::MD5Final; | 55 using google_breakpad::MD5Final; |
57 | 56 |
58 MachoID::MachoID(const char *path) | 57 MachoID::MachoID(const char *path) |
59 : memory_(0), | 58 : memory_(0), |
60 memory_size_(0), | 59 memory_size_(0), |
61 crc_(0), | 60 crc_(0), |
62 md5_context_(), | 61 md5_context_(), |
63 update_function_(NULL) { | 62 update_function_(NULL) { |
64 strlcpy(path_, path, sizeof(path_)); | 63 strncpy(path_, path, sizeof(path_) - 1); |
65 } | 64 } |
66 | 65 |
67 MachoID::MachoID(const char *path, void *memory, size_t size) | 66 MachoID::MachoID(const char *path, void *memory, size_t size) |
68 : memory_(memory), | 67 : memory_(memory), |
69 memory_size_(size), | 68 memory_size_(size), |
70 crc_(0), | 69 crc_(0), |
71 md5_context_(), | 70 md5_context_(), |
72 update_function_(NULL) { | 71 update_function_(NULL) { |
73 strlcpy(path_, path, sizeof(path_)); | 72 strncpy(path_, path, sizeof(path_) - 1); |
74 } | 73 } |
75 | 74 |
76 MachoID::~MachoID() { | 75 MachoID::~MachoID() { |
77 } | 76 } |
78 | 77 |
79 // The CRC info is from http://en.wikipedia.org/wiki/Adler-32 | 78 // The CRC info is from http://en.wikipedia.org/wiki/Adler-32 |
80 // With optimizations from http://www.zlib.net/ | 79 // With optimizations from http://www.zlib.net/ |
81 | 80 |
82 // The largest prime smaller than 65536 | 81 // The largest prime smaller than 65536 |
83 #define MOD_ADLER 65521 | 82 #define MOD_ADLER 65521 |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
254 bool swap, void *context) { | 253 bool swap, void *context) { |
255 MachoID *macho_id = (MachoID *)context; | 254 MachoID *macho_id = (MachoID *)context; |
256 | 255 |
257 if (cmd->cmd == LC_SEGMENT) { | 256 if (cmd->cmd == LC_SEGMENT) { |
258 struct segment_command seg; | 257 struct segment_command seg; |
259 | 258 |
260 if (!walker->ReadBytes(&seg, sizeof(seg), offset)) | 259 if (!walker->ReadBytes(&seg, sizeof(seg), offset)) |
261 return false; | 260 return false; |
262 | 261 |
263 if (swap) | 262 if (swap) |
264 swap_segment_command(&seg, NXHostByteOrder()); | 263 breakpad_swap_segment_command(&seg); |
265 | 264 |
266 struct mach_header_64 header; | 265 struct mach_header_64 header; |
267 off_t header_offset; | 266 off_t header_offset; |
268 | 267 |
269 if (!walker->CurrentHeader(&header, &header_offset)) | 268 if (!walker->CurrentHeader(&header, &header_offset)) |
270 return false; | 269 return false; |
271 | 270 |
272 // Process segments that have sections: | 271 // Process segments that have sections: |
273 // (e.g., __TEXT, __DATA, __IMPORT, __OBJC) | 272 // (e.g., __TEXT, __DATA, __IMPORT, __OBJC) |
274 offset += sizeof(struct segment_command); | 273 offset += sizeof(struct segment_command); |
275 struct section sec; | 274 struct section sec; |
276 for (unsigned long i = 0; i < seg.nsects; ++i) { | 275 for (unsigned long i = 0; i < seg.nsects; ++i) { |
277 if (!walker->ReadBytes(&sec, sizeof(sec), offset)) | 276 if (!walker->ReadBytes(&sec, sizeof(sec), offset)) |
278 return false; | 277 return false; |
279 | 278 |
280 if (swap) | 279 if (swap) |
281 swap_section(&sec, 1, NXHostByteOrder()); | 280 breakpad_swap_section(&sec, 1); |
282 | 281 |
283 // sections of type S_ZEROFILL are "virtual" and contain no data | 282 // sections of type S_ZEROFILL are "virtual" and contain no data |
284 // in the file itself | 283 // in the file itself |
285 if ((sec.flags & SECTION_TYPE) != S_ZEROFILL && sec.offset != 0) | 284 if ((sec.flags & SECTION_TYPE) != S_ZEROFILL && sec.offset != 0) |
286 macho_id->Update(walker, header_offset + sec.offset, sec.size); | 285 macho_id->Update(walker, header_offset + sec.offset, sec.size); |
287 | 286 |
288 offset += sizeof(struct section); | 287 offset += sizeof(struct section); |
289 } | 288 } |
290 } else if (cmd->cmd == LC_SEGMENT_64) { | 289 } else if (cmd->cmd == LC_SEGMENT_64) { |
291 struct segment_command_64 seg64; | 290 struct segment_command_64 seg64; |
292 | 291 |
293 if (!walker->ReadBytes(&seg64, sizeof(seg64), offset)) | 292 if (!walker->ReadBytes(&seg64, sizeof(seg64), offset)) |
294 return false; | 293 return false; |
295 | 294 |
296 if (swap) | 295 if (swap) |
297 breakpad_swap_segment_command_64(&seg64, NXHostByteOrder()); | 296 breakpad_swap_segment_command_64(&seg64); |
298 | 297 |
299 struct mach_header_64 header; | 298 struct mach_header_64 header; |
300 off_t header_offset; | 299 off_t header_offset; |
301 | 300 |
302 if (!walker->CurrentHeader(&header, &header_offset)) | 301 if (!walker->CurrentHeader(&header, &header_offset)) |
303 return false; | 302 return false; |
304 | 303 |
305 // Process segments that have sections: | 304 // Process segments that have sections: |
306 // (e.g., __TEXT, __DATA, __IMPORT, __OBJC) | 305 // (e.g., __TEXT, __DATA, __IMPORT, __OBJC) |
307 offset += sizeof(struct segment_command_64); | 306 offset += sizeof(struct segment_command_64); |
308 struct section_64 sec64; | 307 struct section_64 sec64; |
309 for (unsigned long i = 0; i < seg64.nsects; ++i) { | 308 for (unsigned long i = 0; i < seg64.nsects; ++i) { |
310 if (!walker->ReadBytes(&sec64, sizeof(sec64), offset)) | 309 if (!walker->ReadBytes(&sec64, sizeof(sec64), offset)) |
311 return false; | 310 return false; |
312 | 311 |
313 if (swap) | 312 if (swap) |
314 breakpad_swap_section_64(&sec64, 1, NXHostByteOrder()); | 313 breakpad_swap_section_64(&sec64, 1); |
315 | 314 |
316 // sections of type S_ZEROFILL are "virtual" and contain no data | 315 // sections of type S_ZEROFILL are "virtual" and contain no data |
317 // in the file itself | 316 // in the file itself |
318 if ((sec64.flags & SECTION_TYPE) != S_ZEROFILL && sec64.offset != 0) | 317 if ((sec64.flags & SECTION_TYPE) != S_ZEROFILL && sec64.offset != 0) |
319 macho_id->Update(walker, | 318 macho_id->Update(walker, |
320 header_offset + sec64.offset, | 319 header_offset + sec64.offset, |
321 (size_t)sec64.size); | 320 (size_t)sec64.size); |
322 | 321 |
323 offset += sizeof(struct section_64); | 322 offset += sizeof(struct section_64); |
324 } | 323 } |
325 } | 324 } |
326 | 325 |
327 // Continue processing | 326 // Continue processing |
328 return true; | 327 return true; |
329 } | 328 } |
330 | 329 |
331 // static | 330 // static |
332 bool MachoID::UUIDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset, | 331 bool MachoID::UUIDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset, |
333 bool swap, void *context) { | 332 bool swap, void *context) { |
334 if (cmd->cmd == LC_UUID) { | 333 if (cmd->cmd == LC_UUID) { |
335 struct breakpad_uuid_command *uuid_cmd = | 334 struct breakpad_uuid_command *uuid_cmd = |
336 (struct breakpad_uuid_command *)context; | 335 (struct breakpad_uuid_command *)context; |
337 | 336 |
338 if (!walker->ReadBytes(uuid_cmd, sizeof(struct breakpad_uuid_command), | 337 if (!walker->ReadBytes(uuid_cmd, sizeof(struct breakpad_uuid_command), |
339 offset)) | 338 offset)) |
340 return false; | 339 return false; |
341 | 340 |
342 if (swap) | 341 if (swap) |
343 breakpad_swap_uuid_command(uuid_cmd, NXHostByteOrder()); | 342 breakpad_swap_uuid_command(uuid_cmd); |
344 | 343 |
345 return false; | 344 return false; |
346 } | 345 } |
347 | 346 |
348 // Continue processing | 347 // Continue processing |
349 return true; | 348 return true; |
350 } | 349 } |
351 | 350 |
352 // static | 351 // static |
353 bool MachoID::IDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset, | 352 bool MachoID::IDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset, |
354 bool swap, void *context) { | 353 bool swap, void *context) { |
355 if (cmd->cmd == LC_ID_DYLIB) { | 354 if (cmd->cmd == LC_ID_DYLIB) { |
356 struct dylib_command *dylib_cmd = (struct dylib_command *)context; | 355 struct dylib_command *dylib_cmd = (struct dylib_command *)context; |
357 | 356 |
358 if (!walker->ReadBytes(dylib_cmd, sizeof(struct dylib_command), offset)) | 357 if (!walker->ReadBytes(dylib_cmd, sizeof(struct dylib_command), offset)) |
359 return false; | 358 return false; |
360 | 359 |
361 if (swap) | 360 if (swap) |
362 swap_dylib_command(dylib_cmd, NXHostByteOrder()); | 361 breakpad_swap_dylib_command(dylib_cmd); |
363 | 362 |
364 return false; | 363 return false; |
365 } | 364 } |
366 | 365 |
367 // Continue processing | 366 // Continue processing |
368 return true; | 367 return true; |
369 } | 368 } |
370 | 369 |
371 } // namespace MacFileUtilities | 370 } // namespace MacFileUtilities |
OLD | NEW |