enum {
CSMAGIC_REQUIREMENT = 0xfade0c00,
CSMAGIC_REQUIREMENTS = 0xfade0c01,
CSMAGIC_CODEDIRECTORY = 0xfade0c02,
CSMAGIC_EMBEDDED_SIGNATURE = 0xfade0cc0,
CSMAGIC_DETACHED_SIGNATURE = 0xfade0cc1,
CSSLOT_CODEDIRECTORY = 0,
};
typedef struct __BlobIndex {
uint32_t type;
uint32_t offset;
} CS_BlobIndex;
typedef struct __SuperBlob {
uint32_t magic;
uint32_t length;
uint32_t count;
CS_BlobIndex index[];
} CS_SuperBlob;
typedef struct __CodeDirectory {
uint32_t magic;
uint32_t length;
uint32_t version;
uint32_t flags;
uint32_t hashOffset;
uint32_t identOffset;
uint32_t nSpecialSlots;
uint32_t nCodeSlots;
uint32_t codeLimit;
uint8_t hashSize;
uint8_t hashType;
uint8_t spare1;
uint8_t pageSize;
uint32_t spare2;
} CS_CodeDirectory;
static inline const CS_CodeDirectory *findCodeDirectory(const CS_SuperBlob *embedded)
{
if (embedded && ntohl(embedded->magic) == CSMAGIC_EMBEDDED_SIGNATURE) {
const CS_BlobIndex *limit = &embedded->index[ntohl(embedded->count)];
const CS_BlobIndex *p;
for (p = embedded->index; p < limit; ++p)
if (ntohl(p->type) == CSSLOT_CODEDIRECTORY) {
const unsigned char *base = (const unsigned char *)embedded;
const CS_CodeDirectory *cd = (const CS_CodeDirectory *)(base + ntohl(p->offset));
if (cd->magic == CSMAGIC_CODEDIRECTORY)
return cd;
else
break;
}
}
return NULL;
}
static inline const unsigned char *hashes(const CS_CodeDirectory *cd, unsigned page)
{
const unsigned char *base = (const unsigned char *)cd;
assert(page < ntohl(cd->nCodeSlots));
return base + ntohl(cd->hashOffset) + page * 20;
}