Exemple #1
0
static int dw_iter_by_addr(struct ps_prochandle *P, const char *object_name, int which,
                           int mask, proc_sym_f *func, void *cd)
{
    int fd = 0, ret = -1, i, index = 0;
    Pe_object *pe;
    proc_mod_t *mod = findmodulebyname(P, object_name);

    fd = _open(mod->fullname, _O_RDONLY|_O_BINARY, 0);

    if (fd == -1 )
        return -1;

    if  ((pe = pe_init(fd)) != NULL) {
        IMAGE_SYMBOL *Sym = pe_getsymarr(pe, &index);
        char name[MAX_SYM_NAME];

        if (Sym == NULL)
            goto end;
        ret = 0;
        for (i = 0; i < index; i++) {
            GElf_Sym symp;
            char *n = NULL;

            if (ISFCN(Sym[i].Type) == 0)
                continue;
            symp.st_name = 0;
            symp.st_other = 0;
            symp.st_info = GELF_ST_INFO((STB_GLOBAL), (STT_FUNC));
            symp.st_shndx = 1;
            symp.st_value = Sym[i].Value+mod->imgbase+pe_getsecva(pe, Sym[i].SectionNumber);
            /* If size is zero libdtrace will reject the probe.Allow creation of entry probe */
            symp.st_size = 1;
            if (pe_getsymname(pe, &Sym[i], name, MAX_SYM_NAME) == NULL)
                continue;

            if (pe_getarch(pe) == PE_ARCH_I386)
                func(cd, &symp, &name[1]);
            else
                func(cd, &symp, name);
        }
    }
end:
    if (pe != NULL)
        pe_end(pe);
    if (fd != -1)
        close(fd);
    return ret;
}
Exemple #2
0
static int dw_lookup_by_name(struct ps_prochandle *P, const char *oname, const char *sname, GElf_Sym *symp)
{
    IMAGE_SYMBOL Sym;
    int ret = -1, fd;
    Pe_object *pe;
    proc_mod_t *mod;

    mod = findmodulebyname(P, oname);
    if (mod == NULL)
        return -1;

    fd = _open(mod->fullname, _O_RDONLY|_O_BINARY, 0);

    if (fd != -1 && (pe = pe_init(fd)) != NULL) {
        char s[MAX_SYM_NAME];

        if (pe_getarch(pe) == PE_ARCH_I386) {
            s[0] = '_';
            strcpy(&s[1], sname);
        } else {
            strcpy(s, sname);
        }

        if (pe_getsymbyname(pe, s, &Sym) != NULL) {
            symp->st_name = 0;
            symp->st_other = 0;
            if (ISFCN(Sym.Type)) {
                symp->st_info = GELF_ST_INFO((STB_GLOBAL), (STT_FUNC));
                symp->st_shndx = 1;
            } else {
                symp->st_info = GELF_ST_INFO((STB_GLOBAL), (STT_NOTYPE));
                symp->st_shndx = SHN_UNDEF;
            }
            symp->st_value = Sym.Value + mod->imgbase + pe_getsecva(pe, Sym.SectionNumber);
            /* If size is zero libdtrace will reject the function. Allow creation of entry probe */
            symp->st_size = 1;
            ret = 0;
        }
    }

    if (pe != NULL)
        pe_end(pe);
    if (fd != -1)
        close(fd);

    return ret;
}
Exemple #3
0
static void
obj_coff_type (int ignore ATTRIBUTE_UNUSED)
{
  if (def_symbol_in_progress == NULL)
    {
      as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
      demand_empty_rest_of_line ();
      return;
    }

  S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());

  if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
      S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
    SF_SET_FUNCTION (def_symbol_in_progress);

  demand_empty_rest_of_line ();
}
Exemple #4
0
static int dw_lookup_by_addr(struct ps_prochandle *P, uintptr_t addr, char *buf, size_t size, GElf_Sym *symp)
{
    proc_mod_t *mod = NULL;
    int fd, ret = -1, index, i;
    Pe_object *pe;

    mod = findmodulebyaddr(P, addr);
    if (mod == NULL)
        return -1;

    fd = _open(mod->fullname, _O_RDONLY|_O_BINARY, 0);

    if (fd == -1 )
        return -1;

    if ((pe = pe_init(fd)) != NULL) {
        IMAGE_SYMBOL *Sym = pe_getsymarr(pe, &index);
        char name[MAX_SYM_NAME];

        int secno, addr1, mark = -1, prev = 0, va;

        if (Sym == NULL)
            goto end;

        if ((secno = pe_getsecnofromaddr(pe, addr - mod->imgbase))== 0)
            goto end;

        va = pe_getsecva(pe, secno);
        addr1 = addr - (mod->imgbase + va);
        if (addr1 <= 0)
            goto end;
        for (i = 0; i < index; i++) {
            if (ISFCN(Sym[i].Type) == 0 || Sym[i].SectionNumber != secno)
                continue;
            if (addr1 == Sym[i].Value) {
                mark = i;
                break;
            } else if (addr1 > Sym[i].Value) {
                if (prev < Sym[i].Value) {
                    prev = Sym[i].Value;
                    mark = i;
                }
            }
        }
        if (mark >= 0) {
            symp->st_name = 0;
            symp->st_other = 0;
            symp->st_info = GELF_ST_INFO((STB_GLOBAL), (STT_FUNC));
            symp->st_shndx = 1;
            symp->st_value = Sym[mark].Value + mod->imgbase
                             + pe_getsecva(pe, Sym[mark].SectionNumber);
            /* If size is zero libdtrace will reject the function. Allow creation of entry probe */
            symp->st_size = 1;

            if (pe_getsymname(pe, &Sym[mark], name, MAX_SYM_NAME) == NULL)
                goto end;
            if (pe_getarch(pe) == PE_ARCH_I386) {
                strncpy(buf, &name[1], size);
            } else {
                strncpy(buf, name, size);
            }

            ret = 0;
        }
    }
end:
    if (pe != NULL)
        pe_end(pe);
    if (fd != -1)
        close(fd);

    return ret;
}
void PE_Debug::DumpSymbolInfo(std::ostream& dumpBuffer, DWORD relativeAddress )
{
    // Variables to keep track of function symbols
    PIMAGE_SYMBOL currentSym = COFFSymbolTable ;
    PIMAGE_SYMBOL fnSymbol = NULL ;
    DWORD maxFnAddress = 0 ;

#ifdef DUMPRAM
    InitSymbols();
#endif

    // Variables to keep track of file symbols
    PIMAGE_SYMBOL fileSymbol = NULL ;
    PIMAGE_SYMBOL latestFileSymbol = NULL ;
    for ( int i = 0; i < COFFSymbolCount; i++ )	{

        // Look for .text section where relativeAddress belongs to.
        // Keep track of the filename the .text section belongs to.
        if ( currentSym->StorageClass == IMAGE_SYM_CLASS_FILE )	{
            latestFileSymbol = currentSym;
        }

        // Borland uses "CODE" instead of the standard ".text" entry
        // Microsoft uses sections that only _begin_ with .text
        const char* symName = GetSymbolName( currentSym ) ;

        if ( strnicmp( symName, ".text", 5 ) == 0 || strcmpi( symName, "CODE" ) == 0 )	{
            if ( currentSym->Value <= relativeAddress )	{
                PIMAGE_AUX_SYMBOL auxSym = (PIMAGE_AUX_SYMBOL)(currentSym + 1) ;
                if ( currentSym->Value + auxSym->Section.Length >= relativeAddress )	{
                    fileSymbol = latestFileSymbol ;
                }
            }
        }


        // Look for the function with biggest address <= relativeAddress
        BOOL isFunction = ISFCN( currentSym->Type ); // Type == 0x20, See WINNT.H
        if ( isFunction && ( currentSym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL || currentSym->StorageClass == IMAGE_SYM_CLASS_STATIC ) )	{

            if ( currentSym->Value <= relativeAddress && currentSym->Value > maxFnAddress )	{
                maxFnAddress = currentSym->Value ;
                fnSymbol = currentSym ;
            }
        }

#ifdef DUMPRAM
        if ( !isFunction && (currentSym->SectionNumber >= 0) )	{
            if ( (symName[0]=='_' && symName[1]!='$') || (symName[0]=='?') ) {

                char pretty_module[1024];

                if ( fileSymbol )	{
                    const char* auxSym = (const char*)(latestFileSymbol + 1) ;
                    char tmpFile[ VA_MAX_FILENAME_LEN ] ;
                    strcpy_s( tmpFile, auxSym ) ;
                    strcpy_s( pretty_module, tmpFile );
                    char *p = pretty_module+strlen(pretty_module)-1;
                    // Move p to point to first letter of EXE filename
                    while( (*p!='\\') && (*p!='/') && (*p!=':') )
                        p--;
                    p++;
                    if ( strlen(p) < 1 ) {
                        strcpy_s( pretty_module, "<unknown>" );
                    } else {
                        memmove( pretty_module, p, strlen(p)+1 );
                    }
                } else {
                    strcpy_s( pretty_module, "" );
                }

                Add_Symbol( currentSym->SectionNumber, currentSym->Value, symName, pretty_module );
            }
        }
#endif

        // Advance counters, skip aux symbols
        i += currentSym->NumberOfAuxSymbols ;
        currentSym += currentSym->NumberOfAuxSymbols ;
        currentSym++ ;
    }

#ifdef DUMPRAM
    DumpSymbols();
#endif

    // dump symbolic info if found
    if ( fileSymbol )	{
        const char* auxSym = (const char*)(fileSymbol + 1) ;

        if( strcmpi( latestFile, auxSym ) )	{
            strcpy_s( latestFile, auxSym ) ;
            //JAS      dumpBuffer.Printf( "  file: %s\r\n", auxSym ) ;
        }
    } else {
        latestFile[ 0 ] = 0 ;
        //JAS    dumpBuffer.Printf( "  file: unknown\r\n" ) ;
    }

    if ( fnSymbol )	{
        char tmp_name[1024];
        unmangle(tmp_name, GetSymbolName( fnSymbol ) );
        dumpBuffer << "    " << tmp_name << "()";
    } else {
        dumpBuffer << "    <unknown>";
    }
}
Exemple #6
0
static debug_type
parse_coff_type (bfd *abfd, struct coff_symbols *symbols,
		 struct coff_types *types, long coff_symno, int ntype,
		 union internal_auxent *pauxent, bfd_boolean useaux,
		 void *dhandle)
{
  debug_type type;

  if ((ntype & ~N_BTMASK) != 0)
    {
      int newtype;

      newtype = DECREF (ntype);

      if (ISPTR (ntype))
	{
	  type = parse_coff_type (abfd, symbols, types, coff_symno, newtype,
				  pauxent, useaux, dhandle);
	  type = debug_make_pointer_type (dhandle, type);
	}
      else if (ISFCN (ntype))
	{
	  type = parse_coff_type (abfd, symbols, types, coff_symno, newtype,
				  pauxent, useaux, dhandle);
	  type = debug_make_function_type (dhandle, type, (debug_type *) NULL,
					   FALSE);
	}
      else if (ISARY (ntype))
	{
	  int n;

	  if (pauxent == NULL)
	    n = 0;
	  else
	    {
	      unsigned short *dim;
	      int i;

	      /* FIXME: If pauxent->x_sym.x_tagndx.l == 0, gdb sets
                 the c_naux field of the syment to 0.  */

	      /* Move the dimensions down, so that the next array
                 picks up the next one.  */
	      dim = pauxent->x_sym.x_fcnary.x_ary.x_dimen;
	      n = dim[0];
	      for (i = 0; *dim != 0 && i < DIMNUM - 1; i++, dim++)
		*dim = *(dim + 1);
	      *dim = 0;
	    }

	  type = parse_coff_type (abfd, symbols, types, coff_symno, newtype,
				  pauxent, FALSE, dhandle);
	  type = debug_make_array_type (dhandle, type,
					parse_coff_base_type (abfd, symbols,
							      types,
							      coff_symno,
							      T_INT,
							      NULL, dhandle),
					0, n - 1, FALSE);
	}
      else
	{
	  non_fatal (_("parse_coff_type: Bad type code 0x%x"), ntype);
	  return DEBUG_TYPE_NULL;
	}

      return type;
    }

  if (pauxent != NULL && pauxent->x_sym.x_tagndx.l > 0)
    {
      debug_type *slot;

      /* This is a reference to an existing type.  FIXME: gdb checks
	 that the class is not C_STRTAG, nor C_UNTAG, nor C_ENTAG.  */
      slot = coff_get_slot (types, pauxent->x_sym.x_tagndx.l);
      if (*slot != DEBUG_TYPE_NULL)
	return *slot;
      else
	return debug_make_indirect_type (dhandle, slot, (const char *) NULL);
    }

  /* If the aux entry has already been used for something, useaux will
     have been set to false, indicating that parse_coff_base_type
     should not use it.  We need to do it this way, rather than simply
     passing pauxent as NULL, because we need to be able handle
     multiple array dimensions while still discarding pauxent after
     having handled all of them.  */
  if (! useaux)
    pauxent = NULL;

  return parse_coff_base_type (abfd, symbols, types, coff_symno, ntype,
			       pauxent, dhandle);
}
Exemple #7
0
DECLSPEC_HIDDEN BOOL coff_process_info(const struct msc_debug_info* msc_dbg)
{
    const IMAGE_AUX_SYMBOL*		aux;
    const IMAGE_COFF_SYMBOLS_HEADER*	coff;
    const IMAGE_LINENUMBER*		coff_linetab;
    const IMAGE_LINENUMBER*		linepnt;
    const char*                         coff_strtab;
    const IMAGE_SYMBOL* 		coff_sym;
    const IMAGE_SYMBOL* 		coff_symbols;
    struct CoffFileSet	                coff_files;
    int				        curr_file_idx = -1;
    unsigned int		        i;
    int			       	        j;
    int			       	        k;
    int			       	        l;
    int		       		        linetab_indx;
    const char*                         nampnt;
    int		       		        naux;
    BOOL                                ret = FALSE;
    ULONG64                             addr;

    TRACE("Processing COFF symbols...\n");

    assert(sizeof(IMAGE_SYMBOL) == IMAGE_SIZEOF_SYMBOL);
    assert(sizeof(IMAGE_LINENUMBER) == IMAGE_SIZEOF_LINENUMBER);

    coff_files.files = NULL;
    coff_files.nfiles = coff_files.nfiles_alloc = 0;

    coff = (const IMAGE_COFF_SYMBOLS_HEADER*)msc_dbg->root;

    coff_symbols = (const IMAGE_SYMBOL*)((const char *)coff + coff->LvaToFirstSymbol);
    coff_linetab = (const IMAGE_LINENUMBER*)((const char *)coff + coff->LvaToFirstLinenumber);
    coff_strtab = (const char*)(coff_symbols + coff->NumberOfSymbols);

    linetab_indx = 0;

    for (i = 0; i < coff->NumberOfSymbols; i++)
    {
        coff_sym = coff_symbols + i;
        naux = coff_sym->NumberOfAuxSymbols;

        if (coff_sym->StorageClass == IMAGE_SYM_CLASS_FILE)
	{
            curr_file_idx = coff_add_file(&coff_files, msc_dbg->module, 
                                          (const char*)(coff_sym + 1));
            TRACE("New file %s\n", (const char*)(coff_sym + 1));
            i += naux;
            continue;
	}

        if (curr_file_idx < 0)
        {
            assert(coff_files.nfiles == 0 && coff_files.nfiles_alloc == 0);
            curr_file_idx = coff_add_file(&coff_files, msc_dbg->module, "<none>");
            TRACE("New file <none>\n");
        }

        /*
         * This guy marks the size and location of the text section
         * for the current file.  We need to keep track of this so
         * we can figure out what file the different global functions
         * go with.
         */
        if (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC &&
            naux != 0 && coff_sym->Type == 0 && coff_sym->SectionNumber == 1)
	{
            aux = (const IMAGE_AUX_SYMBOL*) (coff_sym + 1);

            if (coff_files.files[curr_file_idx].linetab_offset != -1)
	    {
                /*
                 * Save this so we can still get the old name.
                 */
                const char* fn;

                fn = source_get(msc_dbg->module,
                                coff_files.files[curr_file_idx].compiland->source);

                TRACE("Duplicating sect from %s: %x %x %x %d %d\n",
                      fn, aux->Section.Length,
                      aux->Section.NumberOfRelocations,
                      aux->Section.NumberOfLinenumbers,
                      aux->Section.Number, aux->Section.Selection);
                TRACE("More sect %d %s %08x %d %d %d\n",
                      coff_sym->SectionNumber,
                      coff_get_name(coff_sym, coff_strtab),
                      coff_sym->Value, coff_sym->Type,
                      coff_sym->StorageClass, coff_sym->NumberOfAuxSymbols);

                /*
                 * Duplicate the file entry.  We have no way to describe
                 * multiple text sections in our current way of handling things.
                 */
                coff_add_file(&coff_files, msc_dbg->module, fn);
	    }
            else
	    {
                TRACE("New text sect from %s: %x %x %x %d %d\n",
                      source_get(msc_dbg->module, coff_files.files[curr_file_idx].compiland->source),
                      aux->Section.Length,
                      aux->Section.NumberOfRelocations,
                      aux->Section.NumberOfLinenumbers,
                      aux->Section.Number, aux->Section.Selection);
	    }

            if (coff_files.files[curr_file_idx].startaddr > coff_sym->Value)
	    {
                coff_files.files[curr_file_idx].startaddr = coff_sym->Value;
	    }

            if (coff_files.files[curr_file_idx].endaddr < coff_sym->Value + aux->Section.Length)
	    {
                coff_files.files[curr_file_idx].endaddr = coff_sym->Value + aux->Section.Length;
	    }

            coff_files.files[curr_file_idx].linetab_offset = linetab_indx;
            coff_files.files[curr_file_idx].linecnt = aux->Section.NumberOfLinenumbers;
            linetab_indx += aux->Section.NumberOfLinenumbers;
            i += naux;
            continue;
	}

        if (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC && naux == 0 && 
            coff_sym->SectionNumber == 1)
	{
            DWORD base = msc_dbg->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
            /*
             * This is a normal static function when naux == 0.
             * Just register it.  The current file is the correct
             * one in this instance.
             */
            nampnt = coff_get_name(coff_sym, coff_strtab);

            TRACE("\tAdding static symbol %s\n", nampnt);

            /* FIXME: was adding symbol to this_file ??? */
            coff_add_symbol(&coff_files.files[curr_file_idx],
                            &symt_new_function(msc_dbg->module, 
                                               coff_files.files[curr_file_idx].compiland, 
                                               nampnt,
                                               msc_dbg->module->module.BaseOfImage + base + coff_sym->Value,
                                               0 /* FIXME */,
                                               NULL /* FIXME */)->symt);
            i += naux;
            continue;
	}

        if (coff_sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL &&
            ISFCN(coff_sym->Type) && coff_sym->SectionNumber > 0)
	{
            struct symt_compiland* compiland = NULL;
            DWORD base = msc_dbg->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
            nampnt = coff_get_name(coff_sym, coff_strtab);

            TRACE("%d: %s %s\n",
                  i, wine_dbgstr_longlong(msc_dbg->module->module.BaseOfImage + base + coff_sym->Value),
                  nampnt);
            TRACE("\tAdding global symbol %s (sect=%s)\n",
                  nampnt, msc_dbg->sectp[coff_sym->SectionNumber - 1].Name);

            /*
             * Now we need to figure out which file this guy belongs to.
             */
            for (j = 0; j < coff_files.nfiles; j++)
	    {
                if (coff_files.files[j].startaddr <= base + coff_sym->Value
                     && coff_files.files[j].endaddr > base + coff_sym->Value)
		{
                    compiland = coff_files.files[j].compiland;
                    break;
		}
	    }
            if (j < coff_files.nfiles)
            {
                coff_add_symbol(&coff_files.files[j],
                                &symt_new_function(msc_dbg->module, compiland, nampnt, 
                                                   msc_dbg->module->module.BaseOfImage + base + coff_sym->Value,
                                                   0 /* FIXME */, NULL /* FIXME */)->symt);
            } 
            else 
            {
                symt_new_function(msc_dbg->module, NULL, nampnt, 
                                  msc_dbg->module->module.BaseOfImage + base + coff_sym->Value,
                                  0 /* FIXME */, NULL /* FIXME */);
            }
            i += naux;
            continue;
	}

        if (coff_sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL &&
            coff_sym->SectionNumber > 0)
	{
            DWORD base = msc_dbg->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
            struct location loc;

            /*
             * Similar to above, but for the case of data symbols.
             * These aren't treated as entrypoints.
             */
            nampnt = coff_get_name(coff_sym, coff_strtab);

            TRACE("%d: %s %s\n",
                  i, wine_dbgstr_longlong(msc_dbg->module->module.BaseOfImage + base + coff_sym->Value),
                  nampnt);
            TRACE("\tAdding global data symbol %s\n", nampnt);

            /*
             * Now we need to figure out which file this guy belongs to.
             */
            loc.kind = loc_absolute;
            loc.reg = 0;
            loc.offset = msc_dbg->module->module.BaseOfImage + base + coff_sym->Value;
            symt_new_global_variable(msc_dbg->module, NULL, nampnt, TRUE /* FIXME */,
                                     loc, 0 /* FIXME */, NULL /* FIXME */);
            i += naux;
            continue;
	}

        if (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC && naux == 0)
	{
            /*
             * Ignore these.  They don't have anything to do with
             * reality.
             */
            i += naux;
            continue;
	}

        TRACE("Skipping unknown entry '%s' %d %d %d\n",
              coff_get_name(coff_sym, coff_strtab),
              coff_sym->StorageClass, coff_sym->SectionNumber, naux);
        
        /*
         * For now, skip past the aux entries.
         */
        i += naux;
    }

    if (coff_files.files != NULL)
    {
        /*
         * OK, we now should have a list of files, and we should have a list
         * of entrypoints.  We need to sort the entrypoints so that we are
         * able to tie the line numbers with the given functions within the
         * file.
         */
        for (j = 0; j < coff_files.nfiles; j++)
        {
            if (coff_files.files[j].entries != NULL)
            {
                qsort(coff_files.files[j].entries, coff_files.files[j].neps,
                      sizeof(struct symt*), symt_cmp_addr);
            }
        }

        /*
         * Now pick apart the line number tables, and attach the entries
         * to the given functions.
         */
        for (j = 0; j < coff_files.nfiles; j++)
        {
            l = 0;
            if (coff_files.files[j].neps != 0)
            {
                for (k = 0; k < coff_files.files[j].linecnt; k++)
                {
                    linepnt = coff_linetab + coff_files.files[j].linetab_offset + k;
                    /*
                     * If we have spilled onto the next entrypoint, then
                     * bump the counter..
                     */
                    for (;;)
                    {
                        if (l+1 >= coff_files.files[j].neps) break;
                        symt_get_address(coff_files.files[j].entries[l+1], &addr);
                        if (((msc_dbg->module->module.BaseOfImage + linepnt->Type.VirtualAddress) < addr))
                            break;
                        l++;
                    }

                    if (coff_files.files[j].entries[l+1]->tag == SymTagFunction)
                    {
                        /*
                         * Add the line number.  This is always relative to the
                         * start of the function, so we need to subtract that offset
                         * first.
                         */
                        symt_get_address(coff_files.files[j].entries[l+1], &addr);
                        symt_add_func_line(msc_dbg->module, (struct symt_function*)coff_files.files[j].entries[l+1], 
                                           coff_files.files[j].compiland->source, linepnt->Linenumber,
                                           msc_dbg->module->module.BaseOfImage + linepnt->Type.VirtualAddress - addr);
                    }
                }
            }
        }

        for (j = 0; j < coff_files.nfiles; j++)
	{
            HeapFree(GetProcessHeap(), 0, coff_files.files[j].entries);
	}
        HeapFree(GetProcessHeap(), 0, coff_files.files);
        msc_dbg->module->module.SymType = SymCoff;
        /* FIXME: we could have a finer grain here */
        msc_dbg->module->module.LineNumbers = TRUE;
        msc_dbg->module->module.GlobalSymbols = TRUE;
        msc_dbg->module->module.TypeInfo = FALSE;
        msc_dbg->module->module.SourceIndexed = TRUE;
        msc_dbg->module->module.Publics = TRUE;
        ret = TRUE;
    }

    return ret;
}
Exemple #8
0
/*
 * Search for the symbol on PE's symbol table.
 *
 * Symbols for which there's no DWARF debugging information might still appear there, put by MinGW linker.
 *
 * - https://msdn.microsoft.com/en-gb/library/ms809762.aspx
 *   - https://www.microsoft.com/msj/backissues86.aspx
 * - http://go.microsoft.com/fwlink/p/?linkid=84140
 */
static BOOL
pe_find_symbol(PBYTE lpFileBase,
               DWORD64 Addr,
               ULONG MaxSymbolNameLen,
               LPSTR pSymbolName,
               PDWORD64 pDisplacement)
{
    PIMAGE_DOS_HEADER pDosHeader;
    PIMAGE_NT_HEADERS pNtHeaders;
    PIMAGE_OPTIONAL_HEADER pOptionalHeader;
    PIMAGE_OPTIONAL_HEADER32 pOptionalHeader32;
    PIMAGE_OPTIONAL_HEADER64 pOptionalHeader64;
    DWORD64 ImageBase = 0;
    BOOL bUnderscore = TRUE;

    pDosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
    pNtHeaders = (PIMAGE_NT_HEADERS)(lpFileBase + pDosHeader->e_lfanew);
    PIMAGE_SECTION_HEADER Sections = (PIMAGE_SECTION_HEADER) (
        (PBYTE)pNtHeaders +
        sizeof(DWORD) +
        sizeof(IMAGE_FILE_HEADER) +
        pNtHeaders->FileHeader.SizeOfOptionalHeader
    );
    PIMAGE_SYMBOL pSymbolTable = (PIMAGE_SYMBOL) (
        lpFileBase +
        pNtHeaders->FileHeader.PointerToSymbolTable
    );
    PSTR pStringTable = (PSTR)
        &pSymbolTable[pNtHeaders->FileHeader.NumberOfSymbols];
    pOptionalHeader = &pNtHeaders->OptionalHeader;
    pOptionalHeader32 = (PIMAGE_OPTIONAL_HEADER32)pOptionalHeader;
    pOptionalHeader64 = (PIMAGE_OPTIONAL_HEADER64)pOptionalHeader;

    switch (pOptionalHeader->Magic) {
    case IMAGE_NT_OPTIONAL_HDR32_MAGIC :
        ImageBase = pOptionalHeader32->ImageBase;
        break;
    case IMAGE_NT_OPTIONAL_HDR64_MAGIC :
        ImageBase = pOptionalHeader64->ImageBase;
        bUnderscore = FALSE;
        break;
    default:
        assert(0);
    }

    DWORD64 Displacement = ~(DWORD64)0;
    BOOL bRet = FALSE;

    DWORD i;
    for (i = 0; i < pNtHeaders->FileHeader.NumberOfSymbols; ++i) {
        PIMAGE_SYMBOL pSymbol = &pSymbolTable[i];

        DWORD64 SymbolAddr = pSymbol->Value;
        SHORT SectionNumber = pSymbol->SectionNumber;
        if (SectionNumber > 0) {
            PIMAGE_SECTION_HEADER pSection = Sections + SectionNumber - 1;
            SymbolAddr += ImageBase + pSection->VirtualAddress;
        }

        LPCSTR SymbolName;
        char ShortName[9];
        if (pSymbol->N.Name.Short != 0) {
            strncpy(ShortName, (LPCSTR)pSymbol->N.ShortName, 8);
            ShortName[8] = '\0';
            SymbolName = ShortName;
        } else {
            SymbolName = &pStringTable[pSymbol->N.Name.Long];
        }

        if (bUnderscore && SymbolName[0] == '_') {
            SymbolName = &SymbolName[1];
        }

        if (0) {
            OutputDebug("%04lu: 0x%08I64X %s\n", i, SymbolAddr, SymbolName);
        }

        if (SymbolAddr <= Addr &&
            ISFCN(pSymbol->Type) &&
            SymbolName[0] != '.') {
            DWORD64 SymbolDisp = Addr - SymbolAddr;
            if (SymbolDisp < Displacement) {
                strncpy(pSymbolName, SymbolName, MaxSymbolNameLen);

                bRet = TRUE;

                Displacement = SymbolDisp;

                if (Displacement == 0) {
                    break;
                }
            }
        }

        i += pSymbol->NumberOfAuxSymbols;
    }

    if (pDisplacement) {
        *pDisplacement = Displacement;
    }

    return bRet;
}