#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); } }