#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 setHasPrecomputedObjC(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 setHasTerminators(bool);
void setUUID(const uuid_t uuid);
void addCDHash(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 setInitSectRange(uint32_t sectionOffset, uint32_t sectionSize);
void setTermOffsets(const uint32_t termOffsets[], 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 setRebasesNotEncoded();
void setTextRebaseInfo(const Array<Image::TextFixupPattern>&);
void setBindInfo(const Array<Image::BindPattern>&);
void setObjCFixupInfo(const Image::ResolvedSymbolTarget& objcProtocolClassTarget,
uint64_t objcImageInfoVMOffset,
const Array<Image::ProtocolISAFixup>& protocolISAFixups,
const Array<Image::SelectorReferenceFixup>& selRefFixups,
const Array<Image::ClassStableSwiftFixup>& classStableSwiftFixups,
const Array<Image::MethodListFixup>& methodListFixups);
void setAsOverrideOf(ImageNum);
void setInitsOrder(const ImageNum images[], uint32_t count);
void setChainedFixups(uint64_t runtimeStartsStructOffset, const Array<Image::ResolvedSymbolTarget>& targets);
void setFixupsNotEncoded();
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, bool hasRoots);
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>&);
void applyInterposing(const LaunchClosure* launchClosure);
void addWarning(Closure::Warning::Type type, const char* warning);
};
class VIS_HIDDEN LaunchClosureWriter : public ClosureWriter
{
friend class ClosureBuilder;
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 setUsedInterposing(bool);
void setHasInsertedLibraries(bool);
void setMustBeMissingFiles(const Array<const char*>& paths);
void setMustExistFiles(const Array<LaunchClosure::SkippedFile>& files);
void addInterposingTuples(const Array<InterposingTuple>& tuples);
void setDyldCacheUUID(const uuid_t);
void addEnvVar(const char* envVar);
void setObjCSelectorInfo(const Array<uint8_t>& hashTable, const Array<Image::ObjCSelectorImage>& hashTableImages);
void setObjCClassAndProtocolInfo(const Array<uint8_t>& classHashTable, const Array<uint8_t>& protocolHashTable,
const Array<Image::ObjCClassImage>& hashTableImages);
void setObjCDuplicateClassesInfo(const Array<uint8_t>& hashTable);
void setHasProgramVars(uint32_t offset);
private:
LaunchClosure::Flags& getFlags();
int _flagsOffset = -1;
};
class VIS_HIDDEN DlopenClosureWriter : public ClosureWriter
{
public:
DlopenClosureWriter(const ImageArray* images);
const DlopenClosure* finalize();
};
} }
#endif // ClosureWriter_h