Chromium Code Reviews| 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 |