Skip to content

Commit ac7bc96

Browse files
pawel-kupczaklgaver2
authored andcommitted
gdb: refactor amd64_analyze_prologue
Refactor amd64_analyze_prologue so it clearly reflects what is the order of operations in the prologue that we expect to encounter, as is the case for i386's implementation. Approved-By: Andrew Burgess <[email protected]>
1 parent 9acfa04 commit ac7bc96

File tree

1 file changed

+75
-51
lines changed

1 file changed

+75
-51
lines changed

gdb/amd64-tdep.c

Lines changed: 75 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2129,6 +2129,30 @@ amd64_alloc_frame_cache (void)
21292129
return cache;
21302130
}
21312131

2132+
/* Check whether PC is at "endbr64" instruction. If so, return PC past it.
2133+
Otherwise, return PC passed to this function. */
2134+
2135+
static CORE_ADDR
2136+
amd64_skip_endbr (gdbarch *gdbarch, CORE_ADDR pc)
2137+
{
2138+
static const gdb_byte endbr64[4] = { 0xf3, 0x0f, 0x1e, 0xfa };
2139+
2140+
bfd_endian byte_order = gdbarch_byte_order (gdbarch);
2141+
gdb_byte buf[3];
2142+
gdb_byte op = read_code_unsigned_integer (pc, 1, byte_order);
2143+
2144+
/* Check for the `endbr64` instruction, skip it if found. */
2145+
if (op == endbr64[0])
2146+
{
2147+
read_code (pc + 1, buf, 3);
2148+
2149+
if (memcmp (buf, &endbr64[1], 3) == 0)
2150+
return pc + 4;
2151+
}
2152+
2153+
return pc;
2154+
}
2155+
21322156
/* GCC 4.4 and later, can put code in the prologue to realign the
21332157
stack pointer. Check whether PC points to such code, and update
21342158
CACHE accordingly. Return the first instruction after the code
@@ -2466,70 +2490,30 @@ amd64_x32_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc,
24662490
return std::min (pc + offset + 2, current_pc);
24672491
}
24682492

2469-
/* Do a limited analysis of the prologue at PC and update CACHE
2470-
accordingly. Bail out early if CURRENT_PC is reached. Return the
2471-
address where the analysis stopped.
2472-
2473-
We will handle only functions beginning with:
2474-
2475-
pushq %rbp 0x55
2476-
movq %rsp, %rbp 0x48 0x89 0xe5 (or 0x48 0x8b 0xec)
2477-
2478-
or (for the X32 ABI):
2479-
2480-
pushq %rbp 0x55
2481-
movl %esp, %ebp 0x89 0xe5 (or 0x8b 0xec)
2482-
2483-
The `endbr64` instruction can be found before these sequences, and will be
2484-
skipped if found.
2493+
/* Analyze frame setup instructions at PC on behalf of amd64_analyze_prologue
2494+
and update CACHE accordingly. Bail out early if CURRENT_PC is reached.
2495+
Return the address where the analysis stopped.
24852496
2486-
Any function that doesn't start with one of these sequences will be
2487-
assumed to have no prologue and thus no valid frame pointer in
2488-
%rbp. */
2497+
See comment on amd64_analyze_prologue for the sequences handled. The
2498+
movq/movl after the push of %rbp is considered optional. 'endbr64' is
2499+
handled before this function. */
24892500

24902501
static CORE_ADDR
2491-
amd64_analyze_prologue (struct gdbarch *gdbarch,
2492-
CORE_ADDR pc, CORE_ADDR current_pc,
2493-
struct amd64_frame_cache *cache)
2502+
amd64_analyze_frame_setup (gdbarch *gdbarch, CORE_ADDR pc,
2503+
CORE_ADDR current_pc, amd64_frame_cache *cache)
24942504
{
2495-
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
2496-
/* The `endbr64` instruction. */
2497-
static const gdb_byte endbr64[4] = { 0xf3, 0x0f, 0x1e, 0xfa };
24982505
/* There are two variations of movq %rsp, %rbp. */
24992506
static const gdb_byte mov_rsp_rbp_1[3] = { 0x48, 0x89, 0xe5 };
25002507
static const gdb_byte mov_rsp_rbp_2[3] = { 0x48, 0x8b, 0xec };
25012508
/* Ditto for movl %esp, %ebp. */
25022509
static const gdb_byte mov_esp_ebp_1[2] = { 0x89, 0xe5 };
25032510
static const gdb_byte mov_esp_ebp_2[2] = { 0x8b, 0xec };
25042511

2512+
bfd_endian byte_order = gdbarch_byte_order (gdbarch);
25052513
gdb_byte buf[3];
2506-
gdb_byte op;
2507-
2508-
if (current_pc <= pc)
2509-
return current_pc;
2510-
2511-
if (gdbarch_ptr_bit (gdbarch) == 32)
2512-
pc = amd64_x32_analyze_stack_align (pc, current_pc, cache);
2513-
else
2514-
pc = amd64_analyze_stack_align (pc, current_pc, cache);
2515-
2516-
op = read_code_unsigned_integer (pc, 1, byte_order);
2514+
gdb_byte op = read_code_unsigned_integer (pc, 1, byte_order);
25172515

2518-
/* Check for the `endbr64` instruction, skip it if found. */
2519-
if (op == endbr64[0])
2520-
{
2521-
read_code (pc + 1, buf, 3);
2522-
2523-
if (memcmp (buf, &endbr64[1], 3) == 0)
2524-
pc += 4;
2525-
2526-
op = read_code_unsigned_integer (pc, 1, byte_order);
2527-
}
2528-
2529-
if (current_pc <= pc)
2530-
return current_pc;
2531-
2532-
if (op == 0x55) /* pushq %rbp */
2516+
if (op == 0x55) /* pushq %rbp. */
25332517
{
25342518
/* Take into account that we've executed the `pushq %rbp' that
25352519
starts this instruction sequence. */
@@ -2569,6 +2553,46 @@ amd64_analyze_prologue (struct gdbarch *gdbarch,
25692553
return pc;
25702554
}
25712555

2556+
/* Do a limited analysis of the prologue at PC and update CACHE
2557+
accordingly. Bail out early if CURRENT_PC is reached. Return the
2558+
address where the analysis stopped.
2559+
2560+
We will handle only functions beginning with:
2561+
2562+
pushq %rbp 0x55
2563+
movq %rsp, %rbp 0x48 0x89 0xe5 (or 0x48 0x8b 0xec)
2564+
2565+
or (for the X32 ABI):
2566+
2567+
pushq %rbp 0x55
2568+
movl %esp, %ebp 0x89 0xe5 (or 0x8b 0xec)
2569+
2570+
The `endbr64` instruction can be found before these sequences, and will be
2571+
skipped if found.
2572+
2573+
Any function that doesn't start with one of these sequences will be
2574+
assumed to have no prologue and thus no valid frame pointer in
2575+
%rbp. */
2576+
2577+
static CORE_ADDR
2578+
amd64_analyze_prologue (gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR current_pc,
2579+
amd64_frame_cache *cache)
2580+
{
2581+
if (current_pc <= pc)
2582+
return current_pc;
2583+
2584+
if (gdbarch_ptr_bit (gdbarch) == 32)
2585+
pc = amd64_x32_analyze_stack_align (pc, current_pc, cache);
2586+
else
2587+
pc = amd64_analyze_stack_align (pc, current_pc, cache);
2588+
2589+
pc = amd64_skip_endbr (gdbarch, pc);
2590+
if (current_pc <= pc)
2591+
return current_pc;
2592+
2593+
return amd64_analyze_frame_setup (gdbarch, pc, current_pc, cache);
2594+
}
2595+
25722596
/* Work around false termination of prologue - GCC PR debug/48827.
25732597
25742598
START_PC is the first instruction of a function, PC is its minimal already

0 commit comments

Comments
 (0)