⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msc.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
    const unsigned int*         filetab;
    const struct p_string*      p_fn;
    int				i;
    int				k;
    struct codeview_linetab*    lt_hdr;
    const unsigned int*         lt_ptr;
    int				nfile;
    int				nseg;
    union any_size		pnt;
    union any_size		pnt2;
    const struct startend*      start;
    int				this_seg;
    struct symt_compiland*      compiland;
 
    /*
     * Now get the important bits.
     */
    pnt.c = linetab;
    nfile = *pnt.s++;
    nseg = *pnt.s++;
 
    filetab = (const unsigned int*) pnt.c;
 
    /*
     * Now count up the number of segments in the file.
     */
    nseg = 0;
    for (i = 0; i < nfile; i++)
    {
        pnt2.c = linetab + filetab[i];
        nseg += *pnt2.s;
    }
 
    /*
     * Next allocate the header we will be returning.
     * There is one header for each segment, so that we can reach in
     * and pull bits as required.
     */
    lt_hdr = (struct codeview_linetab*)
        HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nseg + 1) * sizeof(*lt_hdr));
    if (lt_hdr == NULL)
    {
        goto leave;
    }
 
    /*
     * Now fill the header we will be returning, one for each segment.
     * Note that this will basically just contain pointers into the existing
     * line table, and we do not actually copy any additional information
     * or allocate any additional memory.
     */
 
    this_seg = 0;
    for (i = 0; i < nfile; i++)
    {
        /*
         * Get the pointer into the segment information.
         */
        pnt2.c = linetab + filetab[i];
        file_segcount = *pnt2.s;
 
        pnt2.ui++;
        lt_ptr = (const unsigned int*) pnt2.c;
        start = (const struct startend*)(lt_ptr + file_segcount);
 
        /*
         * Now snarf the filename for all of the segments for this file.
         */
        if (pascal_str)
        {
            p_fn = (const struct p_string*)(start + file_segcount);
            memset(filename, 0, sizeof(filename));
            memcpy(filename, p_fn->name, p_fn->namelen);
            compiland = symt_new_compiland(module, filename);
        }
        else
            compiland = symt_new_compiland(module, (const char*)(start + file_segcount));
 
        for (k = 0; k < file_segcount; k++, this_seg++)
	{
            pnt2.c = linetab + lt_ptr[k];
            lt_hdr[this_seg].start      = start[k].start;
            lt_hdr[this_seg].end        = start[k].end;
            lt_hdr[this_seg].compiland  = compiland;
            lt_hdr[this_seg].segno      = *pnt2.s++;
            lt_hdr[this_seg].nline      = *pnt2.s++;
            lt_hdr[this_seg].offtab     = pnt2.ui;
            lt_hdr[this_seg].linetab    = (const unsigned short*)(pnt2.ui + lt_hdr[this_seg].nline);
	}
    }
 
leave:
 
  return lt_hdr;
 
}
 
/*========================================================================
 * Process CodeView symbol information.
 */
 
static unsigned int codeview_map_offset(const struct msc_debug_info* msc_dbg,
                                        unsigned int offset)
{
    int                 nomap = msc_dbg->nomap;
    const OMAP_DATA*    omapp = msc_dbg->omapp;
    int                 i;
 
    if (!nomap || !omapp) return offset;
 
    /* FIXME: use binary search */
    for (i = 0; i < nomap - 1; i++)
        if (omapp[i].from <= offset && omapp[i+1].from > offset)
            return !omapp[i].to ? 0 : omapp[i].to + (offset - omapp[i].from);
 
    return 0;
}
 
static const struct codeview_linetab*
codeview_get_linetab(const struct codeview_linetab* linetab,
                     unsigned seg, unsigned offset)
{
    /*
     * Check whether we have line number information
     */
    if (linetab)
    {
        for (; linetab->linetab; linetab++)
            if (linetab->segno == seg &&
                linetab->start <= offset && linetab->end   >  offset)
                break;
        if (!linetab->linetab) linetab = NULL;
    }
    return linetab;
}
 
static unsigned codeview_get_address(const struct msc_debug_info* msc_dbg, 
                                     unsigned seg, unsigned offset)
{
    int			        nsect = msc_dbg->nsect;
    const IMAGE_SECTION_HEADER* sectp = msc_dbg->sectp;
 
    if (!seg || seg > nsect) return 0;
    return msc_dbg->module->module.BaseOfImage +
        codeview_map_offset(msc_dbg, sectp[seg-1].VirtualAddress + offset);
}
 
static void codeview_add_func_linenum(struct module* module, 
                                      struct symt_function* func,
                                      const struct codeview_linetab* linetab,
                                      unsigned offset, unsigned size)
{
    unsigned int        i;
 
    if (!linetab) return;
    for (i = 0; i < linetab->nline; i++)
    {
        if (linetab->offtab[i] >= offset && linetab->offtab[i] < offset + size)
        {
            symt_add_func_line(module, func, linetab->compiland->source,
                               linetab->linetab[i], linetab->offtab[i] - offset);
        }
    }
}
 
static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root, 
                          int offset, int size,
                          struct codeview_linetab* linetab)
{
    struct symt_function*               curr_func = NULL;
    int                                 i, length;
    const struct codeview_linetab*      flt;
    struct symt_block*                  block = NULL;
    struct symt*                        symt;
    const char*                         name;
 
    /*
     * Loop over the different types of records and whenever we
     * find something we are interested in, record it and move on.
     */
    for (i = offset; i < size; i += length)
    {
        const union codeview_symbol* sym = (const union codeview_symbol*)(root + i);
        length = sym->generic.len + 2;
        if (length & 3) FIXME("unpadded len %u\n", length + 2);
 
        switch (sym->generic.id)
        {
        /*
         * Global and local data symbols.  We don't associate these
         * with any given source file.
         */
	case S_GDATA_V1:
	case S_LDATA_V1:
            flt = codeview_get_linetab(linetab, sym->data_v1.segment, sym->data_v1.offset);
            symt_new_global_variable(msc_dbg->module, 
                                     flt ? flt->compiland : NULL,
                                     terminate_string(&sym->data_v1.p_name), sym->generic.id == S_LDATA_V1,
                                     codeview_get_address(msc_dbg, sym->data_v1.segment, sym->data_v1.offset),
                                     0,
                                     codeview_get_type(sym->data_v1.symtype, FALSE));
	    break;
	case S_GDATA_V2:
	case S_LDATA_V2:
            flt = codeview_get_linetab(linetab, sym->data_v2.segment, sym->data_v2.offset);
            name = terminate_string(&sym->data_v2.p_name);
            if (name)
                symt_new_global_variable(msc_dbg->module, flt ? flt->compiland : NULL,
                                         name, sym->generic.id == S_LDATA_V2,
                                         codeview_get_address(msc_dbg, sym->data_v2.segment, sym->data_v2.offset),
                                         0,
                                         codeview_get_type(sym->data_v2.symtype, FALSE));
	    break;
	case S_GDATA_V3:
	case S_LDATA_V3:
            flt = codeview_get_linetab(linetab, sym->data_v3.segment, sym->data_v3.offset);
            if (*sym->data_v3.name)
                symt_new_global_variable(msc_dbg->module, flt ? flt->compiland : NULL,
                                         sym->data_v3.name,
                                         sym->generic.id == S_LDATA_V3,
                                         codeview_get_address(msc_dbg, sym->data_v3.segment, sym->data_v3.offset),
                                         0,
                                         codeview_get_type(sym->data_v3.symtype, FALSE));
	    break;
 
	case S_PUB_V1: /* FIXME is this really a 'data_v1' structure ?? */
            if (!(dbghelp_options & SYMOPT_NO_PUBLICS))
            {
                flt = codeview_get_linetab(linetab, sym->data_v1.segment, sym->data_v1.offset);
                symt_new_public(msc_dbg->module, flt ? flt->compiland : NULL,
                                terminate_string(&sym->data_v1.p_name), 
                                codeview_get_address(msc_dbg, sym->data_v1.segment, sym->data_v1.offset),
                                0, TRUE /* FIXME */, TRUE /* FIXME */);
            }
            break;
	case S_PUB_V2: /* FIXME is this really a 'data_v2' structure ?? */
            if (!(dbghelp_options & SYMOPT_NO_PUBLICS))
            {
                flt = codeview_get_linetab(linetab, sym->data_v2.segment, sym->data_v2.offset);
                symt_new_public(msc_dbg->module, flt ? flt->compiland : NULL,
                                terminate_string(&sym->data_v2.p_name), 
                                codeview_get_address(msc_dbg, sym->data_v2.segment, sym->data_v2.offset),
                                0, TRUE /* FIXME */, TRUE /* FIXME */);
            }
	    break;
 
        /*
         * Sort of like a global function, but it just points
         * to a thunk, which is a stupid name for what amounts to
         * a PLT slot in the normal jargon that everyone else uses.
         */
	case S_THUNK_V1:
            flt = codeview_get_linetab(linetab, sym->thunk_v1.segment, sym->thunk_v1.offset);
            symt_new_thunk(msc_dbg->module, flt ? flt->compiland : NULL,
                           terminate_string(&sym->thunk_v1.p_name), sym->thunk_v1.thtype,
                           codeview_get_address(msc_dbg, sym->thunk_v1.segment, sym->thunk_v1.offset),
                           sym->thunk_v1.thunk_len);
	    break;
	case S_THUNK_V3:
            flt = codeview_get_linetab(linetab, sym->thunk_v3.segment, sym->thunk_v3.offset);
            symt_new_thunk(msc_dbg->module, flt ? flt->compiland : NULL,
                           sym->thunk_v3.name, sym->thunk_v3.thtype,
                           codeview_get_address(msc_dbg, sym->thunk_v3.segment, sym->thunk_v3.offset),
                           sym->thunk_v3.thunk_len);
	    break;
 
        /*
         * Global and static functions.
         */
	case S_GPROC_V1:
	case S_LPROC_V1:
            flt = codeview_get_linetab(linetab, sym->proc_v1.segment, sym->proc_v1.offset);
            if (curr_func) FIXME("nested function\n");
            curr_func = symt_new_function(msc_dbg->module,
                                          flt ? flt->compiland : NULL,
                                          terminate_string(&sym->proc_v1.p_name),
                                          codeview_get_address(msc_dbg, sym->proc_v1.segment, sym->proc_v1.offset),
                                          sym->proc_v1.proc_len,
                                          codeview_get_type(sym->proc_v1.proctype, FALSE));
            codeview_add_func_linenum(msc_dbg->module, curr_func, flt, 
                                      sym->proc_v1.offset, sym->proc_v1.proc_len);
            symt_add_function_point(msc_dbg->module, curr_func, SymTagFuncDebugStart, sym->proc_v1.debug_start, NULL);
            symt_add_function_point(msc_dbg->module, curr_func, SymTagFuncDebugEnd, sym->proc_v1.debug_end, NULL);
	    break;
	case S_GPROC_V2:
	case S_LPROC_V2:
            flt = codeview_get_linetab(linetab, sym->proc_v2.segment, sym->proc_v2.offset);
            if (curr_func) FIXME("nested function\n");
            curr_func = symt_new_function(msc_dbg->module, 
                                          flt ? flt->compiland : NULL,
                                          terminate_string(&sym->proc_v2.p_name),
                                          codeview_get_address(msc_dbg, sym->proc_v2.segment, sym->proc_v2.offset),
                                          sym->proc_v2.proc_len,
                                          codeview_get_type(sym->proc_v2.proctype, FALSE));
            codeview_add_func_linenum(msc_dbg->module, curr_func, flt, 
                                      sym->proc_v2.offset, sym->proc_v2.proc_len);
            symt_add_function_point(msc_dbg->module, curr_func, SymTagFuncDebugStart, sym->proc_v2.debug_start, NULL);
            symt_add_function_point(msc_dbg->module, curr_func, SymTagFuncDebugEnd, sym->proc_v2.debug_end, NULL);
	    break;
	case S_GPROC_V3:
	case S_LPROC_V3:
            flt = codeview_get_linetab(linetab, sym->proc_v3.segment, sym->proc_v3.offset);
            if (curr_func) FIXME("nested function\n");
            curr_func = symt_new_function(msc_dbg->module, 
                                          flt ? flt->compiland : NULL,
                                          sym->proc_v3.name,
                                          codeview_get_address(msc_dbg, sym->proc_v3.segment, sym->proc_v3.offset),
                                          sym->proc_v3.proc_len,
                                          codeview_get_type(sym->proc_v3.proctype, FALSE));
            codeview_add_func_linenum(msc_dbg->module, curr_func, flt, 
                                      sym->proc_v3.offset, sym->proc_v3.proc_len);
            symt_add_function_point(msc_dbg->module, curr_func, SymTagFuncDebugStart, sym->proc_v3.debug_start, NULL);
            symt_add_function_point(msc_dbg->module, curr_func, SymTagFuncDebugEnd, sym->proc_v3.debug_end, NULL);
	    break;
        /*
         * Function parameters and stack variables.
         */
	case S_BPREL_V1:
            symt_add_func_local(msc_dbg->module, curr_func, 0, sym->stack_v1.offset,
                                block, codeview_get_type(sym->stack_v1.symtype, FALSE),
                                terminate_string(&sym->stack_v1.p_name));
            break;
	case S_BPREL_V2:
            symt_add_func_local(msc_dbg->module, curr_func, 0, sym->stack_v2.offset,
                                block, codeview_get_type(sym->stack_v2.symtype, FALSE),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -