Add stackdump and fix socktest for mipsel

This commit is contained in:
Lucas Schumacher 2025-05-04 20:22:54 -04:00
parent cc557ed1b9
commit f7109b8743
3 changed files with 156 additions and 3 deletions

View File

@ -11,7 +11,7 @@ X86_64_CFLAGS := --target=x86_64-linux-gnu
AARCH64_CFLAGS := --target=aarch64-linux-gnu AARCH64_CFLAGS := --target=aarch64-linux-gnu
all: buildtest socktest all: buildtest socktest stackdump
clean: clean:
rm $(bindir)/* rm $(bindir)/*
@ -22,9 +22,10 @@ $(bindir)/:
headers := sys.h int.h headers := sys.h int.h
buildtest: $(bindir)/bldtst $(bindir)/bldtst_llvm $(bindir)/bldtst_x64 $(bindir)/bldtst_aarch64 $(bindir)/bldtst_mips $(bindir)/bldtst_mipsel buildtest: $(bindir)/bldtst $(bindir)/bldtst_llvm $(bindir)/bldtst_x64 $(bindir)/bldtst_aarch64 $(bindir)/bldtst_mips $(bindir)/bldtst_mipsel
socktest: $(bindir)/socktest $(bindir)/socktest_llvm $(bindir)/socktest_x64 $(bindir)/socktest_aarch64 $(bindir)/socktest_mips $(bindir)/socktest_mipsel socktest: $(bindir)/socktest $(bindir)/socktest_llvm $(bindir)/socktest_x64 $(bindir)/socktest_aarch64 $(bindir)/socktest_mips $(bindir)/socktest_mipsel
stackdump: $(bindir)/stackdump $(bindir)/stackdump_llvm $(bindir)/stackdump_x64 $(bindir)/stackdump_aarch64 $(bindir)/stackdump_mips $(bindir)/stackdump_mipsel
.PHONY: all clean buildtest socktest .PHONY: all clean buildtest socktest stackdump
${bindir}/bldtst: buildtest.c $(headers) arch/* | $(bindir)/ ${bindir}/bldtst: buildtest.c $(headers) arch/* | $(bindir)/
@ -63,3 +64,22 @@ ${bindir}/socktest_mips: $(headers) socktest.c arch/mips.c arch/generic.h | $(bi
${bindir}/socktest_mipsel: $(headers) socktest.c arch/mips.c arch/generic.h | $(bindir)/ ${bindir}/socktest_mipsel: $(headers) socktest.c arch/mips.c arch/generic.h | $(bindir)/
clang $(MIPSEL_CFLAGS) $(CFLAGS) $(CLANG_WNO) -o $@ socktest.c arch/mips.c clang $(MIPSEL_CFLAGS) $(CFLAGS) $(CLANG_WNO) -o $@ socktest.c arch/mips.c
${bindir}/stackdump: stackdump.c $(headers) arch/* | $(bindir)/
gcc -D _START_DEFINED $(CFLAGS) $(GCC_WNO) -o $@ stackdump.c arch/*.c
${bindir}/stackdump_llvm: $(headers) stackdump.c arch/* | $(bindir)/
clang -D _START_DEFINED $(CFLAGS) $(CLANG_WNO) -o $@ stackdump.c arch/*.c
${bindir}/stackdump_x64: $(headers) stackdump.c arch/x86_64.c arch/generic.h | $(bindir)/
clang -D _START_DEFINED $(X86_64_CFLAGS) $(CFLAGS) $(CLANG_WNO) -o $@ stackdump.c arch/x86_64.c
${bindir}/stackdump_aarch64: $(headers) stackdump.c arch/aarch64.c arch/generic.h | $(bindir)/
clang -D _START_DEFINED $(AARCH64_CFLAGS) $(CFLAGS) $(CLANG_WNO) -o $@ stackdump.c arch/aarch64.c
${bindir}/stackdump_mips: $(headers) stackdump.c arch/mips.c arch/generic.h | $(bindir)/
clang -D _START_DEFINED $(MIPS_CFLAGS) $(CFLAGS) $(CLANG_WNO) -o $@ stackdump.c arch/mips.c
${bindir}/stackdump_mipsel: $(headers) stackdump.c arch/mips.c arch/generic.h | $(bindir)/
clang -D _START_DEFINED $(MIPSEL_CFLAGS) $(CFLAGS) $(CLANG_WNO) -o $@ stackdump.c arch/mips.c

View File

@ -9,7 +9,7 @@ int main() {
server.sin_family = AF_INET; server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY; server.sin_addr.s_addr = INADDR_ANY;
#if defined(__mips__) #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
server.sin_port = 6969; server.sin_port = 6969;
#else #else
server.sin_port = 0x391b; server.sin_port = 0x391b;

133
stackdump.c Normal file
View File

@ -0,0 +1,133 @@
#include "sys.h"
#include "int.h"
/*
Line format: "AAAAAAAAAAAAAAAA BBBB BBBB BBBB BBBB CCCCCCCC\n"
16: hex ptr
2: space
4: 2 hex bytes data
1: space
4: 2 hex bytes data
1: space
4: 2 hex bytes data
1: space
4: 2 hex bytes data
2: space
8: 8 char bytes data
1: new line
---
48: total bytes
# s0: original sp
# s1: buffer start pointer
# s2: line counter
# s3: current data being printed (both addr and *addr)
# s4: nibble/byte offset
# s5: current nibble (both binary and ascii hex)
# s6: current buffer position pointer
*/
#if defined(__x86_64__) || defined(__aarch64__)
#define WRD_LEN 64
typedef uint64_t word_t;
#define SIZEOF_WORD_T 8
#define LEN 48
#elif defined(__mips__)
#define WRD_LEN 32
typedef uint32_t word_t;
#define SIZEOF_WORD_T 4
#define LEN 26
#endif
#define NIBBLE_LEN 4
#define CHAR_LEN 8
//uint64_t* sp; // Original sp
char* sp; // Original sp
char* fp; // frame pointer
char buff[LEN]; // buffer pointer
int line; // line counter
word_t data; // Current data
int offset; // nibble/char offset
int nibble; // current nibble/char
char* pos; // buffer position
// Compile with -D _START_DEFINED
#if defined(__mips__)
void __start() {
#else
void _start() {
#endif /* ifndef defined(__mips__) */
// Save stack pointer
#if defined(__x86_64__)
asm volatile("mov %%rsp, %0\n" : "=r"(sp));
#elif defined(__mips__)
asm volatile("move %0, $sp\n" : "=r"(sp));
#elif defined(__aarch64__)
asm volatile("mov %0, sp\n" : "=r"(sp));
#else
#error arch not supported
#endif
fp = __builtin_frame_address(0);
//fp = __builtin_return_address(0);
//if(fp != sp) exit(sp - fp);
// Clear buffer with spaces and newline
for(pos=buff; pos < buff+LEN-1; ++pos) *pos = ' ';
buff[LEN-1] = '\n';
// Add some vars to see how ith changes the stack
// volatile word_t padd = 0x11;
// volatile word_t padd2 = 0x12;
// Loop until segfault
for(line = 0;;line += 1) {
// Load address of next word into data
data = (word_t)((line*SIZEOF_WORD_T) + sp);
if(fp == (char*)data) write(STDOUT, "FP\n", 3);
// reset buffer position
pos = buff;
// print addr in hex //
for(offset=WRD_LEN-NIBBLE_LEN; offset >= 0; offset -= NIBBLE_LEN) {
nibble = (data >> offset) & 0x0f; // store current nibble in nibble
// convert nibble to hex
nibble = nibble + '0';
if(nibble > '9') nibble = nibble + 7;
// write hex char to buffer
*pos = nibble;
pos += 1;
}
// Print data as hex //
pos += 2; // Add 2 padded spaces
data = *(word_t*)data; // Load data into data
for(offset=WRD_LEN-NIBBLE_LEN; offset>=0; offset -= NIBBLE_LEN) {
nibble = (data >> offset) & 0x0f; // Store current nibble in nibble
// Convert nibble to hex char
nibble = nibble + '0';
if(nibble > '9') nibble = nibble + 7;
// Write hex char to buffer
*pos = nibble;
pos += 1;
// Add space every 2 bytes (4 nibbles)
if((offset % 16) == 0) pos += 1;
}
pos += 1;
// Print data as char //
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
for(offset = WRD_LEN - CHAR_LEN; offset >= 0; offset -= CHAR_LEN) {
#else
for(offset = 0; offset < WRD_LEN; offset += CHAR_LEN) {
#endif /* ifndef defined(__mips__) */
nibble = (data >> offset) & 0xff; // Store current char in nibble
if((nibble < ' ') || (nibble > '~')) *pos = '~'; // Use placeholder for non printable chars
else *pos = nibble; // Write printable char
pos += 1;
}
// Write to STDOUT //
write(STDOUT, buff, LEN);
fsync(STDOUT);
}
}