Add support for dyldcache headers up to dyld-1042.1 (#3536)

Newer dyldcaches have more fields in the header. This change adds
heuristics for determining the version and reading and displaying the
newer fields if available.
This commit is contained in:
Florian Märkl 2023-05-29 19:27:45 +02:00 committed by GitHub
parent c5978e158c
commit ea04e76d1b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 752 additions and 92 deletions

View file

@ -16,7 +16,10 @@ static RzDyldLocSym *rz_dyld_locsym_new(RzDyldCache *cache);
* \param magic zero-terminated string from the beginning of some file
*/
RZ_API bool rz_dyldcache_check_magic(const char *magic) {
return !strcmp(magic, "dyld_v1 arm64") || !strcmp(magic, "dyld_v1 arm64e") || !strcmp(magic, "dyld_v1 x86_64") || !strcmp(magic, "dyld_v1 x86_64h");
return !strncmp(magic, "dyld_v1 arm64", 16) ||
!strncmp(magic, "dyld_v1 arm64e", 16) ||
!strncmp(magic, "dyld_v1 x86_64", 16) ||
!strncmp(magic, "dyld_v1 x86_64h", 16);
}
static ut64 va2pa(uint64_t addr, ut32 n_maps, cache_map_t *maps, RzBuffer *cache_buf, ut64 slide, ut32 *offset, ut32 *left) {
@ -49,33 +52,173 @@ static void free_bin(RzDyldBinImage *bin) {
free(bin);
}
static cache_hdr_t *read_cache_header(RzBuffer *cache_buf, ut64 offset) {
static RzDyldCacheHeader *read_cache_header(RzBuffer *cache_buf, ut64 offset) {
if (!cache_buf) {
return NULL;
}
cache_hdr_t *hdr = RZ_NEW0(cache_hdr_t);
RzDyldCacheHeader *hdr = RZ_NEW0(RzDyldCacheHeader);
if (!hdr) {
return NULL;
}
ut64 size = sizeof(cache_hdr_t);
if (rz_buf_fread_at(cache_buf, offset, (ut8 *)hdr, "16c4i7l16clii4l", 1) != size) {
free(hdr);
return NULL;
}
if (!rz_dyldcache_check_magic(hdr->magic)) {
free(hdr);
return NULL;
ut64 cur = offset;
if (!rz_buf_read_offset(cache_buf, &cur, (ut8 *)hdr->magic, sizeof(hdr->magic)) ||
!rz_dyldcache_check_magic(hdr->magic) ||
!rz_buf_read_le32_offset(cache_buf, &cur, &hdr->mappingOffset) ||
!rz_buf_read_le32_offset(cache_buf, &cur, &hdr->mappingCount) ||
!rz_buf_read_le32_offset(cache_buf, &cur, &hdr->imagesOffset) ||
!rz_buf_read_le32_offset(cache_buf, &cur, &hdr->imagesCount) ||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->dyldBaseAddress) ||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->codeSignatureOffset) ||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->codeSignatureSize) ||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->slideInfoOffset) ||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->slideInfoSize) ||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->localSymbolsOffset) ||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->localSymbolsSize) ||
!rz_buf_read_offset(cache_buf, &cur, hdr->uuid, sizeof(hdr->uuid)) ||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->cacheType) ||
!rz_buf_read_le32_offset(cache_buf, &cur, &hdr->branchPoolsOffset) ||
!rz_buf_read_le32_offset(cache_buf, &cur, &hdr->branchPoolsCount) ||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->accelerateInfoAddr) ||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->accelerateInfoSize) ||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->imagesTextOffset) ||
!rz_buf_read_le64_offset(cache_buf, &cur, &hdr->imagesTextCount)) {
goto fail;
}
if (!hdr->imagesCount && !hdr->imagesOffset) {
if (!rz_buf_read_le32_at(cache_buf, 0x1c0 + offset, &hdr->imagesOffset) || !rz_buf_read_le32_at(cache_buf, 0x1c4 + offset, &hdr->imagesCount)) {
free(hdr);
return NULL;
}
// Size of the header was continuously expanded during versions as newer fields got added.
// There is no dedicated header size stored in the file, but in practice the mappingOffset is
// directly after the header, so we use this as an indicator on how far we may read.
ut64 hdr_end_offset = offset + hdr->mappingOffset;
#define READ_OR_FINISH(bits, dst) \
do { \
if (cur + bits / 8 > hdr_end_offset || !rz_buf_read_le##bits##_offset(cache_buf, &cur, dst)) { \
goto finish; \
} \
} while (0)
READ_OR_FINISH(64, &hdr->patchInfoAddr);
READ_OR_FINISH(64, &hdr->patchInfoSize);
READ_OR_FINISH(64, &hdr->otherImageGroupAddrUnused);
READ_OR_FINISH(64, &hdr->otherImageGroupSizeUnused);
READ_OR_FINISH(64, &hdr->progClosuresAddr);
READ_OR_FINISH(64, &hdr->progClosuresSize);
READ_OR_FINISH(64, &hdr->progClosuresTrieAddr);
READ_OR_FINISH(64, &hdr->progClosuresTrieSize);
READ_OR_FINISH(32, &hdr->platform);
ut32 flags;
READ_OR_FINISH(32, &flags);
hdr->formatVersion = flags & rz_num_bitmask(8);
flags >>= 8;
hdr->dylibsExpectedOnDisk = flags & 1;
flags >>= 1;
hdr->simulator = flags & 1;
flags >>= 1;
hdr->locallyBuiltCache = flags & 1;
flags >>= 1;
hdr->builtFromChainedFixups = flags & 1;
flags >>= 1;
hdr->padding = flags;
READ_OR_FINISH(64, &hdr->sharedRegionStart);
READ_OR_FINISH(64, &hdr->sharedRegionSize);
READ_OR_FINISH(64, &hdr->maxSlide);
READ_OR_FINISH(64, &hdr->dylibsImageArrayAddr);
READ_OR_FINISH(64, &hdr->dylibsImageArraySize);
READ_OR_FINISH(64, &hdr->dylibsTrieAddr);
READ_OR_FINISH(64, &hdr->dylibsTrieSize);
READ_OR_FINISH(64, &hdr->otherImageArrayAddr);
READ_OR_FINISH(64, &hdr->otherImageArraySize);
READ_OR_FINISH(64, &hdr->otherTrieAddr);
READ_OR_FINISH(64, &hdr->otherTrieSize);
READ_OR_FINISH(32, &hdr->mappingWithSlideOffset);
READ_OR_FINISH(32, &hdr->mappingWithSlideCount);
READ_OR_FINISH(64, &hdr->dylibsPBLStateArrayAddrUnused);
READ_OR_FINISH(64, &hdr->dylibsPBLSetAddr);
READ_OR_FINISH(64, &hdr->programsPBLSetPoolAddr);
READ_OR_FINISH(64, &hdr->programsPBLSetPoolSize);
READ_OR_FINISH(64, &hdr->programTrieAddr);
READ_OR_FINISH(32, &hdr->programTrieSize);
READ_OR_FINISH(32, &hdr->osVersion);
READ_OR_FINISH(32, &hdr->altPlatform);
READ_OR_FINISH(32, &hdr->altOsVersion);
READ_OR_FINISH(64, &hdr->swiftOptsOffset);
READ_OR_FINISH(64, &hdr->swiftOptsSize);
READ_OR_FINISH(32, &hdr->subCacheArrayOffset);
READ_OR_FINISH(32, &hdr->subCacheArrayCount);
if (cur + sizeof(hdr->symbolFileUUID) > hdr_end_offset ||
!rz_buf_read_offset(cache_buf, &cur, hdr->symbolFileUUID, sizeof(hdr->symbolFileUUID))) {
goto finish;
}
READ_OR_FINISH(64, &hdr->rosettaReadOnlyAddr);
READ_OR_FINISH(64, &hdr->rosettaReadOnlySize);
READ_OR_FINISH(64, &hdr->rosettaReadWriteAddr);
READ_OR_FINISH(64, &hdr->rosettaReadWriteSize);
// This intentionally overrides the imagesOffset/imagesCount above as these
// two fields were moved down here in dyld-940:
READ_OR_FINISH(32, &hdr->imagesOffset);
READ_OR_FINISH(32, &hdr->imagesCount);
READ_OR_FINISH(32, &hdr->cacheSubType);
cur += 4; // 8-alignment/padding
READ_OR_FINISH(64, &hdr->objcOptsOffset);
READ_OR_FINISH(64, &hdr->objcOptsSize);
READ_OR_FINISH(64, &hdr->cacheAtlasOffset);
READ_OR_FINISH(64, &hdr->cacheAtlasSize);
READ_OR_FINISH(64, &hdr->dynamicDataOffset);
READ_OR_FINISH(64, &hdr->dynamicDataMaxSize);
#undef READ_OR_FINISH
finish:
return hdr;
fail:
free(hdr);
return NULL;
}
RZ_API RZ_NONNULL const char *rz_dyldcache_get_platform_str(RzDyldCache *cache) {
switch (cache->hdr->platform) {
case 1:
return "macOS";
case 2:
return "iOS";
case 3:
return "tvOS";
case 4:
return "watchOS";
case 5:
return "bridgeOS";
case 6:
return "iOSMac";
case 7:
return "iOS_simulator";
case 8:
return "tvOS_simulator";
case 9:
return "watchOS_simulator";
case 10:
return "driverKit";
default:
return "darwin"; // unknown
}
}
RZ_API RZ_NONNULL const char *rz_dyldcache_get_type_str(RzDyldCache *cache) {
switch (cache->hdr->cacheType) {
case 0:
return "development";
case 1:
return "production";
case 2:
return "multi-cache";
default:
return "unknown";
}
}
#define SHIFT_MAYBE(x) \
@ -90,7 +233,7 @@ static void populate_cache_headers(RzDyldCache *cache) {
return;
}
cache_hdr_t *h;
RzDyldCacheHeader *h;
ut64 offsets[MAX_N_HDR];
ut64 offset = 0;
do {
@ -119,7 +262,7 @@ static void populate_cache_headers(RzDyldCache *cache) {
goto beach;
}
cache->hdr = RZ_NEWS0(cache_hdr_t, cache->n_hdr);
cache->hdr = RZ_NEWS0(RzDyldCacheHeader, cache->n_hdr);
if (!cache->hdr) {
cache->n_hdr = 0;
goto beach;
@ -136,12 +279,12 @@ static void populate_cache_headers(RzDyldCache *cache) {
ut32 i = 0;
RzListIter *iter;
cache_hdr_t *item;
RzDyldCacheHeader *item;
rz_list_foreach (hdrs, iter, item) {
if (i >= cache->n_hdr) {
break;
}
memcpy(&cache->hdr[i++], item, sizeof(cache_hdr_t));
memcpy(&cache->hdr[i++], item, sizeof(RzDyldCacheHeader));
}
beach:
@ -157,7 +300,7 @@ static void populate_cache_maps(RzDyldCache *cache) {
ut32 n_maps = 0;
ut64 max_count = 0;
for (i = 0; i < cache->n_hdr; i++) {
cache_hdr_t *hdr = &cache->hdr[i];
RzDyldCacheHeader *hdr = &cache->hdr[i];
if (!hdr->mappingCount || !hdr->mappingOffset) {
continue;
}
@ -181,7 +324,7 @@ static void populate_cache_maps(RzDyldCache *cache) {
ut32 last_idx = UT32_MAX;
ut64 max_address = 0;
for (i = 0; i < cache->n_hdr; i++) {
cache_hdr_t *hdr = &cache->hdr[i];
RzDyldCacheHeader *hdr = &cache->hdr[i];
cache->maps_index[i] = next_map;
if (!hdr->mappingCount || !hdr->mappingOffset) {
@ -213,8 +356,8 @@ static void populate_cache_maps(RzDyldCache *cache) {
}
}
static cache_accel_t *read_cache_accel(RzBuffer *cache_buf, cache_hdr_t *hdr, cache_map_t *maps) {
if (!cache_buf || !hdr || !hdr->accelerateInfoSize || !hdr->accelerateInfoAddr) {
static cache_accel_t *read_cache_accel(RzBuffer *cache_buf, RzDyldCacheHeader *hdr, cache_map_t *maps) {
if (!cache_buf || !hdr || !rz_dyldcache_header_may_have_accel(hdr) || !hdr->accelerateInfoSize || !hdr->accelerateInfoAddr) {
return NULL;
}
@ -315,7 +458,7 @@ beach:
return result;
}
static cache_img_t *read_cache_images(RzBuffer *cache_buf, cache_hdr_t *hdr, ut64 hdr_offset) {
static cache_img_t *read_cache_images(RzBuffer *cache_buf, RzDyldCacheHeader *hdr, ut64 hdr_offset) {
if (!cache_buf || !hdr) {
return NULL;
}
@ -385,7 +528,7 @@ static void match_bin_entries(RzDyldCache *cache, void *entries) {
RZ_FREE(imgs);
}
static cache_imgxtr_t *read_cache_imgextra(RzBuffer *cache_buf, cache_hdr_t *hdr, cache_accel_t *accel) {
static cache_imgxtr_t *read_cache_imgextra(RzBuffer *cache_buf, RzDyldCacheHeader *hdr, cache_accel_t *accel) {
if (!cache_buf || !hdr || !hdr->imagesCount || !accel || !accel->imageExtrasCount || !accel->imagesExtrasOffset) {
return NULL;
}
@ -418,7 +561,7 @@ static int string_contains(const void *a, const void *b) {
return !strstr((const char *)a, (const char *)b);
}
static HtPU *create_path_to_index(RzBuffer *cache_buf, cache_img_t *img, cache_hdr_t *hdr) {
static HtPU *create_path_to_index(RzBuffer *cache_buf, cache_img_t *img, RzDyldCacheHeader *hdr) {
HtPU *path_to_idx = ht_pu_new0();
if (!path_to_idx) {
return NULL;
@ -510,7 +653,7 @@ static RzList /*<RzDyldBinImage *>*/ *create_cache_bins(RzDyldCache *cache) {
ut32 i;
for (i = 0; i < cache->n_hdr; i++) {
cache_hdr_t *hdr = &cache->hdr[i];
RzDyldCacheHeader *hdr = &cache->hdr[i];
ut64 hdr_offset = cache->hdr_offset[i];
ut64 symbols_off = cache->symbols_off_base - hdr_offset;
ut32 maps_index = cache->maps_index[i];
@ -1270,7 +1413,7 @@ static RzDyldLocSym *rz_dyld_locsym_new(RzDyldCache *cache) {
ut32 i;
for (i = 0; i < cache->n_hdr; i++) {
cache_hdr_t *hdr = &cache->hdr[i];
RzDyldCacheHeader *hdr = &cache->hdr[i];
if (!hdr || !hdr->localSymbolsSize || !hdr->localSymbolsOffset) {
continue;
}

View file

@ -12,6 +12,131 @@
#include "mach0.h"
typedef struct rz_dyld_cache_header_t {
char magic[16];
ut32 mappingOffset;
ut32 mappingCount;
ut32 imagesOffset;
ut32 imagesCount;
ut64 dyldBaseAddress;
ut64 codeSignatureOffset;
ut64 codeSignatureSize;
ut64 slideInfoOffset;
ut64 slideInfoSize;
ut64 localSymbolsOffset;
ut64 localSymbolsSize;
ut8 uuid[16];
ut64 cacheType;
ut32 branchPoolsOffset;
ut32 branchPoolsCount;
union {
struct {
ut64 accelerateInfoAddr;
ut64 accelerateInfoSize;
}; ///< used if rz_dyldcache_header_may_have_accel() == true
struct {
ut64 dyldInCacheMH;
ut64 dyldInCacheEntry;
}; ///< used if rz_dyldcache_header_may_have_accel() == false
};
ut64 imagesTextOffset;
ut64 imagesTextCount;
ut64 patchInfoAddr;
ut64 patchInfoSize;
ut64 otherImageGroupAddrUnused;
ut64 otherImageGroupSizeUnused;
ut64 progClosuresAddr;
ut64 progClosuresSize;
ut64 progClosuresTrieAddr;
ut64 progClosuresTrieSize;
ut32 platform;
ut32 formatVersion : 8,
dylibsExpectedOnDisk : 1,
simulator : 1,
locallyBuiltCache : 1,
builtFromChainedFixups : 1,
padding : 20;
ut64 sharedRegionStart;
ut64 sharedRegionSize;
ut64 maxSlide;
ut64 dylibsImageArrayAddr;
ut64 dylibsImageArraySize;
ut64 dylibsTrieAddr;
ut64 dylibsTrieSize;
ut64 otherImageArrayAddr;
ut64 otherImageArraySize;
ut64 otherTrieAddr;
ut64 otherTrieSize;
ut32 mappingWithSlideOffset;
ut32 mappingWithSlideCount;
// offset = 0x140
// below added in dyld-940
ut64 dylibsPBLStateArrayAddrUnused;
ut64 dylibsPBLSetAddr;
ut64 programsPBLSetPoolAddr;
ut64 programsPBLSetPoolSize;
ut64 programTrieAddr;
ut32 programTrieSize;
ut32 osVersion;
ut32 altPlatform;
ut32 altOsVersion;
ut64 swiftOptsOffset;
ut64 swiftOptsSize;
ut32 subCacheArrayOffset;
ut32 subCacheArrayCount;
ut8 symbolFileUUID[16];
ut64 rosettaReadOnlyAddr;
ut64 rosettaReadOnlySize;
ut64 rosettaReadWriteAddr;
ut64 rosettaReadWriteSize;
// ut32 imagesOffset; (consolidated with imageOffset above)
// ut32 imagesCount; (consolidated with imagesCount above)
// offset = 0x1c8
// below added in dyld-1042.1
ut32 cacheSubType;
ut64 objcOptsOffset;
ut64 objcOptsSize;
ut64 cacheAtlasOffset;
ut64 cacheAtlasSize;
ut64 dynamicDataOffset;
ut64 dynamicDataMaxSize;
// offset = 0x200
} RzDyldCacheHeader;
typedef enum rz_dyld_cache_header_version {
RZ_DYLD_CACHE_HEADER_BEFORE_940,
RZ_DYLD_CACHE_HEADER_940_OR_AFTER,
RZ_DYLD_CACHE_HEADER_1042_1_OR_AFTER
} RzDyldCacheHeaderVersion;
/**
* Guess the dyld version that \p hdr was created from
*/
static inline RzDyldCacheHeaderVersion rz_dyldcache_header_version(RzDyldCacheHeader *hdr) {
// Fields were added during different dyld versions, so we can use the size of the header to guess
// the version. Even though there is no explicit header size field, mappingOffset is usually directly
// after the header, so we use this to measure size.
if (hdr->mappingOffset < 0x1c8) {
return RZ_DYLD_CACHE_HEADER_BEFORE_940;
} else if (hdr->mappingOffset < 0x200) {
return RZ_DYLD_CACHE_HEADER_940_OR_AFTER;
} else {
return RZ_DYLD_CACHE_HEADER_1042_1_OR_AFTER;
}
}
/**
* Determine if the accelerateInfoAddr/accelerateInfoSize fields are available in the header,
* as opposed to dyldInCacheMH/dyldInCacheEntry
*/
static inline bool rz_dyldcache_header_may_have_accel(RzDyldCacheHeader *hdr) {
return rz_dyldcache_header_version(hdr) < RZ_DYLD_CACHE_HEADER_1042_1_OR_AFTER;
}
typedef struct rz_dyld_rebase_info_t {
ut8 version;
ut64 slide;
@ -93,7 +218,7 @@ typedef struct rz_bin_dyld_image_t {
typedef struct rz_dyldcache_t {
ut8 magic[8];
cache_hdr_t *hdr;
RzDyldCacheHeader *hdr;
ut64 *hdr_offset;
ut64 symbols_off_base;
ut32 *maps_index;
@ -113,6 +238,8 @@ typedef struct rz_dyldcache_t {
RZ_API bool rz_dyldcache_check_magic(const char *magic);
RZ_API RzDyldCache *rz_dyldcache_new_buf(RzBuffer *buf);
RZ_API void rz_dyldcache_free(RzDyldCache *cache);
RZ_API RZ_NONNULL const char *rz_dyldcache_get_platform_str(RzDyldCache *cache);
RZ_API RZ_NONNULL const char *rz_dyldcache_get_type_str(RzDyldCache *cache);
RZ_API ut64 rz_dyldcache_va2pa(RzDyldCache *cache, uint64_t vaddr, ut32 *offset, ut32 *left);
RZ_API ut64 rz_dyldcache_get_slide(RzDyldCache *cache);
RZ_API objc_cache_opt_info *rz_dyldcache_get_objc_opt_info(RzBinFile *bf, RzDyldCache *cache);

View file

@ -189,47 +189,6 @@ struct arm_thread_state64 {
ut32 cpsr;
};
/* Cache header */
struct cache_header {
char version[16];
ut32 baseaddroff; // mappingOffset
ut32 mappingCount;
ut32 startaddr;
ut32 numlibs;
ut64 dyldaddr;
ut64 codeSignatureOffset;
ut64 codeSignatureSize;
ut64 slideInfoOffset;
ut64 slideInfoSize;
ut64 localSymbolsOffset;
ut64 localSymbolsSize;
};
// dupe?
typedef struct {
char magic[16];
uint32_t mappingOffset;
uint32_t mappingCount;
uint32_t imagesOffset;
uint32_t imagesCount;
uint64_t dyldBaseAddress;
uint64_t codeSignatureOffset;
uint64_t codeSignatureSize;
uint64_t slideInfoOffset;
uint64_t slideInfoSize;
uint64_t localSymbolsOffset;
uint64_t localSymbolsSize;
uint8_t uuid[16];
uint64_t cacheType;
uint32_t branchPoolsOffset;
uint32_t branchPoolsCount;
uint64_t accelerateInfoAddr;
uint64_t accelerateInfoSize;
uint64_t imagesTextOffset;
uint64_t imagesTextCount;
} cache_hdr_t;
typedef struct {
uint8_t uuid[16];
uint64_t loadAddress;

View file

@ -111,7 +111,7 @@ static RzBinInfo *info(RzBinFile *bf) {
}
ret->file = strdup(bf->file);
ret->bclass = strdup("dyldcache");
ret->os = strdup("Darwin"); // TODO: actual OS info is available. See the platform member of struct dyld_cache_header in dyld source.
ret->os = strdup(rz_dyldcache_get_platform_str(cache));
if (strstr(cache->hdr->magic, "x86_64")) {
ret->arch = strdup("x86");
ret->bits = 64;
@ -121,7 +121,8 @@ static RzBinInfo *info(RzBinFile *bf) {
}
ret->machine = strdup(ret->arch);
ret->subsystem = strdup("xnu");
ret->type = strdup("library-cache");
ret->guid = rz_hex_bin2strdup((ut8 *)cache->hdr->uuid, sizeof(cache->hdr->uuid));
ret->type = strdup(rz_dyldcache_get_type_str(cache));
ret->has_va = true;
ret->big_endian = big_endian;
ret->dbg_info = 0;
@ -515,6 +516,21 @@ static void header(RzBinFile *bf) {
}
pj_o(pj);
pj_k(pj, "version");
RzDyldCacheHeaderVersion ver = rz_dyldcache_header_version(cache->hdr);
switch (ver) {
case RZ_DYLD_CACHE_HEADER_BEFORE_940:
pj_s(pj, "<940");
break;
case RZ_DYLD_CACHE_HEADER_940_OR_AFTER:
pj_s(pj, "940");
break;
case RZ_DYLD_CACHE_HEADER_1042_1_OR_AFTER:
pj_s(pj, "1042.1");
break;
}
pj_k(pj, "header");
pj_o(pj);
pj_ks(pj, "magic", cache->hdr->magic);
@ -535,10 +551,73 @@ static void header(RzBinFile *bf) {
pj_ks(pj, "cacheType", (cache->hdr->cacheType == 0) ? "development" : "production");
pj_kn(pj, "branchPoolsOffset", cache->hdr->branchPoolsOffset);
pj_kn(pj, "branchPoolsCount", cache->hdr->branchPoolsCount);
pj_kn(pj, "accelerateInfoAddr", cache->hdr->accelerateInfoAddr + slide);
pj_kn(pj, "accelerateInfoSize", cache->hdr->accelerateInfoSize);
if (rz_dyldcache_header_may_have_accel(cache->hdr)) {
pj_kn(pj, "accelerateInfoAddr", cache->hdr->accelerateInfoAddr + slide);
pj_kn(pj, "accelerateInfoSize", cache->hdr->accelerateInfoSize);
} else {
pj_kn(pj, "dyldInCacheMH", cache->hdr->dyldInCacheMH);
pj_kn(pj, "dyldInCacheEntry", cache->hdr->dyldInCacheEntry);
}
pj_kn(pj, "imagesTextOffset", cache->hdr->imagesTextOffset);
pj_kn(pj, "imagesTextCount", cache->hdr->imagesTextCount);
pj_kn(pj, "patchInfoAddr", cache->hdr->patchInfoAddr);
pj_kn(pj, "patchInfoSize", cache->hdr->patchInfoSize);
pj_kn(pj, "otherImageGroupAddrUnused", cache->hdr->otherImageGroupAddrUnused);
pj_kn(pj, "otherImageGroupSizeUnused", cache->hdr->otherImageGroupSizeUnused);
pj_kn(pj, "progClosuresAddr", cache->hdr->progClosuresAddr);
pj_kn(pj, "progClosuresSize", cache->hdr->progClosuresSize);
pj_kn(pj, "progClosuresTrieAddr", cache->hdr->progClosuresTrieAddr);
pj_kn(pj, "progClosuresTrieSize", cache->hdr->progClosuresTrieSize);
pj_kn(pj, "platform", cache->hdr->platform);
pj_kn(pj, "formatVersion", cache->hdr->formatVersion);
pj_kn(pj, "dylibsExpectedOnDisk", cache->hdr->dylibsExpectedOnDisk);
pj_kn(pj, "simulator", cache->hdr->simulator);
pj_kn(pj, "locallyBuiltCache", cache->hdr->locallyBuiltCache);
pj_kn(pj, "builtFromChainedFixups", cache->hdr->builtFromChainedFixups);
pj_kn(pj, "padding", cache->hdr->padding);
pj_kn(pj, "sharedRegionStart", cache->hdr->sharedRegionStart);
pj_kn(pj, "sharedRegionSize", cache->hdr->sharedRegionSize);
pj_kn(pj, "maxSlide", cache->hdr->maxSlide);
pj_kn(pj, "dylibsImageArrayAddr", cache->hdr->dylibsImageArrayAddr);
pj_kn(pj, "dylibsImageArraySize", cache->hdr->dylibsImageArraySize);
pj_kn(pj, "dylibsTrieAddr", cache->hdr->dylibsTrieAddr);
pj_kn(pj, "dylibsTrieSize", cache->hdr->dylibsTrieSize);
pj_kn(pj, "otherImageArrayAddr", cache->hdr->otherImageArrayAddr);
pj_kn(pj, "otherImageArraySize", cache->hdr->otherImageArraySize);
pj_kn(pj, "otherTrieAddr", cache->hdr->otherTrieAddr);
pj_kn(pj, "otherTrieSize", cache->hdr->otherTrieSize);
pj_kn(pj, "mappingWithSlideOffset", cache->hdr->mappingWithSlideOffset);
pj_kn(pj, "mappingWithSlideCount", cache->hdr->mappingWithSlideCount);
if (ver >= RZ_DYLD_CACHE_HEADER_940_OR_AFTER) {
pj_kn(pj, "dylibsPBLStateArrayAddrUnused", cache->hdr->dylibsPBLStateArrayAddrUnused);
pj_kn(pj, "dylibsPBLSetAddr", cache->hdr->dylibsPBLSetAddr);
pj_kn(pj, "programsPBLSetPoolAddr", cache->hdr->programsPBLSetPoolAddr);
pj_kn(pj, "programsPBLSetPoolSize", cache->hdr->programsPBLSetPoolSize);
pj_kn(pj, "programTrieAddr", cache->hdr->programTrieAddr);
pj_kn(pj, "programTrieSize", cache->hdr->programTrieSize);
pj_kn(pj, "osVersion", cache->hdr->osVersion);
pj_kn(pj, "altPlatform", cache->hdr->altPlatform);
pj_kn(pj, "altOsVersion", cache->hdr->altOsVersion);
pj_kn(pj, "swiftOptsOffset", cache->hdr->swiftOptsOffset);
pj_kn(pj, "swiftOptsSize", cache->hdr->swiftOptsSize);
pj_kn(pj, "subCacheArrayOffset", cache->hdr->subCacheArrayOffset);
pj_kn(pj, "subCacheArrayCount", cache->hdr->subCacheArrayCount);
rz_hex_bin2str(cache->hdr->symbolFileUUID, sizeof(cache->hdr->symbolFileUUID), uuidstr);
pj_ks(pj, "symbolFileUUID", uuidstr);
pj_kn(pj, "rosettaReadOnlyAddr", cache->hdr->rosettaReadOnlyAddr);
pj_kn(pj, "rosettaReadOnlySize", cache->hdr->rosettaReadOnlySize);
pj_kn(pj, "rosettaReadWriteAddr", cache->hdr->rosettaReadWriteAddr);
pj_kn(pj, "rosettaReadWriteSize", cache->hdr->rosettaReadWriteSize);
}
if (ver >= RZ_DYLD_CACHE_HEADER_1042_1_OR_AFTER) {
pj_kn(pj, "cacheSubType", cache->hdr->cacheSubType);
pj_kn(pj, "objcOptsOffset", cache->hdr->objcOptsOffset);
pj_kn(pj, "objcOptsSize", cache->hdr->objcOptsSize);
pj_kn(pj, "cacheAtlasOffset", cache->hdr->cacheAtlasOffset);
pj_kn(pj, "cacheAtlasSize", cache->hdr->cacheAtlasSize);
pj_kn(pj, "dynamicDataOffset", cache->hdr->dynamicDataOffset);
pj_kn(pj, "dynamicDataMaxSize", cache->hdr->dynamicDataMaxSize);
}
pj_end(pj);
if (cache->accel) {

View file

@ -4,7 +4,7 @@ CMDS=<<EOF
i
is
iS
iH
iH~{}
oml
pi 4@ sym._what_is_cool
EOF
@ -17,7 +17,7 @@ mode r-x
format dyldcache
iorw false
block 0x100
type library-cache
type production
arch arm
cpu N/A
baddr 0x180000000
@ -30,14 +30,14 @@ compiler N/A
dbg_file N/A
endian LE
hdr.csum N/A
guid N/A
guid 857bce1a017e34649909d58ee21cf8dc
intrp N/A
laddr 0x00000000
lang N/A
machine arm
maxopsz 4
minopsz 4
os Darwin
os macOS
cc N/A
pcalign 4
rpath N/A
@ -66,7 +66,90 @@ paddr size vaddr vsize align perm name
0x00004fb0 0x50 0x180004fb0 0x50 0x0 -r-x lib_liba-1.0.dylib.2.__TEXT.__unwind_info
0x00008fa0 0x18 0x180008fa0 0x18 0x0 -r-x lib_libb-1.0.dylib.0.__TEXT.__text
0x00008fb8 0x48 0x180008fb8 0x48 0x0 -r-x lib_libb-1.0.dylib.1.__TEXT.__unwind_info
{"header":{"magic":"dyld_v1 arm64","mappingOffset":320,"mappingCount":3,"imagesOffset":656,"imagesCount":2,"dyldBaseAddress":0,"codeSignatureOffset":196608,"codeSignatureSize":16384,"slideInfoOffset":0,"slideInfoSize":0,"localSymbolsOffset":0,"localSymbolsSize":0,"uuid":"857bce1a017e34649909d58ee21cf8dc","cacheType":"production","branchPoolsOffset":0,"branchPoolsCount":0,"accelerateInfoAddr":0,"accelerateInfoSize":0,"imagesTextOffset":720,"imagesTextCount":2},"slideInfo":[{"start":98304,"end":114688,"version":2,"slide":0,"page_starts_count":4,"page_extras_count":0,"delta_mask":72056494526300160,"value_mask":18374687579183251455,"value_add":0,"delta_shift":38,"page_size":4096}],"images":[{"uuid":"ccbf29d455693a1592314e14d41a542a","address":6442455040,"textSegmentSize":16384,"path":"/usr/lib/liba-1.0.dylib","name":"liba-1.0.dylib"},{"uuid":"60d2f3d644a2391087503a56a3d8ff07","address":6442471424,"textSegmentSize":16384,"path":"/usr/lib/libb-1.0.dylib","name":"libb-1.0.dylib"}]}
{
"version": "<940",
"header": {
"magic": "dyld_v1 arm64",
"mappingOffset": 320,
"mappingCount": 3,
"imagesOffset": 656,
"imagesCount": 2,
"dyldBaseAddress": 0,
"codeSignatureOffset": 196608,
"codeSignatureSize": 16384,
"slideInfoOffset": 0,
"slideInfoSize": 0,
"localSymbolsOffset": 0,
"localSymbolsSize": 0,
"uuid": "857bce1a017e34649909d58ee21cf8dc",
"cacheType": "production",
"branchPoolsOffset": 0,
"branchPoolsCount": 0,
"accelerateInfoAddr": 0,
"accelerateInfoSize": 0,
"imagesTextOffset": 720,
"imagesTextCount": 2,
"patchInfoAddr": 6509723956,
"patchInfoSize": 80,
"otherImageGroupAddrUnused": 0,
"otherImageGroupSizeUnused": 0,
"progClosuresAddr": 6509740032,
"progClosuresSize": 0,
"progClosuresTrieAddr": 6509740032,
"progClosuresTrieSize": 8,
"platform": 1,
"formatVersion": 10,
"dylibsExpectedOnDisk": 0,
"simulator": 0,
"locallyBuiltCache": 1,
"builtFromChainedFixups": 0,
"padding": 0,
"sharedRegionStart": 6442450944,
"sharedRegionSize": 4294967296,
"maxSlide": 2147385344,
"dylibsImageArrayAddr": 6509723648,
"dylibsImageArraySize": 240,
"dylibsTrieAddr": 6509723888,
"dylibsTrieSize": 68,
"otherImageArrayAddr": 0,
"otherImageArraySize": 0,
"otherTrieAddr": 0,
"otherTrieSize": 0,
"mappingWithSlideOffset": 488,
"mappingWithSlideCount": 3
},
"slideInfo": [
{
"start": 98304,
"end": 114688,
"version": 2,
"slide": 0,
"page_starts_count": 4,
"page_extras_count": 0,
"delta_mask": 72056494526300160,
"value_mask": 18374687579183251455,
"value_add": 0,
"delta_shift": 38,
"page_size": 4096
}
],
"images": [
{
"uuid": "ccbf29d455693a1592314e14d41a542a",
"address": 6442455040,
"textSegmentSize": 16384,
"path": "/usr/lib/liba-1.0.dylib",
"name": "liba-1.0.dylib"
},
{
"uuid": "60d2f3d644a2391087503a56a3d8ff07",
"address": 6442471424,
"textSegmentSize": 16384,
"path": "/usr/lib/libb-1.0.dylib",
"name": "libb-1.0.dylib"
}
]
}
1 fd: 4 +0x00000000 0x180000000 - 0x180017fff r-x vmap.cache_map.0
2 fd: 4 +0x00018000 0x182018000 - 0x18201bfff r-- vmap.cache_map.1
3 fd: 4 +0x0001c000 0x18401c000 - 0x18402ffff r-- vmap.cache_map.2
@ -85,7 +168,7 @@ o bins/dyldcache/dyld_shared_cache_arm64-macOS
i
is
iS
iH
iH~{}
oml
pi 4@ sym._what_is_cool
EOF
@ -98,7 +181,7 @@ mode r-x
format dyldcache
iorw false
block 0x100
type library-cache
type production
arch arm
cpu N/A
baddr 0x180000000
@ -111,14 +194,14 @@ compiler N/A
dbg_file N/A
endian LE
hdr.csum N/A
guid N/A
guid 857bce1a017e34649909d58ee21cf8dc
intrp N/A
laddr 0x00000000
lang N/A
machine arm
maxopsz 4
minopsz 4
os Darwin
os macOS
cc N/A
pcalign 4
rpath N/A
@ -144,7 +227,90 @@ paddr size vaddr vsize align perm name
0x00004f60 0x48 0x180004f60 0x48 0x0 -r-x lib_liba-1.0.dylib.0.__TEXT.__text
0x00004fa8 0x6 0x180004fa8 0x6 0x0 -r-x lib_liba-1.0.dylib.1.__TEXT.__cstring
0x00004fb0 0x50 0x180004fb0 0x50 0x0 -r-x lib_liba-1.0.dylib.2.__TEXT.__unwind_info
{"header":{"magic":"dyld_v1 arm64","mappingOffset":320,"mappingCount":3,"imagesOffset":656,"imagesCount":2,"dyldBaseAddress":0,"codeSignatureOffset":196608,"codeSignatureSize":16384,"slideInfoOffset":0,"slideInfoSize":0,"localSymbolsOffset":0,"localSymbolsSize":0,"uuid":"857bce1a017e34649909d58ee21cf8dc","cacheType":"production","branchPoolsOffset":0,"branchPoolsCount":0,"accelerateInfoAddr":0,"accelerateInfoSize":0,"imagesTextOffset":720,"imagesTextCount":2},"slideInfo":[{"start":98304,"end":114688,"version":2,"slide":0,"page_starts_count":4,"page_extras_count":0,"delta_mask":72056494526300160,"value_mask":18374687579183251455,"value_add":0,"delta_shift":38,"page_size":4096}],"images":[{"uuid":"ccbf29d455693a1592314e14d41a542a","address":6442455040,"textSegmentSize":16384,"path":"/usr/lib/liba-1.0.dylib","name":"liba-1.0.dylib"},{"uuid":"60d2f3d644a2391087503a56a3d8ff07","address":6442471424,"textSegmentSize":16384,"path":"/usr/lib/libb-1.0.dylib","name":"libb-1.0.dylib"}]}
{
"version": "<940",
"header": {
"magic": "dyld_v1 arm64",
"mappingOffset": 320,
"mappingCount": 3,
"imagesOffset": 656,
"imagesCount": 2,
"dyldBaseAddress": 0,
"codeSignatureOffset": 196608,
"codeSignatureSize": 16384,
"slideInfoOffset": 0,
"slideInfoSize": 0,
"localSymbolsOffset": 0,
"localSymbolsSize": 0,
"uuid": "857bce1a017e34649909d58ee21cf8dc",
"cacheType": "production",
"branchPoolsOffset": 0,
"branchPoolsCount": 0,
"accelerateInfoAddr": 0,
"accelerateInfoSize": 0,
"imagesTextOffset": 720,
"imagesTextCount": 2,
"patchInfoAddr": 6509723956,
"patchInfoSize": 80,
"otherImageGroupAddrUnused": 0,
"otherImageGroupSizeUnused": 0,
"progClosuresAddr": 6509740032,
"progClosuresSize": 0,
"progClosuresTrieAddr": 6509740032,
"progClosuresTrieSize": 8,
"platform": 1,
"formatVersion": 10,
"dylibsExpectedOnDisk": 0,
"simulator": 0,
"locallyBuiltCache": 1,
"builtFromChainedFixups": 0,
"padding": 0,
"sharedRegionStart": 6442450944,
"sharedRegionSize": 4294967296,
"maxSlide": 2147385344,
"dylibsImageArrayAddr": 6509723648,
"dylibsImageArraySize": 240,
"dylibsTrieAddr": 6509723888,
"dylibsTrieSize": 68,
"otherImageArrayAddr": 0,
"otherImageArraySize": 0,
"otherTrieAddr": 0,
"otherTrieSize": 0,
"mappingWithSlideOffset": 488,
"mappingWithSlideCount": 3
},
"slideInfo": [
{
"start": 98304,
"end": 114688,
"version": 2,
"slide": 0,
"page_starts_count": 4,
"page_extras_count": 0,
"delta_mask": 72056494526300160,
"value_mask": 18374687579183251455,
"value_add": 0,
"delta_shift": 38,
"page_size": 4096
}
],
"images": [
{
"uuid": "ccbf29d455693a1592314e14d41a542a",
"address": 6442455040,
"textSegmentSize": 16384,
"path": "/usr/lib/liba-1.0.dylib",
"name": "liba-1.0.dylib"
},
{
"uuid": "60d2f3d644a2391087503a56a3d8ff07",
"address": 6442471424,
"textSegmentSize": 16384,
"path": "/usr/lib/libb-1.0.dylib",
"name": "libb-1.0.dylib"
}
]
}
1 fd: 4 +0x00000000 0x180000000 - 0x180017fff r-x vmap.cache_map.0
2 fd: 4 +0x00018000 0x182018000 - 0x18201bfff r-- vmap.cache_map.1
3 fd: 4 +0x0001c000 0x18401c000 - 0x18402ffff r-- vmap.cache_map.2
@ -177,7 +343,7 @@ mode r-x
format dyldcache
iorw false
block 0x100
type library-cache
type production
arch arm
cpu N/A
baddr 0x180000000
@ -190,14 +356,14 @@ compiler N/A
dbg_file N/A
endian LE
hdr.csum N/A
guid N/A
guid 0051c062211e3a669af7d590307d245c
intrp N/A
laddr 0x00000000
lang N/A
machine arm
maxopsz 4
minopsz 4
os Darwin
os macOS
cc N/A
pcalign 4
rpath N/A
@ -270,7 +436,7 @@ mode r-x
format dyldcache
iorw false
block 0x100
type library-cache
type production
arch arm
cpu N/A
baddr 0x180000000
@ -283,14 +449,14 @@ compiler N/A
dbg_file N/A
endian LE
hdr.csum N/A
guid N/A
guid b3d4bd16c88a378c961fcfefb34344b9
intrp N/A
laddr 0x00000000
lang N/A
machine arm
maxopsz 4
minopsz 4
os Darwin
os macOS
cc N/A
pcalign 4
rpath N/A
@ -434,4 +600,190 @@ q
EOF
EXPECT=<<EOF
EOF
RUN
RUN
NAME=dyldcache 1042.1 header
FILE=bins/dyldcache/dyld_shared_cache_arm64-macOS-1042.1
CMDS=<<EOF
i
is
iS
iH~{}
oml
EOF
EXPECT=<<EOF
fd 3
file bins/dyldcache/dyld_shared_cache_arm64-macOS-1042.1
size 0x20000
humansz 128K
mode r-x
format dyldcache
iorw false
block 0x100
type development
arch arm
cpu N/A
baddr 0x180000000
binsz 0x00020000
bintype N/A
bits 64
retguard false
class dyldcache
compiler N/A
dbg_file N/A
endian LE
hdr.csum N/A
guid c0a042e3c0db394caa455cd7e767643f
intrp N/A
laddr 0x00000000
lang N/A
machine arm
maxopsz 4
minopsz 4
os macOS
cc N/A
pcalign 4
rpath N/A
subsys xnu
stripped false
crypto false
havecode true
va true
sanitiz false
static true
linenum false
lsyms false
canary false
PIE false
RELROCS false
NX false
nth paddr vaddr bind type size lib name
--------------------------------------------------------------------------
0 0x00007fb4 0x180007fb4 GLOBAL FUNC 0 _i_am_libSystem
0 0x0000bfb0 0x18000bfb0 GLOBAL FUNC 0 _say_hello
0 0x0000ff38 0x18000ff38 GLOBAL FUNC 0 dyld3::entryVectorForDyld
1 0x0000ff34 0x18000ff34 GLOBAL FUNC 0 _i_am_libdyld
0 0x00013fb4 0x180013fb4 GLOBAL FUNC 0 _i_am_libsystem_kernel
paddr size vaddr vsize align perm name type flags
-------------------------------------------------------------------------------------------------------------
0x00007fb4 0x4 0x180007fb4 0x4 0x0 -r-x lib_libSystem.B.dylib.0.__TEXT.__text
0x00007fb8 0x48 0x180007fb8 0x48 0x0 -r-x lib_libSystem.B.dylib.1.__TEXT.__unwind_info
0x0000bfb0 0x8 0x18000bfb0 0x8 0x0 -r-x lib_libhello.dylib.0.__TEXT.__text
0x0000bfb8 0x48 0x18000bfb8 0x48 0x0 -r-x lib_libhello.dylib.1.__TEXT.__unwind_info
0x0000ff34 0x4 0x18000ff34 0x4 0x0 -r-x system_libdyld.dylib.0.__TEXT.__text
0x0000ff38 0x80 0x18000ff38 0x80 0x0 -r-x system_libdyld.dylib.1.__TEXT.__const
0x0000ffb8 0x48 0x18000ffb8 0x48 0x0 -r-x system_libdyld.dylib.2.__TEXT.__unwind_info
0x00013fb4 0x4 0x180013fb4 0x4 0x0 -r-x system_libsystem_kernel.dylib.0.__TEXT.__text
0x00013fb8 0x48 0x180013fb8 0x48 0x0 -r-x system_libsystem_kernel.dylib.1.__TEXT.__unwind_info
{
"version": "1042.1",
"header": {
"magic": "dyld_v1 arm64",
"mappingOffset": 512,
"mappingCount": 2,
"imagesOffset": 736,
"imagesCount": 4,
"dyldBaseAddress": 0,
"codeSignatureOffset": 114688,
"codeSignatureSize": 16384,
"slideInfoOffset": 0,
"slideInfoSize": 0,
"localSymbolsOffset": 0,
"localSymbolsSize": 0,
"uuid": "c0a042e3c0db394caa455cd7e767643f",
"cacheType": "development",
"branchPoolsOffset": 0,
"branchPoolsCount": 0,
"dyldInCacheMH": 0,
"dyldInCacheEntry": 0,
"imagesTextOffset": 864,
"imagesTextCount": 4,
"patchInfoAddr": 6442532976,
"patchInfoSize": 264,
"otherImageGroupAddrUnused": 0,
"otherImageGroupSizeUnused": 0,
"progClosuresAddr": 0,
"progClosuresSize": 0,
"progClosuresTrieAddr": 0,
"progClosuresTrieSize": 0,
"platform": 1,
"formatVersion": 0,
"dylibsExpectedOnDisk": 0,
"simulator": 0,
"locallyBuiltCache": 1,
"builtFromChainedFixups": 0,
"padding": 0,
"sharedRegionStart": 6442450944,
"sharedRegionSize": 131072,
"maxSlide": 2147401728,
"dylibsImageArrayAddr": 0,
"dylibsImageArraySize": 0,
"dylibsTrieAddr": 6442532864,
"dylibsTrieSize": 112,
"otherImageArrayAddr": 0,
"otherImageArraySize": 0,
"otherTrieAddr": 0,
"otherTrieSize": 0,
"mappingWithSlideOffset": 624,
"mappingWithSlideCount": 2,
"dylibsPBLStateArrayAddrUnused": 0,
"dylibsPBLSetAddr": 6442533240,
"programsPBLSetPoolAddr": 6442534280,
"programsPBLSetPoolSize": 16384,
"programTrieAddr": 6442550664,
"programTrieSize": 88,
"osVersion": 851968,
"altPlatform": 0,
"altOsVersion": 0,
"swiftOptsOffset": 0,
"swiftOptsSize": 0,
"subCacheArrayOffset": 992,
"subCacheArrayCount": 0,
"symbolFileUUID": "00000000000000000000000000000000",
"rosettaReadOnlyAddr": 0,
"rosettaReadOnlySize": 0,
"rosettaReadWriteAddr": 0,
"rosettaReadWriteSize": 0,
"cacheSubType": 0,
"objcOptsOffset": 0,
"objcOptsSize": 0,
"cacheAtlasOffset": 0,
"cacheAtlasSize": 0,
"dynamicDataOffset": 114688,
"dynamicDataMaxSize": 16384
},
"images": [
{
"uuid": "e0a310e1c61e3b289c5df43f04e71a44",
"address": 6442467328,
"textSegmentSize": 16384,
"path": "/usr/lib/libSystem.B.dylib",
"name": "libSystem.B.dylib"
},
{
"uuid": "f2c8e54bd02937e69928edd8b4bbec63",
"address": 6442483712,
"textSegmentSize": 16384,
"path": "/usr/lib/libhello.dylib",
"name": "libhello.dylib"
},
{
"uuid": "439351ae77ca308ebf1da32729a79709",
"address": 6442500096,
"textSegmentSize": 16384,
"path": "/usr/lib/system/libdyld.dylib",
"name": "libdyld.dylib"
},
{
"uuid": "4ce071b5dd373397aca699d517bdb6e7",
"address": 6442516480,
"textSegmentSize": 16384,
"path": "/usr/lib/system/libsystem_kernel.dylib",
"name": "libsystem_kernel.dylib"
}
]
}
1 fd: 3 +0x00000000 0x180000000 - 0x180013fff r-x fmap.cache_map.0
2 fd: 3 +0x00014000 0x180014000 - 0x18001bfff r-- fmap.cache_map.1
EOF
RUN