|
36 | 36 |
|
37 | 37 | #include "../bounds.h" |
38 | 38 | #include "../loader.h" |
| 39 | +#include "../dwarf/leb128.h" |
39 | 40 |
|
40 | 41 | #include "../../callstack_parser.h" |
41 | 42 |
|
@@ -245,6 +246,26 @@ static inline void machoFile_addFunction(struct pair_funcFile function, va_list |
245 | 246 | vector_pairFuncFile_push_back(&self->functions, function); |
246 | 247 | } |
247 | 248 |
|
| 249 | +static inline int machoFile_uint64Compare(uint64_t* lhs, uint64_t* rhs) { |
| 250 | + if (*lhs == *rhs) return 0; |
| 251 | + |
| 252 | + return *lhs < *rhs ? -1 : +1; |
| 253 | +} |
| 254 | + |
| 255 | +static inline bool machoFile_handleFunctionStarts(struct machoFile* self, struct linkedit_data_command* command, const void* baseAddress, bool bitsReversed) { |
| 256 | + uint32_t offset = macho_maybeSwap(32, bitsReversed, command->dataoff); |
| 257 | + uint32_t size = macho_maybeSwap(32, bitsReversed, command->datasize); |
| 258 | + |
| 259 | + const void* bytes = baseAddress + offset; |
| 260 | + uint64_t funcAddr = self->addressOffset; |
| 261 | + for (size_t i = 0; i < size;) { |
| 262 | + funcAddr += getULEB128(bytes, &i); |
| 263 | + vector_uint64_push_back(&self->functionStarts, funcAddr); |
| 264 | + } |
| 265 | + vector_uint64_sort(&self->functionStarts, &machoFile_uint64Compare); |
| 266 | + return true; |
| 267 | +} |
| 268 | + |
248 | 269 | /** |
249 | 270 | * Parses a Mach-O file into the given Mach-O file abstraction object. |
250 | 271 | * |
@@ -277,6 +298,10 @@ static inline bool machoFile_parseFileImpl(struct machoFile * self, |
277 | 298 | memcpy(&self->uuid, &((struct uuid_command*) ((void*) lc))->uuid, 16); |
278 | 299 | result = true; |
279 | 300 | break; |
| 301 | + |
| 302 | + case LC_FUNCTION_STARTS: |
| 303 | + result = machoFile_handleFunctionStarts(self, (void*) lc, baseAddress, bitsReversed); |
| 304 | + break; |
280 | 305 | } |
281 | 306 | if (!result) { |
282 | 307 | return false; |
@@ -318,6 +343,10 @@ static inline bool machoFile_parseFileImpl64(struct machoFile * self, |
318 | 343 | memcpy(&self->uuid, &((struct uuid_command*) ((void*) lc))->uuid, 16); |
319 | 344 | result = true; |
320 | 345 | break; |
| 346 | + |
| 347 | + case LC_FUNCTION_STARTS: |
| 348 | + result = machoFile_handleFunctionStarts(self, (void*) lc, baseAddress, bitsReversed); |
| 349 | + break; |
321 | 350 | } |
322 | 351 | if (!result) { |
323 | 352 | return false; |
|
0 commit comments