You've already forked Microtransactions64
mirror of
https://github.com/Print-and-Panic/Microtransactions64.git
synced 2026-01-21 10:17:19 -08:00
Merge pull request #59 from someone2639/master
Crash Screen: Report Name of Crashed Function + Stacktrace
This commit is contained in:
15
Makefile
15
Makefile
@@ -108,6 +108,8 @@ else ifeq ($(VERSION),sh)
|
||||
GRUCODE ?= f3dzex
|
||||
endif
|
||||
|
||||
DEBUG_MAP_STACKTRACE_FLAG := -D DEBUG_MAP_STACKTRACE
|
||||
|
||||
TARGET := sm64.$(VERSION)
|
||||
|
||||
|
||||
@@ -575,7 +577,7 @@ $(BUILD_DIR)/src/usb/usb.o: CFLAGS += -Wno-unused-variable -Wno-sign-compare -Wn
|
||||
$(BUILD_DIR)/src/usb/debug.o: OPT_FLAGS := -O0
|
||||
$(BUILD_DIR)/src/usb/debug.o: CFLAGS += -Wno-unused-parameter -Wno-maybe-uninitialized
|
||||
|
||||
ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) $(GODDARD_SRC_DIRS) $(LIBZ_SRC_DIRS) $(ULTRA_BIN_DIRS) $(BIN_DIRS) $(TEXTURE_DIRS) $(TEXT_DIRS) $(SOUND_SAMPLE_DIRS) $(addprefix levels/,$(LEVEL_DIRS)) rsp include) $(YAY0_DIR) $(addprefix $(YAY0_DIR)/,$(VERSION)) $(SOUND_BIN_DIR) $(SOUND_BIN_DIR)/sequences/$(VERSION)
|
||||
ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) asm/debug $(GODDARD_SRC_DIRS) $(LIBZ_SRC_DIRS) $(ULTRA_BIN_DIRS) $(BIN_DIRS) $(TEXTURE_DIRS) $(TEXT_DIRS) $(SOUND_SAMPLE_DIRS) $(addprefix levels/,$(LEVEL_DIRS)) rsp include) $(YAY0_DIR) $(addprefix $(YAY0_DIR)/,$(VERSION)) $(SOUND_BIN_DIR) $(SOUND_BIN_DIR)/sequences/$(VERSION)
|
||||
|
||||
# Make sure build directory exists before compiling anything
|
||||
DUMMY != mkdir -p $(ALL_DIRS)
|
||||
@@ -766,7 +768,7 @@ $(BUILD_DIR)/rsp/%.bin $(BUILD_DIR)/rsp/%_data.bin: rsp/%.s
|
||||
# Run linker script through the C preprocessor
|
||||
$(BUILD_DIR)/$(LD_SCRIPT): $(LD_SCRIPT) $(BUILD_DIR)/goddard.txt
|
||||
$(call print,Preprocessing linker script:,$<,$@)
|
||||
$(V)$(CPP) $(CPPFLAGS) -DBUILD_DIR=$(BUILD_DIR) -MMD -MP -MT $@ -MF $@.d -o $@ $<
|
||||
$(V)$(CPP) $(CPPFLAGS) -DBUILD_DIR=$(BUILD_DIR) $(DEBUG_MAP_STACKTRACE_FLAG) -MMD -MP -MT $@ -MF $@.d -o $@ $<
|
||||
|
||||
# Link libgoddard
|
||||
$(BUILD_DIR)/libgoddard.a: $(GODDARD_O_FILES)
|
||||
@@ -791,10 +793,15 @@ $(BUILD_DIR)/goddard.txt: $(BUILD_DIR)/sm64_prelim.elf
|
||||
$(call print,Getting Goddard size...)
|
||||
$(V)python3 tools/getGoddardSize.py $(BUILD_DIR)/sm64_prelim.map $(VERSION)
|
||||
|
||||
$(BUILD_DIR)/asm/debug/map.o: asm/debug/map.s $(BUILD_DIR)/sm64_prelim.elf
|
||||
$(call print,Assembling:,$<,$@)
|
||||
$(V)python3 tools/mapPacker.py $(BUILD_DIR)/sm64_prelim.map $(BUILD_DIR)/bin/addr.bin $(BUILD_DIR)/bin/name.bin
|
||||
$(V)$(CROSS)gcc -c $(ASMFLAGS) $(foreach i,$(INCLUDE_DIRS),-Wa,-I$(i)) -x assembler-with-cpp -MMD -MF $(BUILD_DIR)/$*.d -o $@ $<
|
||||
|
||||
# Link SM64 ELF file
|
||||
$(ELF): $(BUILD_DIR)/sm64_prelim.elf $(O_FILES) $(YAY0_OBJ_FILES) $(SEG_FILES) $(BUILD_DIR)/$(LD_SCRIPT) undefined_syms.txt $(BUILD_DIR)/libz.a $(BUILD_DIR)/libgoddard.a
|
||||
$(ELF): $(BUILD_DIR)/sm64_prelim.elf $(BUILD_DIR)/asm/debug/map.o $(O_FILES) $(YAY0_OBJ_FILES) $(SEG_FILES) $(BUILD_DIR)/$(LD_SCRIPT) undefined_syms.txt $(BUILD_DIR)/libz.a $(BUILD_DIR)/libgoddard.a
|
||||
@$(PRINT) "$(GREEN)Linking ELF file: $(BLUE)$@ $(NO_COL)\n"
|
||||
$(V)$(LD) --gc-sections -L $(BUILD_DIR) -T undefined_syms.txt -T $(BUILD_DIR)/$(LD_SCRIPT) -T goddard.txt -Map $(BUILD_DIR)/sm64.$(VERSION).map --no-check-sections $(addprefix -R ,$(SEG_FILES)) -o $@ $(O_FILES) -L$(LIBS_DIR) -l$(ULTRALIB) -Llib $(LINK_LIBRARIES) -u sprintf -u osMapTLB -Llib/gcclib/$(LIBGCCDIR) -lgcc -lnustd -lhvqm2
|
||||
$(V)$(LD) --gc-sections -L $(BUILD_DIR) -T undefined_syms.txt -T $(BUILD_DIR)/$(LD_SCRIPT) -T goddard.txt -Map $(BUILD_DIR)/sm64.$(VERSION).map --no-check-sections $(addprefix -R ,$(SEG_FILES)) -o $@ $(O_FILES) -L$(LIBS_DIR) -l$(ULTRALIB) -Llib $(LINK_LIBRARIES) -u sprintf -u osMapTLB -Llib/gcclib/$(LIBGCCDIR) -lgcc
|
||||
|
||||
# Build ROM
|
||||
$(ROM): $(ELF)
|
||||
|
||||
17
asm/debug/map.s
Normal file
17
asm/debug/map.s
Normal file
@@ -0,0 +1,17 @@
|
||||
.include "macros.inc"
|
||||
.section .data
|
||||
.balign 16
|
||||
glabel gMapEntries
|
||||
.incbin "bin/addr.bin"
|
||||
glabel gMapEntryEnd
|
||||
|
||||
.balign 16
|
||||
glabel gMapStrings
|
||||
.incbin "bin/name.bin"
|
||||
glabel gMapStringsEnd
|
||||
|
||||
.balign 16
|
||||
glabel gMapEntrySize
|
||||
.word (gMapEntryEnd - gMapEntries) / 4
|
||||
glabel gMapStringSize
|
||||
.word (gMapStringsEnd - gMapStrings)
|
||||
31
sm64.ld
31
sm64.ld
@@ -144,12 +144,23 @@ SECTIONS
|
||||
. = _hvqbufSegmentBssEnd;
|
||||
#endif
|
||||
|
||||
/* hardcoded symbols to satisfy preliminary link for map parser */
|
||||
#ifndef DEBUG_MAP_STACKTRACE
|
||||
parse_map = 0x80345678;
|
||||
find_function_in_stack = 0x80345678;
|
||||
_mapDataSegmentRomStart = 0;
|
||||
gMapEntries = 0;
|
||||
gMapEntrySize = 0;
|
||||
gMapStrings = 0;
|
||||
#endif
|
||||
|
||||
BEGIN_SEG(main, .) SUBALIGN(16)
|
||||
{
|
||||
KEEP(BUILD_DIR/asm/entry.o(.text));
|
||||
|
||||
BUILD_DIR/src/boot*.o(.text);
|
||||
BUILD_DIR/src/hvqm*.o(.text);
|
||||
BUILD_DIR/src/usb*.o(.text);
|
||||
BUILD_DIR/src/audio*.o(.text);
|
||||
#ifdef S2DEX_TEXT_ENGINE
|
||||
lib/libs2d_engine.a:*(.text);
|
||||
@@ -165,9 +176,11 @@ SECTIONS
|
||||
*/libhvqm2.a:*.o(.text);
|
||||
BUILD_DIR/lib/rsp.o(.text);
|
||||
lib/PR/hvqm/hvqm2sp1.o(.text);
|
||||
_mainSegmentTextEnd = .;
|
||||
|
||||
/* data */
|
||||
BUILD_DIR/src/boot*.o(.*data*);
|
||||
BUILD_DIR/src/usb*.o(.*data*);
|
||||
BUILD_DIR/src/audio*.o(.*data*);
|
||||
#ifdef S2DEX_TEXT_ENGINE
|
||||
lib/libs2d_engine.a:*(.*data*);
|
||||
@@ -185,6 +198,7 @@ SECTIONS
|
||||
|
||||
/* rodata */
|
||||
BUILD_DIR/src/boot*.o(.rodata*);
|
||||
BUILD_DIR/src/usb*.o(.rodata*);
|
||||
BUILD_DIR/src/audio*.o(.rodata*);
|
||||
#ifdef S2DEX_TEXT_ENGINE
|
||||
lib/libs2d_engine.a:*(.rodata*);
|
||||
@@ -201,13 +215,11 @@ SECTIONS
|
||||
lib/PR/hvqm/hvqm2sp1.o(.rodata*);
|
||||
}
|
||||
END_SEG(main)
|
||||
#ifndef PRELIMINARY
|
||||
ASSERT((_mainSegmentRomEnd <= 0x101000), "Error: Please shrink your main segment to under 1MB.")
|
||||
#endif
|
||||
BEGIN_NOLOAD(main)
|
||||
{
|
||||
BUILD_DIR/src/boot*.o(.*bss*);
|
||||
BUILD_DIR/src/hvqm*.o(.*bss*);
|
||||
BUILD_DIR/src/usb*.o(.*bss*);
|
||||
BUILD_DIR/src/audio*.o(.*bss*);
|
||||
#ifdef S2DEX_TEXT_ENGINE
|
||||
lib/libs2d_engine.a:*(.*bss*);
|
||||
@@ -233,23 +245,20 @@ SECTIONS
|
||||
{
|
||||
BUILD_DIR/src/game*.o(.text);
|
||||
BUILD_DIR/src/engine*.o(.text);
|
||||
BUILD_DIR/src/usb*.o(.text);
|
||||
_engineSegmentTextEnd = .;
|
||||
/* data */
|
||||
BUILD_DIR/src/game*.o(.*data*);
|
||||
BUILD_DIR/src/engine*.o(.data*);
|
||||
BUILD_DIR/src/engine*.o(.sdata*);
|
||||
BUILD_DIR/src/usb*.o(.*data*);
|
||||
/* rodata */
|
||||
BUILD_DIR/src/game*.o(.rodata*);
|
||||
BUILD_DIR/src/engine*.o(.rodata*);
|
||||
BUILD_DIR/src/usb*.o(.rodata*);
|
||||
}
|
||||
END_SEG(engine)
|
||||
BEGIN_NOLOAD(engine)
|
||||
{
|
||||
BUILD_DIR/src/game*.o(.*bss*);
|
||||
BUILD_DIR/src/engine*.o(.bss*);
|
||||
BUILD_DIR/src/usb*.o(.*bss*);
|
||||
. = ALIGN(0x40);
|
||||
}
|
||||
END_NOLOAD(engine)
|
||||
@@ -330,6 +339,7 @@ SECTIONS
|
||||
BEGIN_SEG(goddard, RAM_END - GODDARD_SIZE)
|
||||
{
|
||||
KEEP(BUILD_DIR/src/menu*.o(.text));
|
||||
_goddardSegmentTextEnd = .;
|
||||
KEEP(BUILD_DIR/src/menu*.o(.data*));
|
||||
KEEP(BUILD_DIR/src/menu*.o(.rodata*));
|
||||
#ifdef KEEP_MARIO_HEAD
|
||||
@@ -497,6 +507,13 @@ SECTIONS
|
||||
}
|
||||
END_SEG(capcom)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_MAP_STACKTRACE
|
||||
BEGIN_SEG(mapData, 0x80700000) {
|
||||
KEEP(BUILD_DIR/asm/debug/map.o(.data*));
|
||||
}
|
||||
END_SEG(mapData)
|
||||
#endif
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "types.h"
|
||||
#include "puppyprint.h"
|
||||
#include "audio/external.h"
|
||||
#include "farcall.h"
|
||||
#include "game_init.h"
|
||||
#include "main.h"
|
||||
|
||||
@@ -14,8 +15,9 @@
|
||||
#include "printf.h"
|
||||
|
||||
enum crashPages {
|
||||
PAGE_STACK,
|
||||
PAGE_CONTEXT,
|
||||
PAGE_LOG,
|
||||
PAGE_STACKTRACE,
|
||||
PAGE_COUNT
|
||||
};
|
||||
|
||||
@@ -65,6 +67,9 @@ char *gFpcsrDesc[6] = {
|
||||
|
||||
|
||||
extern u64 osClockRate;
|
||||
extern far char *parse_map(u32);
|
||||
extern far void map_data_init(void);
|
||||
extern far char *find_function_in_stack(u32 *);
|
||||
|
||||
struct {
|
||||
OSThread thread;
|
||||
@@ -165,7 +170,7 @@ void crash_screen_print_float_reg(s32 x, s32 y, s32 regNum, void *addr) {
|
||||
if ((exponent >= -0x7E && exponent <= 0x7F) || bits == 0) {
|
||||
crash_screen_print(x, y, "F%02d:%.3e", regNum, *(f32 *) addr);
|
||||
} else {
|
||||
crash_screen_print(x, y, "F%02d:---------", regNum);
|
||||
crash_screen_print(x, y, "F%02d:%08XD", regNum, *(u32 *) addr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +189,7 @@ void crash_screen_print_fpcsr(u32 fpcsr) {
|
||||
}
|
||||
}
|
||||
|
||||
void draw_crash_stack(OSThread *thread, s32 cause)
|
||||
void draw_crash_context(OSThread *thread, s32 cause)
|
||||
{
|
||||
__OSThreadContext *tc = &thread->context;
|
||||
|
||||
@@ -193,7 +198,14 @@ void draw_crash_stack(OSThread *thread, s32 cause)
|
||||
crash_screen_print(30, 35, "PC:%08XH SR:%08XH VA:%08XH", tc->pc, tc->sr, tc->badvaddr);
|
||||
osWritebackDCacheAll();
|
||||
crash_screen_draw_rect(25, 45, 270, 185);
|
||||
crash_screen_print(30, 50, "AT:%08XH V0:%08XH V1:%08XH", (u32) tc->at, (u32) tc->v0, (u32) tc->v1);
|
||||
if ((u32)parse_map == 0x80345678) {
|
||||
crash_screen_print(30, 50, "AT:%08XH V0:%08XH V1:%08XH", (u32) tc->at, (u32) tc->v0,
|
||||
(u32) tc->v1);
|
||||
} else {
|
||||
char *fname = parse_map(tc->pc);
|
||||
crash_screen_print(30, 50, "CRASH AT: %s", fname == NULL ? "UNKNOWN" : fname);
|
||||
}
|
||||
// crash_screen_print(30, 50, "AT:%08XH V0:%08XH V1:%08XH", (u32) tc->at, (u32) tc->v0, (u32) tc->v1);
|
||||
crash_screen_print(30, 60, "A0:%08XH A1:%08XH A2:%08XH", (u32) tc->a0, (u32) tc->a1, (u32) tc->a2);
|
||||
crash_screen_print(30, 70, "A3:%08XH T0:%08XH T1:%08XH", (u32) tc->a3, (u32) tc->t0, (u32) tc->t1);
|
||||
crash_screen_print(30, 80, "T2:%08XH T3:%08XH T4:%08XH", (u32) tc->t2, (u32) tc->t3, (u32) tc->t4);
|
||||
@@ -241,6 +253,46 @@ void draw_crash_log(OSThread *thread, s32 cause)
|
||||
}
|
||||
|
||||
|
||||
// prints any function pointers it finds in the stack
|
||||
// format:
|
||||
// SP address: function name
|
||||
void draw_stacktrace(OSThread *thread, s32 cause) {
|
||||
__OSThreadContext *tc = &thread->context;
|
||||
u32 temp_sp = tc->sp + 0x14;
|
||||
|
||||
crash_screen_draw_rect(25, 20, 270, 25);
|
||||
crash_screen_print(30, 25, "STACK TRACE FROM %08X:", temp_sp);
|
||||
if ((u32) parse_map == 0x80345678) {
|
||||
crash_screen_print(30, 35, "CURRFUNC: NONE");
|
||||
} else {
|
||||
crash_screen_print(30, 35, "CURRFUNC: %s", parse_map(tc->pc));
|
||||
}
|
||||
|
||||
osWritebackDCacheAll();
|
||||
|
||||
for (int i = 0; i < 18; i++) {
|
||||
if ((u32) find_function_in_stack == 0x80345678) {
|
||||
crash_screen_print(30, 45 + (i * 10), "STACK TRACE DISABLED");
|
||||
break;
|
||||
} else {
|
||||
if ((u32) find_function_in_stack == 0x80345678) {
|
||||
return;
|
||||
}
|
||||
|
||||
char *fname = find_function_in_stack(&temp_sp);
|
||||
if (fname == NULL || (*(u32*)temp_sp & 0x80000000 == 0)) {
|
||||
crash_screen_print(30, 45 + (i * 10), "%08X: UNKNOWN", temp_sp);
|
||||
} else {
|
||||
crash_screen_print(30, 45 + (i * 10), "%08X: %s", temp_sp, fname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void draw_crash_screen(OSThread *thread)
|
||||
{
|
||||
s32 cause;
|
||||
@@ -282,8 +334,9 @@ void draw_crash_screen(OSThread *thread)
|
||||
crash_screen_print(15, 10, "Page:%d L/Z: Left R: Right", crashPage);
|
||||
switch (crashPage)
|
||||
{
|
||||
case PAGE_STACK: draw_crash_stack(thread, cause); break;
|
||||
case PAGE_LOG: draw_crash_log(thread, cause); break;
|
||||
case PAGE_CONTEXT: draw_crash_context(thread, cause); break;
|
||||
case PAGE_LOG: draw_crash_log(thread, cause); break;
|
||||
case PAGE_STACKTRACE: draw_stacktrace(thread, cause); break;
|
||||
}
|
||||
|
||||
osWritebackDCacheAll();
|
||||
@@ -321,6 +374,9 @@ void thread2_crash_screen(UNUSED void *arg) {
|
||||
osSetEventMesg(OS_EVENT_FAULT, &gCrashScreen.mesgQueue, (OSMesg) 2);
|
||||
goto finished;
|
||||
reset:
|
||||
if ((u32) map_data_init != 0x80345678) {
|
||||
map_data_init();
|
||||
}
|
||||
gCrashScreen.thread.priority = 15;
|
||||
stop_sounds_in_continuous_banks();
|
||||
stop_background_music(sBackgroundMusicQueue[0].seqId);
|
||||
|
||||
88
src/game/map_parser.c
Normal file
88
src/game/map_parser.c
Normal file
@@ -0,0 +1,88 @@
|
||||
#include <ultra64.h>
|
||||
#include <PR/os_internal_error.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "segments.h"
|
||||
|
||||
#define STACK_TRAVERSAL_LIMIT 100
|
||||
|
||||
struct MapEntry {
|
||||
u32 addr;
|
||||
u32 nm_offset;
|
||||
u32 nm_len;
|
||||
u32 pad;
|
||||
};
|
||||
extern u8 gMapStrings[];
|
||||
extern struct MapEntry gMapEntries[];
|
||||
extern u32 gMapEntrySize;
|
||||
extern u8 _mapDataSegmentRomStart[];
|
||||
|
||||
|
||||
// code provided by Wiseguy
|
||||
static s32 headless_dma(u32 devAddr, void *dramAddr, u32 size)
|
||||
{
|
||||
register u32 stat;
|
||||
stat = IO_READ(PI_STATUS_REG);
|
||||
while (stat & (PI_STATUS_IO_BUSY | PI_STATUS_DMA_BUSY)) {
|
||||
stat = IO_READ(PI_STATUS_REG);
|
||||
}
|
||||
IO_WRITE(PI_DRAM_ADDR_REG, K0_TO_PHYS(dramAddr));
|
||||
IO_WRITE(PI_CART_ADDR_REG, K1_TO_PHYS((u32)osRomBase | devAddr));
|
||||
IO_WRITE(PI_WR_LEN_REG, size - 1);
|
||||
return 0;
|
||||
}
|
||||
static u32 headless_pi_status(void)
|
||||
{
|
||||
return IO_READ(PI_STATUS_REG);
|
||||
}
|
||||
// end of code provided by Wiseguy
|
||||
|
||||
|
||||
void map_data_init(void) {
|
||||
headless_dma(_mapDataSegmentRomStart, 0x80700000, 0x100000);
|
||||
while (headless_pi_status() & (PI_STATUS_DMA_BUSY | PI_STATUS_ERROR));
|
||||
}
|
||||
|
||||
char *parse_map(u32 pc) {
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < gMapEntrySize; i++) {
|
||||
if (gMapEntries[i].addr >= pc) break;
|
||||
}
|
||||
|
||||
if (i == gMapEntrySize - 1) {
|
||||
return NULL;
|
||||
} else {
|
||||
return (char*) ((u32)gMapStrings + gMapEntries[i - 1].nm_offset);
|
||||
}
|
||||
}
|
||||
|
||||
extern u8 _mainSegmentStart[];
|
||||
extern u8 _mainSegmentTextEnd[];
|
||||
extern u8 _engineSegmentStart[];
|
||||
extern u8 _engineSegmentTextEnd[];
|
||||
extern u8 _goddardSegmentStart[];
|
||||
extern u8 _goddardSegmentTextEnd[];
|
||||
|
||||
char *find_function_in_stack(u32 *sp) {
|
||||
for (int i = 0; i < STACK_TRAVERSAL_LIMIT; i++) {
|
||||
u32 val = *sp;
|
||||
val = *(u32 *)val;
|
||||
*sp = *sp + 4;
|
||||
|
||||
if ((val >= (u32)_mainSegmentStart) && (val <= (u32)_mainSegmentTextEnd)) {
|
||||
return parse_map(val);
|
||||
}
|
||||
else if ((val >= (u32)_engineSegmentStart) && (val <= (u32)_engineSegmentTextEnd)) {
|
||||
return parse_map(val);
|
||||
}
|
||||
else if ((val >= (u32)_goddardSegmentStart) && (val <= (u32)_goddardSegmentTextEnd)) {
|
||||
return parse_map(val);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
42
tools/mapPacker.py
Normal file
42
tools/mapPacker.py
Normal file
@@ -0,0 +1,42 @@
|
||||
import sys, struct
|
||||
|
||||
class MapEntry():
|
||||
def __init__(self, nm, addr):
|
||||
self.name = nm
|
||||
self.addr = addr
|
||||
self.strlen = (len(nm) + 4) & (~3)
|
||||
def __str__(self):
|
||||
return "%s %s %d" % (self.addr, self.name, self.strlen)
|
||||
def __repr__(self):
|
||||
return "%s %s %d" % (self.addr, self.name, self.strlen)
|
||||
|
||||
|
||||
structDef = ">LLLL"
|
||||
|
||||
symNames = []
|
||||
|
||||
with open(sys.argv[1]) as f:
|
||||
for line in f:
|
||||
if "0x000000008" in line and "=" not in line and "." not in line and "*" not in line and "load address" not in line:
|
||||
tokens = line.split()
|
||||
symNames.append(MapEntry(tokens[1], int(tokens[0], 16)))
|
||||
|
||||
|
||||
|
||||
f1 = open(sys.argv[2], "wb+")
|
||||
f2 = open(sys.argv[3], "wb+")
|
||||
|
||||
symNames.sort(key=lambda x: x.addr)
|
||||
|
||||
off = 0
|
||||
for x in symNames:
|
||||
f1.write(struct.pack(structDef, x.addr, off, len(x.name), 0))
|
||||
f2.write(struct.pack(">%ds" % x.strlen, bytes(x.name, encoding="ascii")))
|
||||
off += x.strlen
|
||||
|
||||
|
||||
f1.close()
|
||||
f2.close()
|
||||
|
||||
# print('\n'.join([str(hex(x.addr)) + " " + x.name for x in symNames]))
|
||||
|
||||
Reference in New Issue
Block a user