Skip to content

Commit dcd9d81

Browse files
committed
Read thunk symbols from PDB debug info
1 parent 49dc7b2 commit dcd9d81

3 files changed

Lines changed: 66 additions & 4 deletions

File tree

gdb/amd64-windows-tdep.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,7 +1245,8 @@ amd64_windows_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
12451245
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
12461246

12471247
/* Check for jmp *<offset>(%rip) (jump near, absolute indirect (/4)). */
1248-
if (pc && read_memory_unsigned_integer (pc, 2, byte_order) == 0x25ff)
1248+
unsigned instr = pc ? read_memory_unsigned_integer (pc, 2, byte_order) : 0;
1249+
if (instr == 0x25ff)
12491250
{
12501251
/* Get opcode offset and see if we can find a reference in our data. */
12511252
ULONGEST offset
@@ -1264,8 +1265,26 @@ amd64_windows_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
12641265
{
12651266
if (startswith (symname, "__imp_")
12661267
|| startswith (symname, "_imp_"))
1267-
destination
1268-
= read_memory_unsigned_integer (indirect_addr, 8, byte_order);
1268+
{
1269+
destination
1270+
= read_memory_unsigned_integer (indirect_addr, 8, byte_order);
1271+
1272+
pc = destination;
1273+
instr = pc ? read_memory_unsigned_integer (pc, 2, byte_order) : 0;
1274+
}
1275+
}
1276+
}
1277+
1278+
if ((instr & 0xff) == 0xe9)
1279+
{
1280+
struct minimal_symbol *sym = lookup_minimal_symbol_by_pc (pc).minsym;
1281+
const char *symname = sym ? sym->linkage_name () : NULL;
1282+
1283+
if (symname && startswith (symname, "__thunk_"))
1284+
{
1285+
ULONGEST offset
1286+
= read_memory_unsigned_integer (pc + 1, 4, byte_order);
1287+
destination = pc + offset + 5;
12691288
}
12701289
}
12711290

gdb/i386-windows-tdep.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,29 @@ static int i386_windows_gregset_reg_offset[] =
9393
static CORE_ADDR
9494
i386_windows_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
9595
{
96-
return i386_pe_skip_trampoline_code (frame, pc, NULL);
96+
CORE_ADDR addr = i386_pe_skip_trampoline_code (frame, pc, NULL);
97+
if (addr != 0)
98+
pc = addr;
99+
if (pc != 0)
100+
{
101+
struct gdbarch *gdbarch = get_frame_arch (frame);
102+
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
103+
104+
if (read_memory_unsigned_integer (pc, 1, byte_order) == 0xe9)
105+
{
106+
struct minimal_symbol *sym = lookup_minimal_symbol_by_pc (pc).minsym;
107+
const char *symname = sym ? sym->linkage_name () : NULL;
108+
109+
if (symname && (startswith (symname, "__thunk_")
110+
|| startswith (symname, "_thunk_")))
111+
{
112+
ULONGEST offset
113+
= read_memory_unsigned_integer (pc + 1, 4, byte_order);
114+
return pc + offset + 5;
115+
}
116+
}
117+
}
118+
return addr;
97119
}
98120

99121
static const char *

gdb/windows-nat.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4321,6 +4321,27 @@ static BOOL CALLBACK symbol_callback (PSYMBOL_INFO si,
43214321

43224322
pli->functions.push_back (sym);
43234323
}
4324+
else if (si->Tag == SymTagThunk)
4325+
{
4326+
if (si->Flags & SYMFLAG_THUNK)
4327+
{
4328+
ULONGEST val = si->Value + base_ofs;
4329+
4330+
for (symbol *sym : pli->functions)
4331+
{
4332+
if (sym->value_block ()->start () == val)
4333+
{
4334+
std::string imp_name
4335+
= string_printf ("__thunk_%s", sym->linkage_name ());
4336+
struct minimal_symbol *msym = pli->reader->record_full
4337+
(imp_name.c_str (), true, unrelocated_addr (si->Address),
4338+
mst_data, 0);
4339+
if (msym)
4340+
msym->set_size (si->Size);
4341+
}
4342+
}
4343+
}
4344+
}
43244345
else if (si->Tag == SymTagPublicSymbol)
43254346
{
43264347
struct minimal_symbol *msym = pli->reader->record_full

0 commit comments

Comments
 (0)