enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
/* Check for jmp *<offset>(%rip) (jump near, absolute indirect (/4)). */
- if (pc && read_memory_unsigned_integer (pc, 2, byte_order) == 0x25ff)
+ unsigned instr = pc ? read_memory_unsigned_integer (pc, 2, byte_order) : 0;
+ if (instr == 0x25ff)
{
/* Get opcode offset and see if we can find a reference in our data. */
ULONGEST offset
= read_memory_unsigned_integer (indirect_addr, 8, byte_order);
}
}
+ else if ((instr & 0xff) == 0xe9)
+ {
+ struct minimal_symbol *sym = lookup_minimal_symbol_by_pc (pc).minsym;
+ const char *symname = sym ? sym->linkage_name () : NULL;
+
+ if (symname && startswith (symname, "__thunk_"))
+ {
+ ULONGEST offset
+ = read_memory_unsigned_integer (pc + 1, 4, byte_order);
+ destination = pc + offset + 5;
+ }
+ }
return destination;
}
#include "nat/windows-nat.h"
#include "gdbsupport/symbol.h"
#include "buildsym.h"
+#include "block.h"
using namespace windows_nat;
(HANDLE, DWORD64, ULONG, IMAGEHLP_SYMBOL_TYPE_INFO, PVOID);
typedef BOOL WINAPI (SymSetContext_ftype)
(HANDLE, PIMAGEHLP_STACK_FRAME, PIMAGEHLP_CONTEXT);
+typedef BOOL WINAPI (SymSearch_ftype)
+ (HANDLE, ULONG64, DWORD, DWORD, PCSTR, DWORD64,
+ PSYM_ENUMERATESYMBOLS_CALLBACK, PVOID, DWORD);
enum SymTagEnum
{
struct pdb_line_info
{
- //minimal_symbol_reader *reader;
+ minimal_symbol_reader *reader;
buildsym_compunit *builder;
pending **local_symbols;
objfile *objfile;
DWORD64 addr;
DWORD64 max_addr;
std::vector<type *> cache;
+ std::vector<symbol *> functions;
};
context_stack *newobj = pli->builder->push_context (0, si->Address);
symbol *sym = new (&objfile->objfile_obstack) symbol;
sym->set_linkage_name (objfile->intern (si->Name));
+ sym->set_language (language_c, &objfile->objfile_obstack);
sym->set_domain (VAR_DOMAIN);
//type *ret_type = objfile_type (objfile)->builtin_void;
//type *ftype = lookup_function_type (ret_type);
pli->builder->finish_block (cstk.name, cstk.old_blocks, cstk.static_link,
si->Address, si->Address + si->Size);
gdbarch_make_symbol_special (objfile->arch (), cstk.name, objfile);
+
+ pli->functions.push_back (sym);
}
else if (si->Tag == SymTagData)
{
symbol *sym = new (&objfile->objfile_obstack) symbol;
sym->set_linkage_name (objfile->intern (si->Name));
+ sym->set_language (language_c, &objfile->objfile_obstack);
sym->set_domain (VAR_DOMAIN);
sym->set_type (get_pdb_type (pli, si->TypeIndex));
if (si->Flags & SYMFLAG_REGREL)
else
add_symbol_to_list (sym, pli->builder->get_global_symbols ());
}
+ else if (si->Tag == SymTagThunk)
+ {
+ for (symbol *sym : pli->functions)
+ {
+ if (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) == si->Value)
+ {
+ std::string imp_name
+ = string_printf ("__thunk_%s", sym->linkage_name ());
+ struct minimal_symbol *msym = pli->reader->record_full
+ (imp_name.c_str (), true, si->Address, mst_data, 0);
+ if (msym)
+ SET_MSYMBOL_SIZE (msym, si->Size);
+ }
+ }
+ }
return TRUE;
}
GetProcAddress (dh, "SymGetTypeInfo");
SymSetContext_ftype *fSymSetContext = (SymSetContext_ftype *)
GetProcAddress (dh, "SymSetContext");
+ SymSearch_ftype *fSymSearch = (SymSearch_ftype *)
+ GetProcAddress (dh, "SymSearch");
if (fSymInitialize != NULL && fSymCleanup != NULL
&& fSymEnumSymbols != NULL && fSymLoadModule64 != NULL
&& fSymEnumSourceLines != NULL && fSymGetTypeInfo != NULL
- && fSymSetContext != NULL)
+ && fSymSetContext != NULL && fSymSearch != NULL)
{
HANDLE p = (void *) 1;
builder.reset (new buildsym_compunit
(objfile, name, NULL, language_c, addr));
pdb_line_info pli;
- //pli.reader = reader;
+ pli.reader = reader;
pli.builder = builder.get ();
pli.local_symbols = nullptr;
pli.objfile = objfile;
fSymEnumSymbols(p, addr, NULL, symbol_callback, &pli);
+ fSymSearch (p, addr, 0, SymTagThunk, NULL, 0, symbol_callback, &pli,
+ SYMSEARCH_RECURSE);
+
fSymEnumSourceLines(p, addr, NULL, NULL, 0, 0, line_callback, &pli);
builder->end_symtab (pli.max_addr, SECT_OFF_TEXT (objfile));