/*
 * File macho_module.c - processing of Mach-O files
 *      Originally based on elf_module.c
 *
 * Copyright (C) 1996, Eric Youngdale.
 *               1999-2007 Eric Pouech
 *               2009 Ken Thomases, CodeWeavers Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"

#include "dbghelp_private.h"

#ifdef HAVE_MACH_O_LOADER_H

#include <assert.h>
#include <stdarg.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
#endif

#include <mach-o/fat.h>
#include <mach-o/loader.h>
#include <mach-o/nlist.h>

#ifdef HAVE_MACH_O_DYLD_IMAGES_H
#include <mach-o/dyld_images.h>
#else
struct dyld_image_info {
    const struct mach_header *imageLoadAddress;
    const char               *imageFilePath;
    uintptr_t                 imageFileModDate;
};

struct dyld_all_image_infos {
    uint32_t                      version;
    uint32_t                      infoArrayCount;
    const struct dyld_image_info *infoArray;
    void*                         notification;
    int                           processDetachedFromSharedRegion;
};
#endif

#include "winternl.h"
#include "wine/library.h"
#include "wine/debug.h"

#ifdef WORDS_BIGENDIAN
#define swap_ulong_be_to_host(n) (n)
#else
#define swap_ulong_be_to_host(n) (RtlUlongByteSwap(n))
#endif

WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_macho);


struct macho_module_info
{
    unsigned long               load_addr;
    unsigned short              in_use : 1,
                                is_loader : 1;
};

#define MACHO_INFO_DEBUG_HEADER   0x0001
#define MACHO_INFO_MODULE         0x0002
#define MACHO_INFO_NAME           0x0004

struct macho_info
{
    unsigned                    flags;          /* IN  one (or several) of the MACHO_INFO constants */
    unsigned long               dbg_hdr_addr;   /* OUT address of debug header (if MACHO_INFO_DEBUG_HEADER is set) */
    struct module*              module;         /* OUT loaded module (if MACHO_INFO_MODULE is set) */
    const WCHAR*                module_name;    /* OUT found module name (if MACHO_INFO_NAME is set) */
};

/* structure holding information while handling a Mach-O image */
#define BITS_PER_ULONG (sizeof(ULONG) * 8)
#define ULONGS_FOR_BITS(nbits) (((nbits) + BITS_PER_ULONG - 1) / BITS_PER_ULONG)
struct macho_file_map
{
    /* A copy of the Mach-O header for an individual architecture. */
    struct mach_header          mach_header;

    /* The mapped load commands. */
    const struct load_command*  load_commands;

    /* The portion of the file which is this architecture.  mach_header was
     * read from arch_offset. */
    unsigned                    arch_offset;
    unsigned                    arch_size;

    /* The range of address space covered by all segments. */
    size_t                      segs_start;
    size_t                      segs_size;

    /* Map of which sections contain code.  Sections are accessed using 1-based
     * index.  Bit 0 of this bitset indicates if the bitset has been initialized. */
    RTL_BITMAP                  sect_is_code;
    ULONG                       sect_is_code_buff[ULONGS_FOR_BITS(MAX_SECT + 1)];

    /* The file. */
    int                         fd;
};

static void macho_unmap_file(struct macho_file_map* fmap);

/******************************************************************
 *              macho_calc_range
 *
 * For a range (offset & length) of a single architecture within
 * a Mach-O file, calculate the page-aligned range of the whole file
 * that encompasses it.  For a fat binary, the architecture will
 * itself be offset within the file, so take that into account.
 */
static void macho_calc_range(const struct macho_file_map* fmap, unsigned offset,
                             unsigned len, unsigned* out_aligned_offset,
                             unsigned* out_aligned_end, unsigned* out_aligned_len,
                             unsigned* out_misalign)
{
    unsigned pagemask = sysconf( _SC_PAGESIZE ) - 1;
    unsigned file_offset, misalign;

    file_offset = fmap->arch_offset + offset;
    misalign = file_offset & pagemask;
    *out_aligned_offset = file_offset - misalign;
    *out_aligned_end = (file_offset + len + pagemask) & ~pagemask;
    if (out_aligned_len)
        *out_aligned_len = *out_aligned_end - *out_aligned_offset;
    if (out_misalign)
        *out_misalign = misalign;
}

/******************************************************************
 *              macho_map_range
 *
 * Maps a range (offset, length in bytes) from a Mach-O file into memory
 */
static const char* macho_map_range(const struct macho_file_map* fmap, unsigned offset, unsigned len)
{
    unsigned    misalign, aligned_offset, aligned_map_end, map_size;
    const void* aligned_ptr;

    TRACE("(%p/%d, 0x%08x, 0x%08x)\n", fmap, fmap->fd, offset, len);

    macho_calc_range(fmap, offset, len, &aligned_offset, &aligned_map_end,
                     &map_size, &misalign);

    aligned_ptr = mmap(NULL, map_size, PROT_READ, MAP_PRIVATE, fmap->fd, aligned_offset);

    TRACE("Mapped (0x%08x - 0x%08x) to %p\n", aligned_offset, aligned_map_end, aligned_ptr);

    if (aligned_ptr == MAP_FAILED) return MACHO_NO_MAP;
    return (const char*)aligned_ptr + misalign;
}

/******************************************************************
 *              macho_unmap_range
 *
 * Unmaps a range (offset, length in bytes) of a Mach-O file from memory
 */
static void macho_unmap_range(const void** mapped, const struct macho_file_map* fmap,
                              unsigned offset, unsigned len)
{
    TRACE("(%p, %p/%d, 0x%08x, 0x%08x)\n", mapped, fmap, fmap->fd, offset, len);

    if (mapped && *mapped != MACHO_NO_MAP)
    {
        unsigned    misalign, aligned_offset, aligned_map_end, map_size;
        void*       aligned_ptr;

        macho_calc_range(fmap, offset, len, &aligned_offset, &aligned_map_end,
                         &map_size, &misalign);

        aligned_ptr = (char*)*mapped - misalign;
        if (munmap(aligned_ptr, map_size) < 0)
            WARN("Couldn't unmap the range\n");
        TRACE("Unmapped (0x%08x - 0x%08x) from %p - %p\n", aligned_offset, aligned_map_end, aligned_ptr, (char*)aligned_ptr + map_size);
        *mapped = MACHO_NO_MAP;
    }
}

/******************************************************************
 *              macho_map_ranges
 *
 * Maps two ranges (offset, length in bytes) from a Mach-O file
 * into memory.  If the two ranges overlap, use one mmap so that
 * the munmap doesn't fragment the mapping.
 */
static BOOL macho_map_ranges(const struct macho_file_map* fmap,
                             unsigned offset1, unsigned len1,
                             unsigned offset2, unsigned len2,
                             const void** mapped1, const void** mapped2)
{
    unsigned aligned_offset1, aligned_map_end1;
    unsigned aligned_offset2, aligned_map_end2;

    TRACE("(%p/%d, 0x%08x, 0x%08x, 0x%08x, 0x%08x, %p, %p)\n", fmap, fmap->fd,
            offset1, len1, offset2, len2, mapped1, mapped2);

    macho_calc_range(fmap, offset1, len1, &aligned_offset1, &aligned_map_end1, NULL, NULL);
    macho_calc_range(fmap, offset2, len2, &aligned_offset2, &aligned_map_end2, NULL, NULL);

    if (aligned_map_end1 < aligned_offset2 || aligned_map_end2 < aligned_offset1)
    {
        *mapped1 = macho_map_range(fmap, offset1, len1);
        if (*mapped1 != MACHO_NO_MAP)
        {
            *mapped2 = macho_map_range(fmap, offset2, len2);
            if (*mapped2 == MACHO_NO_MAP)
                macho_unmap_range(mapped1, fmap, offset1, len1);
        }
    }
    else
    {
        if (offset1 < offset2)
        {
            *mapped1 = macho_map_range(fmap, offset1, offset2 + len2 - offset1);
            if (*mapped1 != MACHO_NO_MAP)
                *mapped2 = (const char*)*mapped1 + offset2 - offset1;
        }
        else
        {
            *mapped2 = macho_map_range(fmap, offset2, offset1 + len1 - offset2);
            if (*mapped2 != MACHO_NO_MAP)
                *mapped1 = (const char*)*mapped2 + offset1 - offset2;
        }
    }

    TRACE(" => %p, %p\n", *mapped1, *mapped2);

    return (*mapped1 != MACHO_NO_MAP) && (*mapped2 != MACHO_NO_MAP);
}

/******************************************************************
 *              macho_unmap_ranges
 *
 * Unmaps two ranges (offset, length in bytes) of a Mach-O file
 * from memory.  Use for ranges which were mapped by
 * macho_map_ranges.
 */
static void macho_unmap_ranges(const struct macho_file_map* fmap,
                               unsigned offset1, unsigned len1,
                               unsigned offset2, unsigned len2,
                               const void** mapped1, const void** mapped2)
{
    unsigned    aligned_offset1, aligned_map_end1;
    unsigned    aligned_offset2, aligned_map_end2;

    TRACE("(%p/%d, 0x%08x, 0x%08x, 0x%08x, 0x%08x, %p/%p, %p/%p)\n", fmap, fmap->fd,
            offset1, len1, offset2, len2, mapped1, *mapped1, mapped2, *mapped2);

    macho_calc_range(fmap, offset1, len1, &aligned_offset1, &aligned_map_end1, NULL, NULL);
    macho_calc_range(fmap, offset2, len2, &aligned_offset2, &aligned_map_end2, NULL, NULL);

    if (aligned_map_end1 < aligned_offset2 || aligned_map_end2 < aligned_offset1)
    {
        macho_unmap_range(mapped1, fmap, offset1, len1);
        macho_unmap_range(mapped2, fmap, offset2, len2);
    }
    else
    {
        if (offset1 < offset2)
        {
            macho_unmap_range(mapped1, fmap, offset1, offset2 + len2 - offset1);
            *mapped2 = MACHO_NO_MAP;
        }
        else
        {
            macho_unmap_range(mapped2, fmap, offset2, offset1 + len1 - offset2);
            *mapped1 = MACHO_NO_MAP;
        }
    }
}

/******************************************************************
 *              macho_map_load_commands
 *
 * Maps the load commands from a Mach-O file into memory
 */
static const struct load_command* macho_map_load_commands(struct macho_file_map* fmap)
{
    if (fmap->load_commands == MACHO_NO_MAP)
    {
        fmap->load_commands = (const struct load_command*) macho_map_range(
                fmap, sizeof(fmap->mach_header), fmap->mach_header.sizeofcmds);
        TRACE("Mapped load commands: %p\n", fmap->load_commands);
    }

    return fmap->load_commands;
}

/******************************************************************
 *              macho_unmap_load_commands
 *
 * Unmaps the load commands of a Mach-O file from memory
 */
static void macho_unmap_load_commands(struct macho_file_map* fmap)
{
    if (fmap->load_commands != MACHO_NO_MAP)
    {
        TRACE("Unmapping load commands: %p\n", fmap->load_commands);
        macho_unmap_range((const void**)&fmap->load_commands, fmap,
                    sizeof(fmap->mach_header), fmap->mach_header.sizeofcmds);
    }
}

/******************************************************************
 *              macho_next_load_command
 *
 * Advance to the next load command
 */
static const struct load_command* macho_next_load_command(const struct load_command* lc)
{
    return (const struct load_command*)((const char*)lc + lc->cmdsize);
}

/******************************************************************
 *              macho_enum_load_commands
 *
 * Enumerates the load commands for a Mach-O file, selecting by
 * the command type, calling a callback for each.  If the callback
 * returns <0, that indicates an error.  If it returns >0, that means
 * it's not interested in getting any more load commands.
 * If this function returns <0, that's an error produced by the
 * callback.  If >=0, that's the count of load commands successfully
 * processed.
 */
static int macho_enum_load_commands(struct macho_file_map* fmap, unsigned cmd,
                                    int (*cb)(struct macho_file_map*, const struct load_command*, void*),
                                    void* user)
{
    const struct load_command* lc;
    int i;
    int count = 0;

    TRACE("(%p/%d, %u, %p, %p)\n", fmap, fmap->fd, cmd, cb, user);

    if ((lc = macho_map_load_commands(fmap)) == MACHO_NO_MAP) return -1;

    TRACE("%d total commands\n", fmap->mach_header.ncmds);

    for (i = 0; i < fmap->mach_header.ncmds; i++, lc = macho_next_load_command(lc))
    {
        int result;

        if (cmd && cmd != lc->cmd) continue;
        count++;

        result = cb(fmap, lc, user);
        TRACE("load_command[%d] (%p), cmd %u; callback => %d\n", i, lc, lc->cmd, result);
        if (result) return (result < 0) ? result : count;
    }

    return count;
}

/******************************************************************
 *              macho_accum_segs_range
 *
 * Callback for macho_enum_load_commands.  Accumulates the address
 * range covered by the segments of a Mach-O file.  All commands
 * are expected to be of LC_SEGMENT type.
 */
static int macho_accum_segs_range(struct macho_file_map* fmap,
                                  const struct load_command* lc, void* user)
{
    const struct segment_command*   sc = (const struct segment_command*)lc;
    unsigned                        tmp, page_mask = sysconf( _SC_PAGESIZE ) - 1;

    TRACE("(%p/%d, %p, %p) before: 0x%08x - 0x%08x\n", fmap, fmap->fd, lc, user,
            (unsigned)fmap->segs_start, (unsigned)fmap->segs_size);
    TRACE("Segment command vm: 0x%08x - 0x%08x\n", (unsigned)sc->vmaddr,
            (unsigned)sc->vmaddr + sc->vmsize);

    if (!strncmp(sc->segname, "WINE_", 5))
    {
        TRACE("Ignoring special Wine segment %s\n", debugstr_an(sc->segname, sizeof(sc->segname)));
        return 0;
    }

    /* If this segment starts before previously-known earliest, record
     * new earliest. */
    if (sc->vmaddr < fmap->segs_start)
        fmap->segs_start = sc->vmaddr;

    /* If this segment extends beyond previously-known furthest, record
     * new furthest. */
    tmp = (sc->vmaddr + sc->vmsize + page_mask) & ~page_mask;
    if (fmap->segs_size < tmp) fmap->segs_size = tmp;

    TRACE("after: 0x%08x - 0x%08x\n", (unsigned)fmap->segs_start, (unsigned)fmap->segs_size);

    return 0;
}

/******************************************************************
 *              macho_map_file
 *
 * Maps a Mach-O file into memory (and checks it's a real Mach-O file)
 */
static BOOL macho_map_file(const WCHAR* filenameW, struct macho_file_map* fmap)
{
    struct fat_header   fat_header;
    struct stat         statbuf;
    int                 i;
    char*               filename;
    unsigned            len;
    BOOL                ret = FALSE;

    TRACE("(%s, %p)\n", debugstr_w(filenameW), fmap);

    fmap->fd = -1;
    fmap->load_commands = MACHO_NO_MAP;
    RtlInitializeBitMap(&fmap->sect_is_code, fmap->sect_is_code_buff, MAX_SECT + 1);

    len = WideCharToMultiByte(CP_UNIXCP, 0, filenameW, -1, NULL, 0, NULL, NULL);
    if (!(filename = HeapAlloc(GetProcessHeap(), 0, len))) return FALSE;
    WideCharToMultiByte(CP_UNIXCP, 0, filenameW, -1, filename, len, NULL, NULL);

    /* check that the file exists */
    if (stat(filename, &statbuf) == -1 || S_ISDIR(statbuf.st_mode)) goto done;

    /* Now open the file, so that we can mmap() it. */
    if ((fmap->fd = open(filename, O_RDONLY)) == -1) goto done;

    if (read(fmap->fd, &fat_header, sizeof(fat_header)) != sizeof(fat_header))
        goto done;
    TRACE("... got possible fat header\n");

    /* Fat header is always in big-endian order. */
    if (swap_ulong_be_to_host(fat_header.magic) == FAT_MAGIC)
    {
        int narch = swap_ulong_be_to_host(fat_header.nfat_arch);
        for (i = 0; i < narch; i++)
        {
            struct fat_arch fat_arch;
            if (read(fmap->fd, &fat_arch, sizeof(fat_arch)) != sizeof(fat_arch))
                goto done;
            if (swap_ulong_be_to_host(fat_arch.cputype) == CPU_TYPE_X86)
            {
                fmap->arch_offset = swap_ulong_be_to_host(fat_arch.offset);
                fmap->arch_size = swap_ulong_be_to_host(fat_arch.size);
                break;
            }
        }
        if (i >= narch) goto done;
        TRACE("... found x86 arch\n");
    }
    else
    {
        fmap->arch_offset = 0;
        fmap->arch_size = statbuf.st_size;
        TRACE("... not a fat header\n");
    }

    /* Individual architecture (standalone or within a fat file) is in its native byte order. */
    lseek(fmap->fd, fmap->arch_offset, SEEK_SET);
    if (read(fmap->fd, &fmap->mach_header, sizeof(fmap->mach_header)) != sizeof(fmap->mach_header))
        goto done;
    TRACE("... got possible Mach header\n");
    /* and check for a Mach-O header */
    if (fmap->mach_header.magic != MH_MAGIC ||
        fmap->mach_header.cputype != CPU_TYPE_X86) goto done;
    /* Make sure the file type is one of the ones we expect. */
    switch (fmap->mach_header.filetype)
    {
        case MH_EXECUTE:
        case MH_DYLIB:
        case MH_DYLINKER:
        case MH_BUNDLE:
            break;
        default:
            goto done;
    }
    TRACE("... verified Mach x86 header\n");

    fmap->segs_size = 0;
    fmap->segs_start = ~0L;

    if (macho_enum_load_commands(fmap, LC_SEGMENT, macho_accum_segs_range, NULL) < 0)
        goto done;

    fmap->segs_size -= fmap->segs_start;
    TRACE("segs_start: 0x%08x, segs_size: 0x%08x\n", (unsigned)fmap->segs_start,
            (unsigned)fmap->segs_size);

    ret = TRUE;
done:
    if (!ret)
        macho_unmap_file(fmap);
    HeapFree(GetProcessHeap(), 0, filename);
    return ret;
}

/******************************************************************
 *              macho_unmap_file
 *
 * Unmaps a Mach-O file from memory (previously mapped with macho_map_file)
 */
static void macho_unmap_file(struct macho_file_map* fmap)
{
    TRACE("(%p/%d)\n", fmap, fmap->fd);
    if (fmap->fd != -1)
    {
        macho_unmap_load_commands(fmap);
        close(fmap->fd);
        fmap->fd = -1;
    }
}

/******************************************************************
 *              macho_fill_sect_is_code
 *
 * Callback for macho_enum_load_commands.  Determines which segments
 * of a Mach-O file contain code.  All commands are expected to be
 * of LC_SEGMENT type.
 */
static int macho_fill_sect_is_code(struct macho_file_map* fmap,
                                   const struct load_command* lc, void* user)
{
    const struct segment_command*   sc = (const struct segment_command*)lc;
    const struct section*           sections;
    int*                            cursect = user;
    int                             i;

    TRACE("(%p/%d, %p, %p/%d) scanning %u sections\n", fmap, fmap->fd, lc,
            cursect, *cursect, sc->nsects);

    sections = (const struct section*)(sc + 1);
    for (i = 0; i < sc->nsects; i++)
    {
        if (*cursect > MAX_SECT) return -1;
        (*cursect)++;

        if (!(sections[i].flags & SECTION_TYPE) &&
            (sections[i].flags & (S_ATTR_PURE_INSTRUCTIONS|S_ATTR_SOME_INSTRUCTIONS)))
            RtlSetBits(&fmap->sect_is_code, *cursect, 1);
        else
            RtlClearBits(&fmap->sect_is_code, *cursect, 1);
        TRACE("Section %d (%d of this segment) is%s code\n", *cursect, i,
                (RtlAreBitsSet(&fmap->sect_is_code, *cursect, 1) ? "" : " not"));
    }

    return 0;
}

/******************************************************************
 *              macho_sect_is_code
 *
 * Checks if a section, identified by sectidx which is a 1-based
 * index into the sections of all segments, in order of load
 * commands, contains code.
 */
static BOOL macho_sect_is_code(struct macho_file_map* fmap, unsigned char sectidx)
{
    TRACE("(%p/%d, %u)\n", fmap, fmap->fd, sectidx);

    if (!RtlAreBitsSet(&fmap->sect_is_code, 0, 1))
    {
        int cursect = 0;
        if (macho_enum_load_commands(fmap, LC_SEGMENT, macho_fill_sect_is_code, &cursect) < 0)
            WARN("Couldn't load sect_is_code map\n");
        RtlSetBits(&fmap->sect_is_code, 0, 1);
    }

    return RtlAreBitsSet(&fmap->sect_is_code, sectidx, 1);
}

struct symtab_elt
{
    struct hash_table_elt       ht_elt;
    struct symt_compiland*      compiland;
    unsigned long               addr;
    unsigned char               is_code:1,
                                is_public:1,
                                is_global:1,
                                used:1;
};

struct macho_debug_info
{
    struct macho_file_map*      fmap;
    struct module*              module;
    struct pool                 pool;
    struct hash_table           ht_symtab;
};

/******************************************************************
 *              macho_stabs_def_cb
 *
 * Callback for stabs_parse.  Collect symbol definitions.
 */
static void macho_stabs_def_cb(struct module* module, unsigned long load_offset,
                               const char* name, unsigned long offset,
                               BOOL is_public, BOOL is_global, unsigned char sectidx,
                               struct symt_compiland* compiland, void* user)
{
    struct macho_debug_info*    mdi = user;
    struct symtab_elt*          ste;

    TRACE("(%p, 0x%08lx, %s, 0x%08lx, %d, %d, %u, %p, %p/%p/%d)\n", module, load_offset,
            debugstr_a(name), offset, is_public, is_global, sectidx,
            compiland, mdi, mdi->fmap, mdi->fmap->fd);

    /* Defer the creation of new non-debugging symbols until after we've
     * finished parsing the stabs. */
    ste                 = pool_alloc(&mdi->pool, sizeof(*ste));
    ste->ht_elt.name    = pool_strdup(&mdi->pool, name);
    ste->compiland      = compiland;
    ste->addr           = load_offset + offset;
    ste->is_code        = !!macho_sect_is_code(mdi->fmap, sectidx);
    ste->is_public      = !!is_public;
    ste->is_global      = !!is_global;
    ste->used           = 0;
    hash_table_add(&mdi->ht_symtab, &ste->ht_elt);
}

/******************************************************************
 *              macho_parse_symtab
 *
 * Callback for macho_enum_load_commands.  Processes the LC_SYMTAB
 * load commands from the Mach-O file.
 */
static int macho_parse_symtab(struct macho_file_map* fmap,
                              const struct load_command* lc, void* user)
{
    const struct symtab_command*    sc = (const struct symtab_command*)lc;
    struct macho_debug_info*        mdi = user;
    const struct nlist*             stab;
    const char*                     stabstr;
    int                             ret = 0;

    TRACE("(%p/%d, %p, %p) %u syms at 0x%08x, strings 0x%08x - 0x%08x\n", fmap, fmap->fd, lc,
            user, sc->nsyms, sc->symoff, sc->stroff, sc->stroff + sc->strsize);

    if (!macho_map_ranges(fmap, sc->symoff, sc->nsyms * sizeof(struct nlist),
            sc->stroff, sc->strsize, (const void**)&stab, (const void**)&stabstr))
        return 0;

    if (!stabs_parse(mdi->module,
                     mdi->module->format_info[DFI_MACHO]->u.macho_info->load_addr - fmap->segs_start,
                     stab, sc->nsyms * sizeof(struct nlist),
                     stabstr, sc->strsize, macho_stabs_def_cb, mdi))
        ret = -1;

    macho_unmap_ranges(fmap, sc->symoff, sc->nsyms * sizeof(struct nlist),
            sc->stroff, sc->strsize, (const void**)&stab, (const void**)&stabstr);

    return ret;
}

/******************************************************************
 *              macho_finish_stabs
 *
 * Integrate the non-debugging symbols we've gathered into the
 * symbols that were generated during stabs parsing.
 */
static void macho_finish_stabs(struct module* module, struct hash_table* ht_symtab)
{
    struct hash_table_iter      hti_ours;
    struct symtab_elt*          ste;
    BOOL                        adjusted = FALSE;

    TRACE("(%p, %p)\n", module, ht_symtab);

    /* For each of our non-debugging symbols, see if it can provide some
     * missing details to one of the module's known symbols. */
    hash_table_iter_init(ht_symtab, &hti_ours, NULL);
    while ((ste = hash_table_iter_up(&hti_ours)))
    {
        struct hash_table_iter  hti_modules;
        void*                   ptr;
        struct symt_ht*         sym;
        struct symt_function*   func;
        struct symt_data*       data;

        hash_table_iter_init(&module->ht_symbols, &hti_modules, ste->ht_elt.name);
        while ((ptr = hash_table_iter_up(&hti_modules)))
        {
            sym = GET_ENTRY(ptr, struct symt_ht, hash_elt);

            if (strcmp(sym->hash_elt.name, ste->ht_elt.name))
                continue;

            switch (sym->symt.tag)
            {
            case SymTagFunction:
                func = (struct symt_function*)sym;
                if (func->address == module->format_info[DFI_MACHO]->u.macho_info->load_addr)
                {
                    TRACE("Adjusting function %p/%s!%s from 0x%08lx to 0x%08lx\n", func,
                          debugstr_w(module->module.ModuleName), sym->hash_elt.name,
                          func->address, ste->addr);
                    func->address = ste->addr;
                    adjusted = TRUE;
                }
                if (func->address == ste->addr)
                    ste->used = 1;
                break;
            case SymTagData:
                data = (struct symt_data*)sym;
                switch (data->kind)
                {
                case DataIsGlobal:
                case DataIsFileStatic:
                    if (data->u.var.offset == module->format_info[DFI_MACHO]->u.macho_info->load_addr)
                    {
                        TRACE("Adjusting data symbol %p/%s!%s from 0x%08lx to 0x%08lx\n",
                              data, debugstr_w(module->module.ModuleName), sym->hash_elt.name,
                              data->u.var.offset, ste->addr);
                        data->u.var.offset = ste->addr;
                        adjusted = TRUE;
                    }
                    if (data->u.var.offset == ste->addr)
                    {
                        enum DataKind new_kind;

                        new_kind = ste->is_global ? DataIsGlobal : DataIsFileStatic;
                        if (data->kind != new_kind)
                        {
                            WARN("Changing kind for %p/%s!%s from %d to %d\n", sym,
                                 debugstr_w(module->module.ModuleName), sym->hash_elt.name,
                                 (int)data->kind, (int)new_kind);
                            data->kind = new_kind;
                            adjusted = TRUE;
                        }
                        ste->used = 1;
                    }
                    break;
                default:;
                }
                break;
            default:
                TRACE("Ignoring tag %u\n", sym->symt.tag);
                break;
            }
        }
    }

    if (adjusted)
    {
        /* since we may have changed some addresses, mark the module to be resorted */
        module->sortlist_valid = FALSE;
    }

    /* Mark any of our non-debugging symbols which fall on an already-used
     * address as "used".  This allows us to skip them in the next loop,
     * below.  We do this in separate loops because symt_new_* marks the
     * list as needing sorting and symt_find_nearest sorts if needed,
     * causing thrashing. */
    if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
    {
        hash_table_iter_init(ht_symtab, &hti_ours, NULL);
        while ((ste = hash_table_iter_up(&hti_ours)))
        {
            struct symt_ht* sym;
            ULONG64         addr;

            if (ste->used) continue;

            sym = symt_find_nearest(module, ste->addr);
            if (sym)
                symt_get_address(&sym->symt, &addr);
            if (sym && ste->addr == addr)
            {
                ULONG64 size = 0;
                DWORD   kind = -1;

                ste->used = 1;

                /* If neither symbol has a correct size (ours never does), we
                 * consider them both to be markers.  No warning is needed in
                 * that case.
                 * Also, we check that we don't have two symbols, one local, the other
                 * global, which is legal.
                 */
                symt_get_info(module, &sym->symt, TI_GET_LENGTH,   &size);
                symt_get_info(module, &sym->symt, TI_GET_DATAKIND, &kind);
                if (size && kind == (ste->is_global ? DataIsGlobal : DataIsFileStatic))
                    FIXME("Duplicate in %s: %s<%08lx> %s<%s-%s>\n",
                          debugstr_w(module->module.ModuleName),
                          ste->ht_elt.name, ste->addr,
                          sym->hash_elt.name,
                          wine_dbgstr_longlong(addr), wine_dbgstr_longlong(size));
            }
        }
    }

    /* For any of our remaining non-debugging symbols which have no match
     * among the module's known symbols, add them as new symbols. */
    hash_table_iter_init(ht_symtab, &hti_ours, NULL);
    while ((ste = hash_table_iter_up(&hti_ours)))
    {
        if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY) && !ste->used)
        {
            if (ste->is_code)
            {
                symt_new_function(module, ste->compiland, ste->ht_elt.name,
                    ste->addr, 0, NULL);
            }
            else
            {
                struct location loc;

                loc.kind = loc_absolute;
                loc.reg = 0;
                loc.offset = ste->addr;
                symt_new_global_variable(module, ste->compiland, ste->ht_elt.name,
                                         !ste->is_global, loc, 0, NULL);
            }

            ste->used = 1;
        }

        if (ste->is_public && !(dbghelp_options & SYMOPT_NO_PUBLICS))
        {
            symt_new_public(module, ste->compiland, ste->ht_elt.name, ste->addr, 0);
        }
    }
}

/******************************************************************
 *              macho_load_debug_info_from_map
 *
 * Loads the symbolic information from a Mach-O module.
 * Returns
 *      FALSE if the file doesn't contain symbolic info (or this info
 *              cannot be read or parsed)
 *      TRUE on success
 */
static BOOL macho_load_debug_info_from_map(struct module* module,
                                           struct macho_file_map* fmap)
{
    BOOL                    ret = FALSE;
    struct macho_debug_info mdi;
    int                     result;

    TRACE("(%p, %p/%d)\n", module, fmap, fmap->fd);

    module->module.SymType = SymExport;

    mdi.fmap = fmap;
    mdi.module = module;
    pool_init(&mdi.pool, 65536);
    hash_table_init(&mdi.pool, &mdi.ht_symtab, 256);
    result = macho_enum_load_commands(fmap, LC_SYMTAB, macho_parse_symtab, &mdi);
    if (result > 0)
        ret = TRUE;
    else if (result < 0)
        WARN("Couldn't correctly read stabs\n");

    macho_finish_stabs(module, &mdi.ht_symtab);

    pool_destroy(&mdi.pool);
    return ret;
}

/******************************************************************
 *              macho_load_debug_info
 *
 * Loads Mach-O debugging information from the module image file.
 */
BOOL macho_load_debug_info(struct module* module, struct macho_file_map* fmap)
{
    BOOL                    ret = TRUE;
    struct macho_file_map   my_fmap;

    TRACE("(%p, %p/%d)\n", module, fmap, fmap ? fmap->fd : -1);

    if (module->type != DMT_MACHO || !module->format_info[DFI_MACHO]->u.macho_info)
    {
        ERR("Bad Mach-O module '%s'\n", debugstr_w(module->module.LoadedImageName));
        return FALSE;
    }

    if (!fmap)
    {
        fmap = &my_fmap;
        ret = macho_map_file(module->module.LoadedImageName, fmap);
    }
    if (ret)
        ret = macho_load_debug_info_from_map(module, fmap);

    if (fmap == &my_fmap) macho_unmap_file(fmap);
    return ret;
}

/******************************************************************
 *              macho_fetch_file_info
 *
 * Gathers some more information for a Mach-O module from a given file
 */
BOOL macho_fetch_file_info(const WCHAR* name, DWORD_PTR* base,
                           DWORD* size, DWORD* checksum)
{
    struct macho_file_map fmap;

    TRACE("(%s, %p, %p, %p)\n", debugstr_w(name), base, size, checksum);

    if (!macho_map_file(name, &fmap)) return FALSE;
    if (base) *base = fmap.segs_start;
    *size = fmap.segs_size;
    *checksum = calc_crc32(fmap.fd);
    macho_unmap_file(&fmap);
    return TRUE;
}

/******************************************************************
 *              macho_load_file
 *
 * Loads the information for Mach-O module stored in 'filename'.
 * The module has been loaded at 'load_addr' address.
 * returns
 *      FALSE if the file cannot be found/opened or if the file doesn't
 *              contain symbolic info (or this info cannot be read or parsed)
 *      TRUE on success
 */
static BOOL macho_load_file(struct process* pcs, const WCHAR* filename,
                            unsigned long load_addr, struct macho_info* macho_info)
{
    BOOL                    ret = TRUE;
    struct macho_file_map   fmap;

    TRACE("(%p/%p, %s, 0x%08lx, %p/0x%08x)\n", pcs, pcs->handle, debugstr_w(filename),
            load_addr, macho_info, macho_info->flags);

    if (!macho_map_file(filename, &fmap)) return FALSE;

    /* Find the dynamic loader's table of images loaded into the process.
     */
    if (macho_info->flags & MACHO_INFO_DEBUG_HEADER)
    {
        static void* dyld_all_image_infos_addr;

        /* This symbol should be in the same place in all processes. */
        if (!dyld_all_image_infos_addr)
        {
            struct nlist nl[2];
            memset(nl, 0, sizeof(nl));
            nl[0].n_un.n_name = (char*)"_dyld_all_image_infos";
            if (!nlist("/usr/lib/dyld", nl))
                dyld_all_image_infos_addr = (void*)nl[0].n_value;
        }

        if (dyld_all_image_infos_addr)
            macho_info->dbg_hdr_addr = (unsigned long)dyld_all_image_infos_addr;
        else
            ret = FALSE;
        TRACE("dbg_hdr_addr = 0x%08lx\n", macho_info->dbg_hdr_addr);
    }

    if (macho_info->flags & MACHO_INFO_MODULE)
    {
        struct macho_module_info *macho_module_info;
        struct module_format*   modfmt =
            HeapAlloc(GetProcessHeap(), 0, sizeof(struct module_format) + sizeof(struct macho_module_info));
        if (!modfmt) goto leave;
        macho_info->module = module_new(pcs, filename, DMT_MACHO, FALSE, load_addr,
                                        fmap.segs_size, 0, calc_crc32(fmap.fd));
        if (!macho_info->module)
        {
            HeapFree(GetProcessHeap(), 0, modfmt);
            goto leave;
        }
        macho_module_info = (void*)(modfmt + 1);
        macho_info->module->format_info[DFI_MACHO] = modfmt;

        modfmt->module       = macho_info->module;
        modfmt->remove       = NULL;
        modfmt->loc_compute  = NULL;
        modfmt->u.macho_info = macho_module_info;

        macho_module_info->load_addr = load_addr;

        if (dbghelp_options & SYMOPT_DEFERRED_LOADS)
            macho_info->module->module.SymType = SymDeferred;
        else if (!macho_load_debug_info(macho_info->module, &fmap))
            ret = FALSE;

        macho_info->module->format_info[DFI_MACHO]->u.macho_info->in_use = 1;
        macho_info->module->format_info[DFI_MACHO]->u.macho_info->is_loader = 0;
        TRACE("module = %p\n", macho_info->module);
    }

    if (macho_info->flags & MACHO_INFO_NAME)
    {
        WCHAR*  ptr;
        ptr = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1) * sizeof(WCHAR));
        if (ptr)
        {
            strcpyW(ptr, filename);
            macho_info->module_name = ptr;
        }
        else ret = FALSE;
        TRACE("module_name = %p %s\n", macho_info->module_name, debugstr_w(macho_info->module_name));
    }
leave:
    macho_unmap_file(&fmap);

    TRACE(" => %d\n", ret);
    return ret;
}

/******************************************************************
 *              macho_load_file_from_path
 * Tries to load a Mach-O file from a set of paths (separated by ':')
 */
static BOOL macho_load_file_from_path(HANDLE hProcess,
                                      const WCHAR* filename,
                                      unsigned long load_addr,
                                      const char* path,
                                      struct macho_info* macho_info)
{
    BOOL                ret = FALSE;
    WCHAR               *s, *t, *fn;
    WCHAR*              pathW = NULL;
    unsigned            len;

    TRACE("(%p, %s, 0x%08lx, %s, %p)\n", hProcess, debugstr_w(filename), load_addr,
            debugstr_a(path), macho_info);

    if (!path) return FALSE;

    len = MultiByteToWideChar(CP_UNIXCP, 0, path, -1, NULL, 0);
    pathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
    if (!pathW) return FALSE;
    MultiByteToWideChar(CP_UNIXCP, 0, path, -1, pathW, len);

    for (s = pathW; s && *s; s = (t) ? (t+1) : NULL)
    {
        t = strchrW(s, ':');
        if (t) *t = '\0';
        fn = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1 + lstrlenW(s) + 1) * sizeof(WCHAR));
        if (!fn) break;
        strcpyW(fn, s);
        strcatW(fn, S_SlashW);
        strcatW(fn, filename);
        ret = macho_load_file(hProcess, fn, load_addr, macho_info);
        HeapFree(GetProcessHeap(), 0, fn);
        if (ret) break;
        s = (t) ? (t+1) : NULL;
    }

    TRACE(" => %d\n", ret);
    HeapFree(GetProcessHeap(), 0, pathW);
    return ret;
}

/******************************************************************
 *              macho_load_file_from_dll_path
 *
 * Tries to load a Mach-O file from the dll path
 */
static BOOL macho_load_file_from_dll_path(HANDLE hProcess,
                                          const WCHAR* filename,
                                          unsigned long load_addr,
                                          struct macho_info* macho_info)
{
    BOOL ret = FALSE;
    unsigned int index = 0;
    const char *path;

    TRACE("(%p, %s, 0x%08lx, %p)\n", hProcess, debugstr_w(filename), load_addr,
            macho_info);

    while (!ret && (path = wine_dll_enum_load_path( index++ )))
    {
        WCHAR *name;
        unsigned len;

        len = MultiByteToWideChar(CP_UNIXCP, 0, path, -1, NULL, 0);

        name = HeapAlloc( GetProcessHeap(), 0,
                          (len + lstrlenW(filename) + 2) * sizeof(WCHAR) );

        if (!name) break;
        MultiByteToWideChar(CP_UNIXCP, 0, path, -1, name, len);
        strcatW( name, S_SlashW );
        strcatW( name, filename );
        ret = macho_load_file(hProcess, name, load_addr, macho_info);
        HeapFree( GetProcessHeap(), 0, name );
    }
    TRACE(" => %d\n", ret);
    return ret;
}

/******************************************************************
 *              macho_search_and_load_file
 *
 * Lookup a file in standard Mach-O locations, and if found, load it
 */
static BOOL macho_search_and_load_file(struct process* pcs, const WCHAR* filename,
                                       unsigned long load_addr,
                                       struct macho_info* macho_info)
{
    BOOL                ret = FALSE;
    struct module*      module;
    static WCHAR        S_libstdcPPW[] = {'l','i','b','s','t','d','c','+','+','\0'};
    const WCHAR*        p;

    TRACE("(%p/%p, %s, 0x%08lx, %p)\n", pcs, pcs->handle, debugstr_w(filename), load_addr,
            macho_info);

    if (filename == NULL || *filename == '\0') return FALSE;
    if ((module = module_is_already_loaded(pcs, filename)))
    {
        macho_info->module = module;
        module->format_info[DFI_MACHO]->u.macho_info->in_use = 1;
        return module->module.SymType;
    }

    if (strstrW(filename, S_libstdcPPW)) return FALSE; /* We know we can't do it */

    /* If has no directories, try LD_LIBRARY_PATH first. */
    if (!strchrW(filename, '/'))
    {
        ret = macho_load_file_from_path(pcs, filename, load_addr,
                                      getenv("PATH"), macho_info);
    }
    /* Try DYLD_LIBRARY_PATH, with just the filename (no directories). */
    if (!ret)
    {
        if ((p = strrchrW(filename, '/'))) p++;
        else p = filename;
        ret = macho_load_file_from_path(pcs, p, load_addr,
                                      getenv("DYLD_LIBRARY_PATH"), macho_info);
    }
    /* Try the path as given. */
    if (!ret)
        ret = macho_load_file(pcs, filename, load_addr, macho_info);
    /* Try DYLD_FALLBACK_LIBRARY_PATH, with just the filename (no directories). */
    if (!ret)
    {
        ret = macho_load_file_from_path(pcs, p, load_addr,
                                      getenv("DYLD_FALLBACK_LIBRARY_PATH"), macho_info);
    }
    if (!ret && !strchrW(filename, '/'))
        ret = macho_load_file_from_dll_path(pcs, filename, load_addr, macho_info);

    return ret;
}

/******************************************************************
 *              macho_enum_modules_internal
 *
 * Enumerate Mach-O modules from a running process
 */
static BOOL macho_enum_modules_internal(const struct process* pcs,
                                        const WCHAR* main_name,
                                        enum_modules_cb cb, void* user)
{
    struct dyld_all_image_infos image_infos;
    struct dyld_image_info*     info_array = NULL;
    unsigned long               len;
    int                         i;
    char                        bufstr[256];
    WCHAR                       bufstrW[MAX_PATH];
    BOOL                        ret = FALSE;

    TRACE("(%p/%p, %s, %p, %p)\n", pcs, pcs->handle, debugstr_w(main_name), cb,
            user);

    if (!pcs->dbg_hdr_addr ||
        !ReadProcessMemory(pcs->handle, (void*)pcs->dbg_hdr_addr,
                           &image_infos, sizeof(image_infos), NULL) ||
        !image_infos.infoArray)
        goto done;
    TRACE("Process has %u image infos at %p\n", image_infos.infoArrayCount, image_infos.infoArray);

    len = image_infos.infoArrayCount * sizeof(info_array[0]);
    info_array = HeapAlloc(GetProcessHeap(), 0, len);
    if (!info_array ||
        !ReadProcessMemory(pcs->handle, image_infos.infoArray,
                           info_array, len, NULL))
        goto done;
    TRACE("... read image infos\n");

    for (i = 0; i < image_infos.infoArrayCount; i++)
    {
        if (info_array[i].imageFilePath != NULL &&
            ReadProcessMemory(pcs->handle, info_array[i].imageFilePath, bufstr, sizeof(bufstr), NULL))
        {
            bufstr[sizeof(bufstr) - 1] = '\0';
            TRACE("[%d] image file %s\n", i, debugstr_a(bufstr));
            MultiByteToWideChar(CP_UNIXCP, 0, bufstr, -1, bufstrW, sizeof(bufstrW) / sizeof(WCHAR));
            if (main_name && !bufstrW[0]) strcpyW(bufstrW, main_name);
            if (!cb(bufstrW, (unsigned long)info_array[i].imageLoadAddress, user)) break;
        }
    }

    ret = TRUE;
done:
    HeapFree(GetProcessHeap(), 0, info_array);
    return ret;
}

struct macho_sync
{
    struct process*     pcs;
    struct macho_info   macho_info;
};

static BOOL macho_enum_sync_cb(const WCHAR* name, unsigned long addr, void* user)
{
    struct macho_sync*  ms = user;

    TRACE("(%s, 0x%08lx, %p)\n", debugstr_w(name), addr, user);
    macho_search_and_load_file(ms->pcs, name, addr, &ms->macho_info);
    return TRUE;
}

/******************************************************************
 *              macho_synchronize_module_list
 *
 * Rescans the debuggee's modules list and synchronizes it with
 * the one from 'pcs', ie:
 * - if a module is in debuggee and not in pcs, it's loaded into pcs
 * - if a module is in pcs and not in debuggee, it's unloaded from pcs
 */
BOOL    macho_synchronize_module_list(struct process* pcs)
{
    struct module*      module;
    struct macho_sync     ms;

    TRACE("(%p/%p)\n", pcs, pcs->handle);

    for (module = pcs->lmodules; module; module = module->next)
    {
        if (module->type == DMT_MACHO && !module->is_virtual)
            module->format_info[DFI_MACHO]->u.macho_info->in_use = 0;
    }

    ms.pcs = pcs;
    ms.macho_info.flags = MACHO_INFO_MODULE;
    if (!macho_enum_modules_internal(pcs, NULL, macho_enum_sync_cb, &ms))
        return FALSE;

    module = pcs->lmodules;
    while (module)
    {
        if (module->type == DMT_MACHO && !module->is_virtual &&
            !module->format_info[DFI_MACHO]->u.macho_info->in_use &&
            !module->format_info[DFI_MACHO]->u.macho_info->is_loader)
        {
            module_remove(pcs, module);
            /* restart all over */
            module = pcs->lmodules;
        }
        else module = module->next;
    }
    return TRUE;
}

/******************************************************************
 *              macho_search_loader
 *
 * Lookup in a running Mach-O process the loader, and sets its Mach-O link
 * address (for accessing the list of loaded images) in pcs.
 * If flags is MACHO_INFO_MODULE, the module for the loader is also
 * added as a module into pcs.
 */
static BOOL macho_search_loader(struct process* pcs, struct macho_info* macho_info)
{
    return macho_search_and_load_file(pcs, get_wine_loader_name(), 0, macho_info);
}

/******************************************************************
 *              macho_read_wine_loader_dbg_info
 *
 * Try to find a decent wine executable which could have loaded the debuggee
 */
BOOL macho_read_wine_loader_dbg_info(struct process* pcs)
{
    struct macho_info     macho_info;

    TRACE("(%p/%p)\n", pcs, pcs->handle);
    macho_info.flags = MACHO_INFO_DEBUG_HEADER | MACHO_INFO_MODULE;
    if (!macho_search_loader(pcs, &macho_info)) return FALSE;
    macho_info.module->format_info[DFI_MACHO]->u.macho_info->is_loader = 1;
    module_set_module(macho_info.module, S_WineLoaderW);
    return (pcs->dbg_hdr_addr = macho_info.dbg_hdr_addr) != 0;
}

/******************************************************************
 *              macho_enum_modules
 *
 * Enumerates the Mach-O loaded modules from a running target (hProc)
 * This function doesn't require that someone has called SymInitialize
 * on this very process.
 */
BOOL macho_enum_modules(HANDLE hProc, enum_modules_cb cb, void* user)
{
    struct process      pcs;
    struct macho_info   macho_info;
    BOOL                ret;

    TRACE("(%p, %p, %p)\n", hProc, cb, user);
    memset(&pcs, 0, sizeof(pcs));
    pcs.handle = hProc;
    macho_info.flags = MACHO_INFO_DEBUG_HEADER | MACHO_INFO_NAME;
    if (!macho_search_loader(&pcs, &macho_info)) return FALSE;
    pcs.dbg_hdr_addr = macho_info.dbg_hdr_addr;
    ret = macho_enum_modules_internal(&pcs, macho_info.module_name, cb, user);
    HeapFree(GetProcessHeap(), 0, (char*)macho_info.module_name);
    return ret;
}

struct macho_load
{
    struct process*     pcs;
    struct macho_info   macho_info;
    const WCHAR*        name;
    BOOL                ret;
};

/******************************************************************
 *              macho_load_cb
 *
 * Callback for macho_load_module, used to walk the list of loaded
 * modules.
 */
static BOOL macho_load_cb(const WCHAR* name, unsigned long addr, void* user)
{
    struct macho_load*  ml = user;
    const WCHAR*        p;

    TRACE("(%s, 0x%08lx, %p)\n", debugstr_w(name), addr, user);

    /* memcmp is needed for matches when bufstr contains also version information
     * ml->name: libc.so, name: libc.so.6.0
     */
    p = strrchrW(name, '/');
    if (!p++) p = name;
    if (!memcmp(p, ml->name, lstrlenW(ml->name) * sizeof(WCHAR)))
    {
        ml->ret = macho_search_and_load_file(ml->pcs, name, addr, &ml->macho_info);
        return FALSE;
    }
    return TRUE;
}

/******************************************************************
 *              macho_load_module
 *
 * Loads a Mach-O module and stores it in process' module list.
 * Also, find module real name and load address from
 * the real loaded modules list in pcs address space.
 */
struct module*  macho_load_module(struct process* pcs, const WCHAR* name, unsigned long addr)
{
    struct macho_load   ml;

    TRACE("(%p/%p, %s, 0x%08lx)\n", pcs, pcs->handle, debugstr_w(name), addr);

    ml.macho_info.flags = MACHO_INFO_MODULE;
    ml.ret = FALSE;

    if (pcs->dbg_hdr_addr) /* we're debugging a live target */
    {
        ml.pcs = pcs;
        /* do only the lookup from the filename, not the path (as we lookup module
         * name in the process' loaded module list)
         */
        ml.name = strrchrW(name, '/');
        if (!ml.name++) ml.name = name;
        ml.ret = FALSE;

        if (!macho_enum_modules_internal(pcs, NULL, macho_load_cb, &ml))
            return NULL;
    }
    else if (addr)
    {
        ml.name = name;
        ml.ret = macho_search_and_load_file(pcs, ml.name, addr, &ml.macho_info);
    }
    if (!ml.ret) return NULL;
    assert(ml.macho_info.module);
    return ml.macho_info.module;
}

#else  /* HAVE_MACH_O_LOADER_H */

BOOL    macho_synchronize_module_list(struct process* pcs)
{
    return FALSE;
}

BOOL macho_fetch_file_info(const WCHAR* name, DWORD_PTR* base,
                           DWORD* size, DWORD* checksum)
{
    return FALSE;
}

BOOL macho_read_wine_loader_dbg_info(struct process* pcs)
{
    return FALSE;
}

BOOL macho_enum_modules(HANDLE hProc, enum_modules_cb cb, void* user)
{
    return FALSE;
}

struct module*  macho_load_module(struct process* pcs, const WCHAR* name, unsigned long addr)
{
    return NULL;
}

BOOL macho_load_debug_info(struct module* module, struct macho_file_map* fmap)
{
    return FALSE;
}
#endif  /* HAVE_MACH_O_LOADER_H */
