134 lines
3.6 KiB
C
134 lines
3.6 KiB
C
#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);
|
|
}
|
|
}
|