#ifndef ClosureWriter_h
#define ClosureWriter_h
#include <stdint.h>
#include <stdio.h>
#include <assert.h>
#include <uuid/uuid.h>
#include <mach/mach.h>
#include <mach-o/loader.h>
#include <uuid/uuid.h>
#include "Closure.h"
namespace dyld3 {
namespace closure {
class VIS_HIDDEN ContainerTypedBytesWriter
{
public:
void deallocate();
protected:
void setContainerType(TypedBytes::Type containerType);
void* append(TypedBytes::Type t, const void* payload, uint32_t payloadSize);
const void* currentTypedBytes();
const void* finalizeContainer();
void* _vmAllocationStart = nullptr;
size_t _vmAllocationSize = 0;
TypedBytes* _containerTypedBytes = nullptr;
void* _end = nullptr;
};
class VIS_HIDDEN ImageWriter : public ContainerTypedBytesWriter
{
public:
void setImageNum(ImageNum num);
void addPath(const char* path); void setInvalid();
void setInDyldCache(bool);
void setIs64(bool);
void setHasObjC(bool);
void setHasPlusLoads(bool);
void setIsBundle(bool);
void setIsDylib(bool);
void setIsExecutable(bool);
void setIsRestricted(bool);
void setHasWeakDefs(bool);
void setUses16KPages(bool);
void setOverridableDylib(bool);
void setNeverUnload(bool);
void setUUID(const uuid_t uuid);
void setCDHash(const uint8_t cdHash[20]);
void setDependents(const Array<Image::LinkedImage>& deps);
void setDofOffsets(const Array<uint32_t>& dofSectionOffsets);
void setInitOffsets(const uint32_t initOffsets[], uint32_t count);
void setDiskSegments(const Image::DiskSegment segs[], uint32_t count);
void setCachedSegments(const Image::DyldCacheSegment segs[], uint32_t count);
void setCodeSignatureLocation(uint32_t fileOffset, uint32_t size);
void setFairPlayEncryptionRange(uint32_t fileOffset, uint32_t size);
void setMappingInfo(uint64_t sliceOffset, uint64_t vmSize);
void setFileInfo(uint64_t inode, uint64_t modTime);
void setRebaseInfo(const Array<Image::RebasePattern>&);
void setTextRebaseInfo(const Array<Image::TextFixupPattern>&);
void setBindInfo(const Array<Image::BindPattern>&);
void setAsOverrideOf(ImageNum);
void addExportPatchInfo(uint32_t implOff, const char* name, uint32_t locCount, const Image::PatchableExport::PatchLocation* locs);
void setInitsOrder(const ImageNum images[], uint32_t count);
void setChainedFixups(const Array<uint64_t>& starts, const Array<Image::ResolvedSymbolTarget>& targets);
const Image* currentImage();
const Image* finalize();
private:
Image::Flags& getFlags();
int _flagsOffset = -1;
};
class VIS_HIDDEN ImageArrayWriter : public ContainerTypedBytesWriter
{
public:
ImageArrayWriter(ImageNum startImageNum, unsigned count);
void appendImage(const Image*);
const ImageArray* finalize();
private:
unsigned _index;
};
class VIS_HIDDEN ClosureWriter : public ContainerTypedBytesWriter
{
public:
void setTopImageNum(ImageNum imageNum);
void addCachePatches(const Array<Closure::PatchEntry>&);
};
class VIS_HIDDEN LaunchClosureWriter : public ClosureWriter
{
public:
LaunchClosureWriter(const ImageArray* images);
const LaunchClosure* finalize();
void setLibSystemImageNum(ImageNum imageNum);
void setInitImageCount(uint32_t count);
void setLibDyldEntry(Image::ResolvedSymbolTarget dyldEntry);
void setMainEntry(Image::ResolvedSymbolTarget main);
void setStartEntry(Image::ResolvedSymbolTarget start);
void setUsedFallbackPaths(bool);
void setUsedAtPaths(bool);
void setMustBeMissingFiles(const Array<const char*>& paths);
void addInterposingTuples(const Array<InterposingTuple>& tuples);
void setDyldCacheUUID(const uuid_t);
void setBootUUID(const char* uuid);
void applyInterposing();
void addEnvVar(const char* envVar);
private:
LaunchClosure::Flags& getFlags();
int _flagsOffset = -1;
};
class VIS_HIDDEN DlopenClosureWriter : public ClosureWriter
{
public:
DlopenClosureWriter(const ImageArray* images);
const DlopenClosure* finalize();
};
} }
#endif // ClosureWriter_h