/*
 * 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 __MACH__

#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 = getpagesize() - 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 = getpagesize() - 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->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->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->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_info(&sym->symt, TI_GET_ADDRESS, &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(&sym->symt, TI_GET_LENGTH,   &size);
                symt_get_info(&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
            {
                symt_new_global_variable(module, ste->compiland, ste->ht_elt.name,
                    !ste->is_global, ste->addr, 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, ste->is_code, ste->is_code);
        }
    }
}

/******************************************************************
 *              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->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* 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 =
            HeapAlloc(GetProcessHeap(), 0, sizeof(struct macho_module_info));
        if (!macho_module_info) 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, macho_module_info);
            goto leave;
        }
        macho_info->module->macho_info = macho_module_info;
        macho_info->module->macho_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->macho_info->in_use = 1;
        macho_info->module->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->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->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->macho_info->in_use && !module->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)
{
    BOOL                ret;
    const char*         ptr;

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

    /* All binaries are loaded with WINELOADER (if run from tree) or by the
     * main executable
     */
    if ((ptr = getenv("WINELOADER")))
    {
        WCHAR   tmp[MAX_PATH];
        MultiByteToWideChar(CP_UNIXCP, 0, ptr, -1, tmp, sizeof(tmp) / sizeof(WCHAR));
        ret = macho_search_and_load_file(pcs, tmp, 0, macho_info);
    }
    else
    {
        ret = macho_search_and_load_file(pcs, S_WineW, 0, macho_info);
    }
    return ret;
}

/******************************************************************
 *              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->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   /* !__MACH__ */

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

BOOL macho_fetch_file_info(const WCHAR* name, DWORD* 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  /* __MACH__ */
