コード例 #1
0
/******************************************************************
 *              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;
}
コード例 #2
0
ファイル: pe_module.c プロジェクト: wine-mirror/wine
/******************************************************************
 *		pe_load_stabs
 *
 * look for stabs information in PE header (it's how the mingw compiler provides 
 * its debugging information)
 */
static BOOL pe_load_stabs(const struct process* pcs, struct module* module)
{
    struct image_file_map*      fmap = &module->format_info[DFI_PE]->u.pe_info->fmap;
    struct image_section_map    sect_stabs, sect_stabstr;
    BOOL                        ret = FALSE;

    if (pe_find_section(fmap, ".stab", &sect_stabs) && pe_find_section(fmap, ".stabstr", &sect_stabstr))
    {
        const char* stab;
        const char* stabstr;

        stab = image_map_section(&sect_stabs);
        stabstr = image_map_section(&sect_stabstr);
        if (stab != IMAGE_NO_MAP && stabstr != IMAGE_NO_MAP)
        {
            ret = stabs_parse(module,
                              module->module.BaseOfImage - fmap->u.pe.ntheader.OptionalHeader.ImageBase,
                              stab, image_get_map_size(&sect_stabs),
                              stabstr, image_get_map_size(&sect_stabstr),
                              NULL, NULL);
        }
        image_unmap_section(&sect_stabs);
        image_unmap_section(&sect_stabstr);
        if (ret) pe_locate_with_coff_symbol_table(module);
    }
    TRACE("%s the STABS debug info\n", ret ? "successfully loaded" : "failed to load");

    return ret;
}
コード例 #3
0
ファイル: pe_module.c プロジェクト: WASSUM/longene_travel
/******************************************************************
 *		pe_load_stabs
 *
 * look for stabs information in PE header (it's how the mingw compiler provides 
 * its debugging information)
 */
static BOOL pe_load_stabs(const struct process* pcs, struct module* module, 
                          void* mapping, IMAGE_NT_HEADERS* nth)
{
    IMAGE_SECTION_HEADER*       section;
    int                         i, stabsize = 0, stabstrsize = 0;
    unsigned int                stabs = 0, stabstr = 0;
    BOOL                        ret = FALSE;

    section = (IMAGE_SECTION_HEADER*)
        ((char*)&nth->OptionalHeader + nth->FileHeader.SizeOfOptionalHeader);
    for (i = 0; i < nth->FileHeader.NumberOfSections; i++, section++)
    {
        if (!strcasecmp((const char*)section->Name, ".stab"))
        {
            stabs = section->VirtualAddress;
            stabsize = section->SizeOfRawData;
        }
        else if (!strncasecmp((const char*)section->Name, ".stabstr", 8))
        {
            stabstr = section->VirtualAddress;
            stabstrsize = section->SizeOfRawData;
        }
    }

    if (stabstrsize && stabsize)
    {
        ret = stabs_parse(module, 
                          module->module.BaseOfImage - nth->OptionalHeader.ImageBase, 
                          RtlImageRvaToVa(nth, mapping, stabs, NULL),
                          stabsize,
                          RtlImageRvaToVa(nth, mapping, stabstr, NULL),
                          stabstrsize);
    }

    TRACE("%s the STABS debug info\n", ret ? "successfully loaded" : "failed to load");
    return ret;
}
コード例 #4
0
ファイル: mach_module.c プロジェクト: NVIDIA/winex_lgpl
/* machLoadDebugInfo(): attempts to load the debug information for the module identified by 
     <module>.  If <map> is NULL, the dylib name is generated from the image name stored 
     in <module> and the file's header and debug information is read into <map> if found.
     If <map> is non-NULL, it is assumed that the debug information has already been read
     into it, and parses from that instead.  Returns TRUE if the file was found, successfully 
     opened, and had its debug information parsed.  Returns FALSE on failure. */
BOOL machLoadDebugInfo(struct process *pcs, struct module *module, MachMap *map){
    MachMap _map;
    BOOL    opened = FALSE;
    BOOL    ret = FALSE;
    int     i;
    DWORD64 loadOffset = 0;


    TRACE("loading the debug information for %s {module = %p, map = %p}\n", debugstr_w(module->module.LoadedImageName), module, map);

    /* the file has not been mapped yet => map it now */
    if (map == NULL){
        /* this isn't a mach file or it couldn't be loaded => fail */
        if (!machIsMachFile(module->module.LoadedImageName, NULL, &_map)){
            ERR("could not map the image file %s into memory\n", debugstr_w(module->module.LoadedImageName));

            return FALSE;
        }

        map = &_map;
        opened = TRUE;
    }


    /* try to retrieve the load offset from the NT header.  The module base address that is passed
       into machLoadModule() and that is stored in 'module->module.BaseOfImage' is not entirely the
       correct address.  The symbol addresses stored in the debug information are relative to the
       start of the mach module itself, and that always seems to load at an address 0x2000 bytes
       below the module's base address.  Unfortunately, all the addresses that get passed to the
       SymFromAddr() function are relative to the address stored in 'module->module.BaseOfImage.
       Happily, the offset between these two addresses is stored in the module's header for the
       text section (IMAGE_SECTION_HEADER).  We'll attempt to grab the offset from there instead
       of hardcoding it.  The load offset will be applied to all the symbol addresses as they are
       parsed. */
    if (module->module.BaseOfImage){
        IMAGE_NT_HEADERS nt;


        /* read the NT header => attempt to grab a section header and extract the load offset */
        if (pe_load_nt_header(pcs->handle, module->module.BaseOfImage, &nt)){
            IMAGE_SECTION_HEADER    sec;
            int                     i;


            for (i = 0; i < nt.FileHeader.NumberOfSections; i++){
                if (pe_load_nt_sect_header(pcs->handle, module->module.BaseOfImage, i, &nt, &sec)){
                    if (!strcmp((char *)sec.Name, ".text")){
                        loadOffset = (DWORD64)(signed)sec.VirtualAddress;

                        break;
                    }
                }
            }

            if (loadOffset == 0)
                WARN("could not find a valid text section header.  Assuming a load offset of 0.  Symbol lookups will fail in this module\n");
        }

        else{
            /* HACK!!!  This value seems to be the correct offset for our modules, but we
                        couldn't calculate it because this module isn't currently loaded.
                        Setting this offset here allows symbols from non-resident modules
                        to still be looked up by address (assuming the base address was
                        correctly specified as well). */
            loadOffset = -0x2000ll;
            FIXME("module could not be read from.  Assuming a load offset of 0x%08llx\n", loadOffset);
        }
    }

    else
        ERR("no module base specified or found.  Symbol lookups in this module will fail!\n");



    for (i = 0; i < map->numLoadCmds; i++){
        switch (map->loadCmds[i].header->cmd){
            case LC_SYMTAB:
                TRACE("parsing the STABS debug information {BaseOfImage = 0x%08llx, loadOffset = 0x%08llx}\n", 
                        module->module.BaseOfImage,
                        loadOffset);

                ret = stabs_parse(  module,
                                    module->module.BaseOfImage + loadOffset,
                                    map->loadCmds[i].data.stabs.stab,
                                    map->loadCmds[i].data.stabs.stabSize,
                                    (const char *)map->loadCmds[i].data.stabs.strings,
                                    map->loadCmds[i].data.stabs.stringsSize);

                TRACE("%s the STABS debug information\n", ret ? "SUCCESSFULLY loaded" : "FAILED to load");
                break;

            case LC_DYSYMTAB:
                /* FIXME!! figure out if we need to load or fixup anything from this table */
                FIXME("figure out if we need to load or fixup anything from the dynamic symbol table\n");
                break;

            default:
                continue;
        }
    }


    TRACE("done loading debug information for %s\n", debugstr_w(module->module.LoadedImageName));

    if (opened)
        machUnmapFile(map);

    return ret;
}