Skip to content

MachoFile

Description

Parsed Mach-O file. Holds the raw bytes plus decoded indices.

Fields

Name Description
allocator Allocator backing the owned buffer and the segments/sections/symbols vectors.
data Raw Mach-O bytes.
data_size Length of data in bytes.
owns_data True if data was allocated via allocator.
cputype Mach-O cputype value (e.g. 0x01000007 = x86_64, 0x0100000C = arm64).
filetype MachoFileType value.
uuid 16-byte UUID from LC_UUID if present.
has_uuid True iff LC_UUID was found.
segments All LC_SEGMENT_64 entries.
sections Flat list of all sections across segments.
symbols Entries from LC_SYMTAB; may be empty if stripped.

Usage example (Cross-references)

Usage examples (Cross-references)
        build_macho_blob();
    
        MachoFile m;
        bool      ok = MachoFileOpenFromMemory(&m, blob, sizeof(blob), base);
        if (!ok) {
        build_macho_blob();
    
        MachoFile m;
        if (!MachoFileOpenFromMemory(&m, blob, sizeof(blob), base)) {
            DefaultAllocatorDeinit(&alloc);
        wr_u32(&fat[0], 0xCAFEBABEu);
    
        MachoFile m;
        bool      ok = !MachoFileOpenFromMemory(&m, fat, sizeof(fat), base);
        Allocator       *base  = ALLOCATOR_OF(&alloc);
    
        MachoFile m;
        if (!MachoFileOpen(&m, path, base)) {
            DefaultAllocatorDeinit(&alloc);
        Allocator       *base  = ALLOCATOR_OF(&alloc);
    
        MachoFile m;
        if (!MachoFileOpen(&m, path, base)) {
            DefaultAllocatorDeinit(&alloc);
    
    typedef struct MachoContext {
        MachoFile *out;
        u32        ncmds;
        u32        sizeofcmds;
    
    static bool decode_header(MachoContext *ctx) {
        MachoFile *m = ctx->out;
        if (m->data_size < MH_HEADER_64_SIZE) {
            LOG_ERROR("MachO: file too small for header");
    // ---------------------------------------------------------------------------
    
    bool MachoFileOpenFromMemory(MachoFile *out, u8 *data, size data_size, Allocator *alloc) {
        if (!out || !data || !alloc) {
            LOG_ERROR("MachoFileOpenFromMemory: NULL argument");
    }
    
    bool MachoFileOpen(MachoFile *out, const char *path, Allocator *alloc) {
        if (!out || !path || !alloc) {
            LOG_ERROR("MachoFileOpen: NULL argument");
    }
    
    void MachoFileDeinit(MachoFile *self) {
        if (!self)
            return;
    }
    
    const MachoSection *MachoFileFindSection(const MachoFile *self, const char *segment, const char *section) {
        if (!self || !segment || !section)
            return NULL;
    // matched stabs with all three bits set -- N_SO / N_FUN / N_OSO /
    // etc. were getting through and polluting lookups).
    const MachoSymbol *MachoFileResolveAddress(const MachoFile *self, u64 vaddr) {
        if (!self || self->symbols.length == 0)
            return NULL;
        char          *module_path;
        u64            slide;
        MachoFile      main;
        bool           main_open;
        MachoFile      dsym;
        MachoFile      main;
        bool           main_open;
        MachoFile      dsym;
        bool           dsym_open;
        DwarfFunctions fns;
        MachoSections sections;
        MachoSymbols  symbols;
    } MachoFile;
    
    ///
    /// TAGS: Parser, MachO, File
    ///
    bool MachoFileOpen(MachoFile *out, const char *path, Allocator *alloc);
    
    ///
    /// TAGS: Parser, MachO, Memory
    ///
    bool MachoFileOpenFromMemory(MachoFile *out, u8 *data, size data_size, Allocator *alloc);
    
    ///
    /// Release storage owned by a `MachoFile`. Safe on a zeroed struct.
    ///
    void MachoFileDeinit(MachoFile *self);
    
    ///
    /// absent.
    ///
    const MachoSection *MachoFileFindSection(const MachoFile *self, const char *segment, const char *section);
    
    ///
    /// FAILURE : Returns NULL.
    ///
    const MachoSymbol *MachoFileResolveAddress(const MachoFile *self, u64 vaddr);
    
    #endif // MISRA_PARSERS_MACHO_H
Last updated on