@@ -51,8 +51,7 @@ static void FIRCLSBinaryImageChanged(bool added,
51
51
static void FIRCLSBinaryImageRecordSlice (bool added, const FIRCLSBinaryImageDetails imageDetails);
52
52
53
53
#pragma mark - Core API
54
- void FIRCLSBinaryImageInit (FIRCLSBinaryImageReadOnlyContext* roContext,
55
- FIRCLSBinaryImageReadWriteContext* rwContext) {
54
+ void FIRCLSBinaryImageInit (void ) {
56
55
// initialize our node array to all zeros
57
56
memset (&_firclsContext.writable ->binaryImage , 0 , sizeof (_firclsContext.writable ->binaryImage ));
58
57
_firclsContext.writable ->binaryImage .file .fd = -1 ;
@@ -281,6 +280,37 @@ static bool FIRCLSBinaryImageMachOSliceInitSectionByName(FIRCLSMachOSliceRef sli
281
280
return true ;
282
281
}
283
282
283
+ static void FIRCLSPopulateImageDetailWithLoadCommand (uint32_t type,
284
+ uint32_t size,
285
+ const struct load_command* cmd,
286
+ void * context) {
287
+ FIRCLSBinaryImageDetails* details = context;
288
+ switch (type) {
289
+ case LC_UUID: {
290
+ const uint8_t * uuid = FIRCLSMachOGetUUID (cmd);
291
+ FIRCLSSafeHexToString (uuid, 16 , details->uuidString );
292
+ } break ;
293
+ case LC_ENCRYPTION_INFO:
294
+ details->encrypted = FIRCLSMachOGetEncrypted (cmd);
295
+ break ;
296
+ case LC_SEGMENT:
297
+ case LC_SEGMENT_64: {
298
+ FIRCLSMachOSegmentCommand segmentCommand = FIRCLSBinaryImageMachOGetSegmentCommand (cmd);
299
+
300
+ if (strncmp (segmentCommand.segname , SEG_TEXT, sizeof (SEG_TEXT)) == 0 ) {
301
+ details->node .size = segmentCommand.vmsize ;
302
+ }
303
+ } break ;
304
+ case LC_VERSION_MIN_MACOSX:
305
+ case LC_VERSION_MIN_IPHONEOS:
306
+ case LC_VERSION_MIN_TVOS:
307
+ case LC_VERSION_MIN_WATCHOS:
308
+ details->minSDK = FIRCLSMachOGetMinimumOSVersion (cmd);
309
+ details->builtSDK = FIRCLSMachOGetLinkedSDKVersion (cmd);
310
+ break ;
311
+ }
312
+ }
313
+
284
314
static bool FIRCLSBinaryImageFillInImageDetails (FIRCLSBinaryImageDetails* details) {
285
315
if (!FIRCLSIsValidPointer (details)) {
286
316
return false ;
@@ -299,33 +329,8 @@ static bool FIRCLSBinaryImageFillInImageDetails(FIRCLSBinaryImageDetails* detail
299
329
// struct types in a few different places.
300
330
details->node .baseAddress = (void * volatile )details->slice .startAddress ;
301
331
302
- FIRCLSMachOSliceEnumerateLoadCommands (
303
- &details->slice , ^(uint32_t type, uint32_t size, const struct load_command* cmd) {
304
- switch (type) {
305
- case LC_UUID: {
306
- const uint8_t * uuid = FIRCLSMachOGetUUID (cmd);
307
- FIRCLSSafeHexToString (uuid, 16 , details->uuidString );
308
- } break ;
309
- case LC_ENCRYPTION_INFO:
310
- details->encrypted = FIRCLSMachOGetEncrypted (cmd);
311
- break ;
312
- case LC_SEGMENT:
313
- case LC_SEGMENT_64: {
314
- FIRCLSMachOSegmentCommand segmentCommand = FIRCLSBinaryImageMachOGetSegmentCommand (cmd);
315
-
316
- if (strncmp (segmentCommand.segname , SEG_TEXT, sizeof (SEG_TEXT)) == 0 ) {
317
- details->node .size = segmentCommand.vmsize ;
318
- }
319
- } break ;
320
- case LC_VERSION_MIN_MACOSX:
321
- case LC_VERSION_MIN_IPHONEOS:
322
- case LC_VERSION_MIN_TVOS:
323
- case LC_VERSION_MIN_WATCHOS:
324
- details->minSDK = FIRCLSMachOGetMinimumOSVersion (cmd);
325
- details->builtSDK = FIRCLSMachOGetLinkedSDKVersion (cmd);
326
- break ;
327
- }
328
- });
332
+ FIRCLSMachOSliceEnumerateLoadCommands_f (&details->slice , details,
333
+ FIRCLSPopulateImageDetailWithLoadCommand);
329
334
330
335
// We look up the section we want, and we *should* be able to use:
331
336
//
@@ -359,6 +364,19 @@ static bool FIRCLSBinaryImageFillInImageDetails(FIRCLSBinaryImageDetails* detail
359
364
return true ;
360
365
}
361
366
367
+ typedef struct {
368
+ FIRCLSBinaryImageDetails details;
369
+ bool added;
370
+ } FIRCLSImageChange;
371
+
372
+ static void FIRCLSProcessBinaryImageChange (void * context) {
373
+ FIRCLSImageChange* imageChange = context;
374
+ // this is an atomic operation
375
+ FIRCLSBinaryImageStoreNode (imageChange->added , imageChange->details );
376
+ FIRCLSBinaryImageRecordSlice (imageChange->added , imageChange->details );
377
+ free (context);
378
+ }
379
+
362
380
static void FIRCLSBinaryImageChanged (bool added,
363
381
const struct mach_header * mh,
364
382
intptr_t vmaddr_slide) {
@@ -368,14 +386,14 @@ static void FIRCLSBinaryImageChanged(bool added,
368
386
369
387
imageDetails.slice = FIRCLSMachOSliceWithHeader ((void *)mh);
370
388
imageDetails.vmaddr_slide = vmaddr_slide;
389
+ // fill imageDetails fields using slice & vmaddr_slide
371
390
FIRCLSBinaryImageFillInImageDetails (&imageDetails);
372
391
373
- // Do these time-consuming operations on a background queue
374
- dispatch_async (FIRCLSGetBinaryImageQueue (), ^{
375
- // this is an atomic operation
376
- FIRCLSBinaryImageStoreNode (added, imageDetails);
377
- FIRCLSBinaryImageRecordSlice (added, imageDetails);
378
- });
392
+ FIRCLSImageChange* change = malloc (sizeof (FIRCLSImageChange));
393
+ if (!change) return ;
394
+ change->added = added;
395
+ change->details = imageDetails;
396
+ dispatch_async_f (FIRCLSGetBinaryImageQueue (), change, FIRCLSProcessBinaryImageChange);
379
397
}
380
398
381
399
#pragma mark - In-Memory Storage
@@ -390,6 +408,7 @@ static void FIRCLSBinaryImageStoreNode(bool added, FIRCLSBinaryImageDetails imag
390
408
return ;
391
409
}
392
410
411
+ // looking for an empty space if an image added
393
412
void * searchAddress = NULL ;
394
413
bool success = false ;
395
414
FIRCLSBinaryImageRuntimeNode* nodes = _firclsContext.writable ->binaryImage .nodes ;
0 commit comments