From f7109b8743adef9e097dbca7689ec31f5a17e66e Mon Sep 17 00:00:00 2001 From: Lucas Schumacher Date: Sun, 4 May 2025 20:22:54 -0400 Subject: [PATCH] Add stackdump and fix socktest for mipsel --- Makefile | 24 +++++++++- socktest.c | 2 +- stackdump.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+), 3 deletions(-) create mode 100644 stackdump.c diff --git a/Makefile b/Makefile index 678e0d6..5562f78 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ X86_64_CFLAGS := --target=x86_64-linux-gnu AARCH64_CFLAGS := --target=aarch64-linux-gnu -all: buildtest socktest +all: buildtest socktest stackdump clean: rm $(bindir)/* @@ -22,9 +22,10 @@ $(bindir)/: headers := sys.h int.h 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 +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)/ @@ -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)/ 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 diff --git a/socktest.c b/socktest.c index 6beadbe..fc3f9a8 100644 --- a/socktest.c +++ b/socktest.c @@ -9,7 +9,7 @@ int main() { server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; - #if defined(__mips__) + #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ server.sin_port = 6969; #else server.sin_port = 0x391b; diff --git a/stackdump.c b/stackdump.c new file mode 100644 index 0000000..253bd7d --- /dev/null +++ b/stackdump.c @@ -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); + } +}