Skip to content

Commit 4206724

Browse files
committed
Demonstrate stack walker to find current position in frame
With top-of-stack pointer
1 parent 80560a3 commit 4206724

File tree

3 files changed

+62
-2
lines changed

3 files changed

+62
-2
lines changed

asm/Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ librot13.so: rot13.s
2727
libroman.so: roman.s
2828
$(CC) -g -shared -o $@ $<
2929

30-
test_walk_stack: walk_stack.S test_walk_stack.c
31-
$(CC) -g -o $@ test_walk_stack.c walk_stack.S
30+
31+
test_stack_walk: stack_walk.s test_stack_walk.c
32+
$(CC) -g -fno-omit-frame-pointer -o $@ stack_walk.s test_stack_walk.c
3233

3334
clean:
3435
rm -f $(OBJECTS) *.so *.o

asm/stack_walk.s

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
.intel_syntax noprefix
2+
.text
3+
.globl stack_find_return_address_in_frame_posix
4+
.globl _stack_find_return_address_in_frame_posix
5+
stack_find_return_address_in_frame_posix:
6+
_stack_find_return_address_in_frame_posix:
7+
mov rcx, rdi /* arg0 = start-of-code region */
8+
mov r8, rdx /* arg2 = stack base-pointer */
9+
mov rdx, rsi /* arg1 = size-of-code */
10+
_stack_find_return_address_in_frame_win64:
11+
push rbp
12+
mov r9, rsp
13+
add rdx, rcx /* compute end-of-code region */
14+
/* rcx = start, rdx = end, r8 = stack base */
15+
loop:
16+
cmp r8, r9 /* have we gone past our start-of-stack pointer? */
17+
jle done /* stack grows downwards */
18+
mov rax, qword ptr [r9+0x8]
19+
mov r9, qword ptr [r9]
20+
cmp rax, rcx
21+
jl loop
22+
cmp rax, rdx
23+
jg loop
24+
done:
25+
/* rax is now within range by definition, or, we're to deep */
26+
pop rbp
27+
ret

asm/test_stack_walk.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <inttypes.h>
4+
5+
void * stack_find_return_address_in_frame_posix(void *base, int size, void *top);
6+
void bar(int *);
7+
int main(int, char**);
8+
9+
void quix(int *a) {
10+
void *pos = stack_find_return_address_in_frame_posix(&bar, 200, a);
11+
void *mnl = stack_find_return_address_in_frame_posix(&main, 200, a);
12+
int ofs = (char*)pos - (char*)bar;
13+
fprintf(stderr, "pos=%"PRIx64", ofs=%d\n", pos, ofs);
14+
fprintf(stderr, "mnl=%"PRIx64", ofs=%d\n", mnl, (char*)mnl - (char*)main);
15+
}
16+
17+
18+
void bar(int *a) {
19+
fprintf(stderr, "Hello, world\n");
20+
quix(a);
21+
fprintf(stderr, "Goodbye!\n");
22+
}
23+
24+
void foo(void) {
25+
int a = 1;
26+
bar(&a);
27+
}
28+
29+
int main(int argc, char **argv) {
30+
foo();
31+
return 0;
32+
}

0 commit comments

Comments
 (0)