From 7ceacbf8ad6dd559184df0314063c58fc41bd5c8 Mon Sep 17 00:00:00 2001 From: Hannes Domani Date: Fri, 15 Apr 2022 20:38:03 +0200 Subject: [PATCH] PDB: skip jump thunks --- gdb/amd64-windows-tdep.c | 15 ++++++++++++++- gdb/windows-nat.c | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c index 3c86ec63319..2b12095fb9d 100644 --- a/gdb/amd64-windows-tdep.c +++ b/gdb/amd64-windows-tdep.c @@ -1237,7 +1237,8 @@ amd64_windows_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* Check for jmp *(%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 @@ -1260,6 +1261,18 @@ amd64_windows_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) = 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; } diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index 853644a3e48..d18a2f160f3 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -72,6 +72,7 @@ #include "nat/windows-nat.h" #include "gdbsupport/symbol.h" #include "buildsym.h" +#include "block.h" using namespace windows_nat; @@ -3289,6 +3290,9 @@ typedef BOOL WINAPI (SymGetTypeInfo_ftype) (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 { @@ -3351,7 +3355,7 @@ enum DataKind struct pdb_line_info { - //minimal_symbol_reader *reader; + minimal_symbol_reader *reader; buildsym_compunit *builder; pending **local_symbols; objfile *objfile; @@ -3362,6 +3366,7 @@ struct pdb_line_info DWORD64 addr; DWORD64 max_addr; std::vector cache; + std::vector functions; }; @@ -3632,6 +3637,7 @@ static BOOL CALLBACK symbol_callback(PSYMBOL_INFO si, 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); @@ -3654,11 +3660,14 @@ static BOOL CALLBACK symbol_callback(PSYMBOL_INFO si, 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) @@ -3682,6 +3691,21 @@ static BOOL CALLBACK symbol_callback(PSYMBOL_INFO si, 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; } @@ -3733,10 +3757,12 @@ pdb_load_functions (const char *name, minimal_symbol_reader *reader, 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; @@ -3747,7 +3773,7 @@ pdb_load_functions (const char *name, minimal_symbol_reader *reader, 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; @@ -3760,6 +3786,9 @@ pdb_load_functions (const char *name, minimal_symbol_reader *reader, 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)); -- 2.47.2