#ifndef DyldSharedCache_h
#define DyldSharedCache_h
#include <set>
#include <string>
#include <vector>
#include <unordered_map>
#include <uuid/uuid.h>
#include "dyld_cache_format.h"
#include "Diagnostics.h"
#include "MachOAnalyzer.h"
#include "Closure.h"
class VIS_HIDDEN DyldSharedCache
{
public:
enum CodeSigningDigestMode
{
SHA256only = 0,
SHA1only = 1,
Agile = 2
};
struct CreateOptions
{
std::string outputFilePath;
std::string outputMapFilePath;
std::string archName;
dyld3::Platform platform;
bool excludeLocalSymbols;
bool optimizeStubs;
bool optimizeObjC;
CodeSigningDigestMode codeSigningDigestMode;
bool dylibsRemovedDuringMastering;
bool inodesAreSameAsRuntime;
bool cacheSupportsASLR;
bool forSimulator;
bool isLocallyBuiltCache;
bool verbose;
bool evictLeafDylibsOnOverflow;
std::unordered_map<std::string, unsigned> dylibOrdering;
std::unordered_map<std::string, unsigned> dirtyDataSegmentOrdering;
std::vector<std::string> pathPrefixes;
std::string loggingPrefix;
};
struct MappedMachO
{
MappedMachO()
: mh(nullptr), length(0), isSetUID(false), protectedBySIP(false), sliceFileOffset(0), modTime(0), inode(0) { }
MappedMachO(const std::string& path, const dyld3::MachOAnalyzer* p, size_t l, bool isu, bool sip, uint64_t o, uint64_t m, uint64_t i)
: runtimePath(path), mh(p), length(l), isSetUID(isu), protectedBySIP(sip), sliceFileOffset(o), modTime(m), inode(i) { }
std::string runtimePath;
const dyld3::MachOAnalyzer* mh;
size_t length;
uint64_t isSetUID : 1,
protectedBySIP : 1,
sliceFileOffset : 62;
uint64_t modTime; uint64_t inode; };
struct CreateResults
{
std::string errorMessage;
std::set<std::string> warnings;
std::set<const dyld3::MachOAnalyzer*> evictions;
bool agileSignature = false;
std::string cdHashFirst;
std::string cdHashSecond;
};
struct FileAlias
{
std::string realPath;
std::string aliasPath;
};
static bool verifySelfContained(std::vector<MappedMachO>& dylibsToCache, MappedMachO (^loader)(const std::string& runtimePath), std::vector<std::pair<DyldSharedCache::MappedMachO, std::set<std::string>>>& excluded);
static CreateResults create(const CreateOptions& options,
const std::vector<MappedMachO>& dylibsToCache,
const std::vector<MappedMachO>& otherOsDylibs,
const std::vector<MappedMachO>& osExecutables);
std::string mapFile() const;
const char* archName() const;
dyld3::Platform platform() const;
void forEachImage(void (^handler)(const mach_header* mh, const char* installName)) const;
bool hasImagePath(const char* dylibPath, uint32_t& imageIndex) const;
bool findMachHeaderImageIndex(const mach_header* mh, uint32_t& imageIndex) const;
void forEachImageEntry(void (^handler)(const char* path, uint64_t mTime, uint64_t inode)) const;
const mach_header* getIndexedImageEntry(uint32_t index, uint64_t& mTime, uint64_t& node) const;
void forEachImageTextSegment(void (^handler)(uint64_t loadAddressUnslid, uint64_t textSegmentSize, const uuid_t dylibUUID, const char* installName, bool& stop)) const;
void forEachRegion(void (^handler)(const void* content, uint64_t vmAddr, uint64_t size, uint32_t permissions)) const;
bool inCache(const void* addr, size_t length, bool& readOnly) const;
uint64_t unslidLoadAddress() const;
void getUUID(uuid_t uuid) const;
uint64_t mappedSize() const;
const dyld3::closure::LaunchClosure* findClosure(const char* executablePath) const;
void forEachLaunchClosure(void (^handler)(const char* executableRuntimePath, const dyld3::closure::LaunchClosure* closure)) const;
void forEachDlopenImage(void (^handler)(const char* runtimePath, const dyld3::closure::Image* image)) const;
const dyld3::closure::ImageArray* cachedDylibsImageArray() const;
const dyld3::closure::ImageArray* otherOSImageArray() const;
const dyld3::closure::Image* findDlopenOtherImage(const char* path) const;
bool addressInText(uint32_t cacheOffset, uint32_t* index) const;
dyld_cache_header header;
};
#endif