mirror of
https://github.com/wiiu-env/WiiUPluginSystem.git
synced 2024-11-16 15:49:23 +01:00
[Plugin] Added plugin that logs some memory infos
This commit is contained in:
parent
55dd57d62f
commit
db8643d3f5
291
plugins/memory_info/Makefile
Normal file
291
plugins/memory_info/Makefile
Normal file
@ -0,0 +1,291 @@
|
||||
DO_LOGGING := 1
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Clear the implicit built in rules
|
||||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(DEVKITPPC)),)
|
||||
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
|
||||
endif
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPRO")
|
||||
endif
|
||||
export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH)
|
||||
export PORTLIBS := $(DEVKITPRO)/portlibs/ppc
|
||||
export WUPSDIR := $(DEVKITPRO)/wups
|
||||
export GCC_VER := $(shell $(DEVKITPPC)/bin/powerpc-eabi-gcc -dumpversion)
|
||||
|
||||
PREFIX := powerpc-eabi-
|
||||
|
||||
export AS := $(PREFIX)as
|
||||
export CC := $(PREFIX)gcc
|
||||
export CXX := $(PREFIX)g++
|
||||
export LD := $(PREFIX)ld
|
||||
export AR := $(PREFIX)ar
|
||||
export OBJCOPY := $(PREFIX)objcopy
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# INCLUDES is a list of directories containing extra header files
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR)).mod
|
||||
BUILD := build
|
||||
SOURCES := src
|
||||
|
||||
DATA :=
|
||||
|
||||
INCLUDES := src
|
||||
|
||||
MAP ?= $(TARGET:.mod=.map)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
# -Os: optimise size
|
||||
# -Wall: generate lots of warnings
|
||||
# -DGEKKO_U: define the symbol GEKKO (used in some headers)
|
||||
# -D__wiiu__: define the symbol __wii__ (used in some headers)
|
||||
# -mrvl: enable wii/gamecube compilation
|
||||
# -mcpu=750: enable processor specific compilation
|
||||
# -meabi: enable eabi specific compilation
|
||||
# -mhard-float: enable hardware floating point instructions
|
||||
# -fshort-wchar: use 16 bit whcar_t type in keeping with Wii executables
|
||||
# -fno-common: stop common variables which the loader can't understand
|
||||
# -msdata-none: do not use r2 or r13 as small data areas
|
||||
# -memb: enable embedded application specific compilation
|
||||
# -ffunction-sections: split up functions so linker can garbage collect
|
||||
# -fdata-sections: split up data so linker can garbage collect
|
||||
COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fshort-wchar -fno-common -msdata=none -memb -ffunction-sections -fdata-sections
|
||||
|
||||
|
||||
# -x c: compile as c code
|
||||
# -std=c11: use the c11 standard
|
||||
CFLAGS += $(COMMON_CFLAGS) -x c -std=c11
|
||||
|
||||
# -x c: compile as c++ code
|
||||
# -std=gnu++11: use the c++11 standard
|
||||
CXXFLAGS += $(COMMON_CFLAGS) -x c++ -std=gnu++11
|
||||
|
||||
ifeq ($(DO_LOGGING), 1)
|
||||
CFLAGS += -D__LOGGING__
|
||||
CXXFLAGS += -D__LOGGING__
|
||||
endif
|
||||
|
||||
ASFLAGS := -mregnames
|
||||
# --relocatable: make sure ld doesn't remove relocations wups will need
|
||||
# -s: strip local symbols to speed linking
|
||||
# -u: keep certain sections
|
||||
# -wrap: wrap function
|
||||
# --gc-sections: remove unneeded symbols
|
||||
# -T: use the linker script specified (to force certain wups sections together)
|
||||
# -Map: generate a map file
|
||||
|
||||
LDFLAG_COMMON += -u wups_load -u wups_meta -u wups_hooks -T $(WUPSDIR)/wups.ld \
|
||||
-Wl,-wrap,open,-wrap,close,-wrap,write,-wrap,read,-wrap,lseek,-wrap,stat,-wrap,fstat,-wrap,opendir,-wrap,closedir,-wrap,readdir \
|
||||
-Wl,-Map,$(notdir $@).map,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r,--gc-sections
|
||||
|
||||
LDFLAGS_MOD += $(LDFLAG_COMMON),--relocatable
|
||||
LDFLAGS_ELF += --relocatable -s -T $(WUPSDIR)/wups_elf.ld
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
Q := @
|
||||
MAKEFLAGS += --no-print-directory
|
||||
#---------------------------------------------------------------------------------
|
||||
# any extra libraries we wish to link with the project
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBS := -lwups -lutils -ldynamiclibs
|
||||
#
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(DEVKITPPC)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#---------------------------------------------------------------------------------
|
||||
export PROJECTDIR := $(CURDIR)
|
||||
export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET)
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# automatically build a list of object files for our project
|
||||
#---------------------------------------------------------------------------------
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
TTFFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.ttf)))
|
||||
PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
export LD_MOD := $(CC)
|
||||
else
|
||||
export LD_MOD := $(CXX)
|
||||
endif
|
||||
|
||||
export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
|
||||
$(sFILES:.s=.o) $(SFILES:.S=.o) \
|
||||
$(PNGFILES:.png=.png.o) $(addsuffix .o,$(BINFILES))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# build a list of include paths
|
||||
#---------------------------------------------------------------------------------
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD) -I$(PORTLIBS)/include \
|
||||
-I$(PORTLIBS)/include/libutils -I$(WUPSDIR)/include
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# build a list of library paths
|
||||
#---------------------------------------------------------------------------------
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
|
||||
-L$(PORTLIBS)/lib \
|
||||
-L$(WUPSDIR)/lib
|
||||
|
||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||
.PHONY: $(BUILD) clean install
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf $(OUTPUT)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
THIS_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
|
||||
|
||||
###############################################################################
|
||||
# Rule to make everything.
|
||||
PHONY += all
|
||||
|
||||
all : $(OUTPUT)
|
||||
###############################################################################
|
||||
# Special build rules
|
||||
|
||||
# Rule to make the module file.
|
||||
$(OUTPUT) : output.elf
|
||||
@echo "checking for missing symbols ..."
|
||||
@$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LIBS) $(LIBPATHS) -o check_linking.elf
|
||||
@echo "linking ..." $@
|
||||
@$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAGS_MOD) $(LIBS) $(LIBPATHS) -o $@
|
||||
|
||||
# Rule to make the module file.
|
||||
output.elf : $(OFILES)
|
||||
@echo "linking ... output.elf"
|
||||
|
||||
|
||||
@$(LD) $(OFILES) $(LDFLAGS_ELF) $(LIBS) $(LIBPATHS) -o $@
|
||||
|
||||
###############################################################################
|
||||
# Standard build rules
|
||||
#---------------------------------------------------------------------------------
|
||||
%.a:
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $@)
|
||||
@rm -f $@
|
||||
@$(AR) -rc $@ $^
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.o: %.cpp
|
||||
@echo $(notdir $<)
|
||||
@$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) $(INCLUDE) -c $< -o $@ $(ERROR_FILTER)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.o: %.c
|
||||
@echo $(notdir $<)
|
||||
@$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(CFLAGS) $(INCLUDE) -c $< -o $@ $(ERROR_FILTER)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.o: %.S
|
||||
@echo $(notdir $<)
|
||||
@$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(ASFLAGS) -c $< -o $@ $(ERROR_FILTER)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.png.o : %.png
|
||||
@echo $(notdir $<)
|
||||
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.jpg.o : %.jpg
|
||||
@echo $(notdir $<)
|
||||
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.ttf.o : %.ttf
|
||||
@echo $(notdir $<)
|
||||
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o : %.bin
|
||||
@echo $(notdir $<)
|
||||
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.wav.o : %.wav
|
||||
@echo $(notdir $<)
|
||||
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.mp3.o : %.mp3
|
||||
@echo $(notdir $<)
|
||||
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.ogg.o : %.ogg
|
||||
@echo $(notdir $<)
|
||||
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||
|
||||
###############################################################################
|
||||
# Assembly listing rules
|
||||
|
||||
# Rule to make assembly listing.
|
||||
PHONY += list
|
||||
list : $(LIST)
|
||||
|
||||
# Rule to make the listing file.
|
||||
%.list : $(TARGET)
|
||||
$(LOG)
|
||||
-$Qmkdir -p $(dir $@)
|
||||
$Q$(OBJDUMP) -d $< > $@
|
||||
|
||||
###############################################################################
|
||||
# Clean rule
|
||||
|
||||
# Rule to clean files.
|
||||
PHONY += clean
|
||||
clean :
|
||||
$Qrm -rf $(wildcard $(BUILD) $(BIN))
|
||||
|
||||
###############################################################################
|
||||
# Phony targets
|
||||
|
||||
.PHONY : $(PHONY)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
13
plugins/memory_info/README.md
Normal file
13
plugins/memory_info/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Memory info for the Wii U Plugin System
|
||||
|
||||
Prints information about the current memory usage when pressing L+R+X+Y+A+B via the UDPReader
|
||||
|
||||
## Building
|
||||
|
||||
For building you need:
|
||||
- [wups](https://github.com/Maschell/WiiUPluginSystem)
|
||||
- [dynamic_libs](https://github.com/Maschell/dynamic_libs/tree/lib) for access to the functions.
|
||||
- [libutils](https://github.com/Maschell/libutils) for common functions.
|
||||
|
||||
|
||||
Install them (in this order) according to their README's. Don't forget the dependencies of the libs itself.
|
27
plugins/memory_info/src/c_retain_vars.c
Normal file
27
plugins/memory_info/src/c_retain_vars.c
Normal file
@ -0,0 +1,27 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2018 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include "c_retain_vars.h"
|
||||
|
||||
memHeapInfo expHeapPointer[MAX_EXP_HEAP_INFOS] __attribute__((section(".data")));
|
||||
memHeapInfo frmHeapPointer[MAX_FRM_HEAP_INFOS] __attribute__((section(".data")));
|
||||
memUnitHeapInfo unitHeapPointer[MAX_UNIT_HEAP_INFOS] __attribute__((section(".data")));
|
||||
|
||||
baseHeapInfo baseHeaphandles[MAX_BASE_HEAP_INFOS] __attribute__((section(".data")));
|
||||
blockHeapInfo blockHeapInfos[MAX_BLOCK_HEAP_INFOS] __attribute__((section(".data")));
|
||||
memHeapInfo userHeapInfos[MAX_USER_HEAP_INFOS] __attribute__((section(".data")));
|
||||
|
||||
u8 gButtonComboCooldown __attribute__((section(".data"))) = 0;
|
32
plugins/memory_info/src/c_retain_vars.h
Normal file
32
plugins/memory_info/src/c_retain_vars.h
Normal file
@ -0,0 +1,32 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2018 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#ifndef C_RETAINS_VARS_H_
|
||||
#define C_RETAINS_VARS_H_
|
||||
|
||||
#include "memory_defs.h"
|
||||
|
||||
extern memHeapInfo expHeapPointer[MAX_EXP_HEAP_INFOS];
|
||||
extern memHeapInfo frmHeapPointer[MAX_FRM_HEAP_INFOS];
|
||||
extern memUnitHeapInfo unitHeapPointer[MAX_UNIT_HEAP_INFOS];
|
||||
|
||||
extern baseHeapInfo baseHeaphandles[MAX_BASE_HEAP_INFOS];
|
||||
extern blockHeapInfo blockHeapInfos[MAX_BLOCK_HEAP_INFOS];
|
||||
extern memHeapInfo userHeapInfos[MAX_USER_HEAP_INFOS];
|
||||
|
||||
extern u8 gButtonComboCooldown;
|
||||
|
||||
#endif // C_RETAINS_VARS_H_
|
34
plugins/memory_info/src/common_hooks.c
Normal file
34
plugins/memory_info/src/common_hooks.c
Normal file
@ -0,0 +1,34 @@
|
||||
#include <wups.h>
|
||||
#include <string.h>
|
||||
#include <dynamic_libs/os_functions.h>
|
||||
#include <dynamic_libs/vpad_functions.h>
|
||||
#include <utils/logger.h>
|
||||
#include "main.h"
|
||||
|
||||
DECL_FUNCTION(void, __PPCExit, void) {
|
||||
// We reset them at ende, in case at application even uses the functions
|
||||
// BEFORE with have our init hook.
|
||||
memset(expHeapPointer,0,sizeof(expHeapPointer));
|
||||
memset(unitHeapPointer,0,sizeof(unitHeapPointer));
|
||||
memset(frmHeapPointer,0,sizeof(frmHeapPointer));
|
||||
memset(baseHeaphandles,0,sizeof(baseHeaphandles));
|
||||
memset(userHeapInfos,0,sizeof(userHeapInfos));
|
||||
real___PPCExit();
|
||||
}
|
||||
|
||||
DECL_FUNCTION(int, VPADRead, int chan, VPADData *buffer, u32 buffer_size, s32 *error) {
|
||||
int result = real_VPADRead(chan, buffer, buffer_size, error);
|
||||
|
||||
int btns = VPAD_BUTTON_R | VPAD_BUTTON_L | VPAD_BUTTON_A | VPAD_BUTTON_B | VPAD_BUTTON_X | VPAD_BUTTON_Y;
|
||||
if(result > 0 && ((buffer[0].btns_h & (btns)) == btns) && gButtonComboCooldown == 0 && OSIsHomeButtonMenuEnabled()) {
|
||||
print_memory_info();
|
||||
gButtonComboCooldown = 0x3C;
|
||||
}
|
||||
if(gButtonComboCooldown > 0) {
|
||||
gButtonComboCooldown--;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
WUPS_MUST_REPLACE(__PPCExit, WUPS_LOADER_LIBRARY_COREINIT, __PPCExit);
|
||||
WUPS_MUST_REPLACE(VPADRead, WUPS_LOADER_LIBRARY_VPAD, VPADRead);
|
106
plugins/memory_info/src/main.c
Normal file
106
plugins/memory_info/src/main.c
Normal file
@ -0,0 +1,106 @@
|
||||
#include <wups.h>
|
||||
#include <string.h>
|
||||
#include <dynamic_libs/os_functions.h>
|
||||
#include <dynamic_libs/socket_functions.h>
|
||||
#include <utils/logger.h>
|
||||
#include "main.h"
|
||||
|
||||
WUPS_PLUGIN_NAME("Memory Info");
|
||||
WUPS_PLUGIN_DESCRIPTION("Prints information about the current memory usage when pressing L+R+X+Y+A+B.");
|
||||
WUPS_PLUGIN_VERSION("v1.0");
|
||||
WUPS_PLUGIN_AUTHOR("Maschell");
|
||||
WUPS_PLUGIN_LICENSE("GPL");
|
||||
|
||||
|
||||
INITIALIZE(args) {
|
||||
InitOSFunctionPointers();
|
||||
InitSocketFunctionPointers();
|
||||
log_init();
|
||||
//InitVPadFunctionPointers();
|
||||
}
|
||||
|
||||
void printMemHeapInfo(memHeapInfo * listStart, u32 listLength, const char * listname) {
|
||||
for(int i = 0; i<listLength; i++) {
|
||||
if(listStart[i].handle != 0) {
|
||||
s32 parent = MEMFindParentHeap(listStart[i].handle);
|
||||
DEBUG_FUNCTION_LINE("%s:", listname);
|
||||
if(parent == 0) {
|
||||
log_print(" parent: <NONE> ");
|
||||
} else {
|
||||
log_printf(" parent: 0x%08X ", parent);
|
||||
}
|
||||
log_printf(" address 0x%08X handle 0x%08X size %07d kb old size %07d kb flags 0x%04X\n",listStart[i].address,listStart[i].handle,listStart[i].size/1024,listStart[i].oldSize/1024,listStart[i].flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print_memory_info() {
|
||||
DEBUG_FUNCTION_LINE("Print expanded heap infos\n");
|
||||
printMemHeapInfo(expHeapPointer,MAX_EXP_HEAP_INFOS, "Expanded heap:");
|
||||
|
||||
DEBUG_FUNCTION_LINE("Print frmHeap\n");
|
||||
printMemHeapInfo(frmHeapPointer,MAX_FRM_HEAP_INFOS, "Frame heap:");
|
||||
|
||||
DEBUG_FUNCTION_LINE("Print unitHeap\n");
|
||||
for(int i = 0; i<MAX_UNIT_HEAP_INFOS; i++) {
|
||||
if(unitHeapPointer[i].handle != 0) {
|
||||
DEBUG_FUNCTION_LINE("unitHeap: address 0x%08X handle 0x%08X heapSize %07d kb memSize %07d kb align 0x%08X flags 0x%04X\n",unitHeapPointer[i].address,unitHeapPointer[i].handle,unitHeapPointer[i].heapSize/1024,unitHeapPointer[i].memSize/1024,unitHeapPointer[i].align,unitHeapPointer[i].flags);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_FUNCTION_LINE("Print set base heap info\n");
|
||||
for(int i = 0; i<MAX_BASE_HEAP_INFOS; i++) {
|
||||
if(baseHeaphandles[i].newHandle != 0) {
|
||||
DEBUG_FUNCTION_LINE("MEMSetBaseHeapHandle was called: oldHandle 0x%08X newHandle 0x%08X arena %d\n",baseHeaphandles[i].oldHandle,baseHeaphandles[i].newHandle,baseHeaphandles[i].memArena);
|
||||
}
|
||||
}
|
||||
DEBUG_FUNCTION_LINE("Print set block heap info\n");
|
||||
for(int i = 0; i<MAX_BLOCK_HEAP_INFOS; i++) {
|
||||
if(blockHeapInfos[i].startAddress != 0) {
|
||||
DEBUG_FUNCTION_LINE("MEMInitBlockHeap was called: handle 0x%08X tracking 0x%08X\n",blockHeapInfos[i].handle,blockHeapInfos[i].tracking);
|
||||
}
|
||||
}
|
||||
DEBUG_FUNCTION_LINE("Print set user heap info\n");
|
||||
printMemHeapInfo(userHeapInfos,MAX_USER_HEAP_INFOS, "User heap:");
|
||||
|
||||
DEBUG_FUNCTION_LINE("Testing malloc\n");
|
||||
u32 size = 0x1000;
|
||||
bool success = false;
|
||||
do {
|
||||
void * result = malloc(size);
|
||||
if(result != NULL) {
|
||||
//DEBUG_FUNCTION_LINE("Allocated %d kb from default heap\n",size/1024);
|
||||
free(result);
|
||||
result = NULL;
|
||||
success = true;
|
||||
} else {
|
||||
//DEBUG_FUNCTION_LINE("Failed to allocate %d kb from default heap\n",size/1024);
|
||||
success = false;
|
||||
}
|
||||
size += 0x1000;
|
||||
} while(success);
|
||||
DEBUG_FUNCTION_LINE("I was able to allocate %07d kb from default heap (alignment 4)\n",size/1024);
|
||||
|
||||
for(int i = 0; i<2; i++) {
|
||||
s32 defaultHeap = MEMGetBaseHeapHandle(i);
|
||||
if(defaultHeap != 0) {
|
||||
u32 start = 0;
|
||||
u32 size_bytes = 0;
|
||||
OSGetMemBound(i+1,&start,&size_bytes);
|
||||
DEBUG_FUNCTION_LINE("Memory Bound MEM%d: startAddress 0x%08X size 0x%08X\n",i+1,start,size_bytes);
|
||||
|
||||
s32 size = MEMGetAllocatableSizeForExpHeapEx(defaultHeap, 4);
|
||||
s32 totalSize = MEMGetTotalFreeSizeForExpHeap(defaultHeap);
|
||||
DEBUG_FUNCTION_LINE("BaseHandle address 0x%08X: MEM%d with %07d kb memory free in one block, %07d kb in total.\n",defaultHeap,i+1,size/1024,totalSize/1024);
|
||||
|
||||
s32 parent = MEMFindParentHeap(defaultHeap);
|
||||
if(parent != 0) {
|
||||
size = MEMGetAllocatableSizeForExpHeapEx(parent, 4);
|
||||
s32 totalSize = MEMGetTotalFreeSizeForExpHeap(parent);
|
||||
DEBUG_FUNCTION_LINE("It's parent heap is 0x%08X: With %07d kb memory free in one block, %07d kb in total.\n",parent,size/1024,totalSize/1024);
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE("No parent found =(\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
plugins/memory_info/src/main.h
Normal file
25
plugins/memory_info/src/main.h
Normal file
@ -0,0 +1,25 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2018 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#ifndef MAIN_H_
|
||||
#define MAIN_H_
|
||||
|
||||
#include "memory_defs.h"
|
||||
#include "c_retain_vars.h"
|
||||
|
||||
void print_memory_info();
|
||||
|
||||
#endif // MAIN_H_
|
64
plugins/memory_info/src/memory_defs.h
Normal file
64
plugins/memory_info/src/memory_defs.h
Normal file
@ -0,0 +1,64 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2018 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _MEMORY_DEFS_H_
|
||||
#define _MEMORY_DEFS_H_
|
||||
|
||||
#include <dynamic_libs/os_types.h>
|
||||
|
||||
#define MAX_USER_HEAP_INFOS 50
|
||||
#define MAX_FRM_HEAP_INFOS 50
|
||||
#define MAX_EXP_HEAP_INFOS 50
|
||||
#define MAX_UNIT_HEAP_INFOS 50
|
||||
#define MAX_ALLOCATOR_EXP_INFOS 50
|
||||
#define MAX_BASE_HEAP_INFOS 50
|
||||
#define MAX_BLOCK_HEAP_INFOS 50
|
||||
|
||||
typedef struct memHeapInfo_ {
|
||||
s32 handle;
|
||||
void * address;
|
||||
u32 size;
|
||||
u32 oldSize;
|
||||
u16 flags;
|
||||
} memHeapInfo;
|
||||
|
||||
typedef struct memUnitHeapInfo_ {
|
||||
s32 handle;
|
||||
void * address;
|
||||
u32 heapSize;
|
||||
u32 memSize;
|
||||
u32 align;
|
||||
u16 flags;
|
||||
} memUnitHeapInfo;
|
||||
|
||||
typedef struct baseHeapInfo_ {
|
||||
s32 oldHandle;
|
||||
s32 newHandle;
|
||||
s32 memArena;
|
||||
} baseHeapInfo;
|
||||
|
||||
typedef struct blockHeapInfo_ {
|
||||
s32 handle;
|
||||
void * tracking;
|
||||
void * startAddress;
|
||||
void * endAddress;
|
||||
void * initTrackMem;
|
||||
u32 initTrackMemBytes;
|
||||
u16 flags;
|
||||
} blockHeapInfo;
|
||||
|
||||
#endif
|
244
plugins/memory_info/src/memory_hooks.c
Normal file
244
plugins/memory_info/src/memory_hooks.c
Normal file
@ -0,0 +1,244 @@
|
||||
#include <wups.h>
|
||||
#include <dynamic_libs/os_types.h>
|
||||
#include "memory_defs.h"
|
||||
#include "c_retain_vars.h"
|
||||
|
||||
DECL_FUNCTION(s32, MEMCreateFrmHeapEx, void* address, u32 size, u16 flags) {
|
||||
s32 result = real_MEMCreateFrmHeapEx(address,size,flags);
|
||||
for(int i = 0; i<MAX_FRM_HEAP_INFOS; i++) {
|
||||
if(frmHeapPointer[i].handle == 0) {
|
||||
frmHeapPointer[i].handle = result;
|
||||
frmHeapPointer[i].address = address;
|
||||
frmHeapPointer[i].size = size;
|
||||
frmHeapPointer[i].flags = flags;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DECL_FUNCTION(s32, MEMCreateUserHeapHandle, void* startAddress, u32 size) {
|
||||
s32 result = real_MEMCreateUserHeapHandle(startAddress,size);
|
||||
for(int i = 0; i<MAX_USER_HEAP_INFOS; i++) {
|
||||
if(userHeapInfos[i].handle == 0) {
|
||||
userHeapInfos[i].handle = result;
|
||||
userHeapInfos[i].address = startAddress;
|
||||
userHeapInfos[i].size = size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DECL_FUNCTION(s32, MEMCreateExpHeapEx, void* address, u32 size, u16 flags) {
|
||||
u32 oldSize = size;
|
||||
s32 result = 0;
|
||||
bool allocated = false;
|
||||
|
||||
/*
|
||||
real_MEMCreateExpHeapEx Just accepts ALL sizes... so.. well..
|
||||
if(size > 0x3B600000 && (u32) address < 0x11000000){
|
||||
//We are pretty sure this the MEM2 default heap.
|
||||
//Let's try to increase it's capacity.
|
||||
//u32 maximumSize = 0x50000000 - (u32) address;
|
||||
u32 maximumSize = 0x80000000;
|
||||
//u32 maximumSize = size + 0x500000;
|
||||
maximumSize -= 0x500000; // remove 5MB, just to leave at least _some_ space.
|
||||
|
||||
u32 curSizeTest = maximumSize;
|
||||
|
||||
do{
|
||||
if(curSizeTest < oldSize){
|
||||
break;
|
||||
}
|
||||
result = real_MEMCreateExpHeapEx(address,curSizeTest,flags);
|
||||
if(result == 0){ // On failure:
|
||||
maximumSize -= 0x100000; // reduce by 1MB and try again.
|
||||
}else{
|
||||
allocated = true;
|
||||
break;
|
||||
}
|
||||
}while(!allocated); // Until the allocation was successful, or we are below default size.
|
||||
}*/
|
||||
if(!allocated || result == 0) {
|
||||
result = real_MEMCreateExpHeapEx(address,size,flags);
|
||||
}
|
||||
|
||||
for(int i = 0; i<MAX_EXP_HEAP_INFOS; i++) {
|
||||
if(expHeapPointer[i].handle == 0) {
|
||||
expHeapPointer[i].handle = result;
|
||||
expHeapPointer[i].address = address;
|
||||
expHeapPointer[i].size = size;
|
||||
expHeapPointer[i].oldSize = oldSize;
|
||||
expHeapPointer[i].flags = flags;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DECL_FUNCTION(s32, MEMCreateUnitHeapEx, void* address, u32 heapSize, u32 memSize, u32 align, u16 flags) {
|
||||
s32 result = real_MEMCreateUnitHeapEx(address,heapSize,memSize,align,flags);
|
||||
|
||||
for(int i = 0; i<MAX_UNIT_HEAP_INFOS; i++) {
|
||||
if(unitHeapPointer[i].handle == 0) {
|
||||
unitHeapPointer[i].handle = result;
|
||||
unitHeapPointer[i].address = address;
|
||||
unitHeapPointer[i].heapSize = heapSize;
|
||||
unitHeapPointer[i].memSize = memSize;
|
||||
unitHeapPointer[i].align = align;
|
||||
unitHeapPointer[i].flags = flags;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DECL_FUNCTION(void *, MEMDestroyExpHeap, s32 heap) {
|
||||
void * result = real_MEMDestroyExpHeap(heap);
|
||||
|
||||
for(int i = 0; i<MAX_EXP_HEAP_INFOS; i++) {
|
||||
if(expHeapPointer[i].handle == heap) {
|
||||
expHeapPointer[i].handle = 0;
|
||||
expHeapPointer[i].address = 0;
|
||||
expHeapPointer[i].size = 0;
|
||||
expHeapPointer[i].flags = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DECL_FUNCTION(void *, MEMDestroyFrmHeap, s32 heap) {
|
||||
void * result = real_MEMDestroyFrmHeap(heap);
|
||||
|
||||
for(int i = 0; i<MAX_FRM_HEAP_INFOS; i++) {
|
||||
if(frmHeapPointer[i].handle == heap) {
|
||||
frmHeapPointer[i].handle = 0;
|
||||
frmHeapPointer[i].address = 0;
|
||||
frmHeapPointer[i].size = 0;
|
||||
frmHeapPointer[i].flags = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DECL_FUNCTION(void *, MEMDestroyUnitHeap, s32 heap) {
|
||||
void * result = real_MEMDestroyUnitHeap(heap);
|
||||
|
||||
for(int i = 0; i<MAX_UNIT_HEAP_INFOS; i++) {
|
||||
if(unitHeapPointer[i].handle == heap) {
|
||||
unitHeapPointer[i].handle = 0;
|
||||
unitHeapPointer[i].address = 0;
|
||||
unitHeapPointer[i].heapSize = 0;
|
||||
unitHeapPointer[i].memSize = 0;
|
||||
unitHeapPointer[i].align = 0;
|
||||
unitHeapPointer[i].flags = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DECL_FUNCTION(s32, MEMSetBaseHeapHandle, s32 arena, s32 heap) {
|
||||
s32 result = real_MEMSetBaseHeapHandle(arena,heap);
|
||||
for(int i = 0; i<MAX_BASE_HEAP_INFOS; i++) {
|
||||
if(baseHeaphandles[i].newHandle == 0) {
|
||||
baseHeaphandles[i].oldHandle = result;
|
||||
baseHeaphandles[i].newHandle = heap;
|
||||
baseHeaphandles[i].memArena = arena;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DECL_FUNCTION(s32, MEMInitBlockHeap,void * tracking, void * startAddress,void * endAddress, void * initTrackMemory, u32 initTrackMemoryBytes, u16 flags) {
|
||||
s32 result = real_MEMInitBlockHeap(tracking,startAddress,endAddress,initTrackMemory,initTrackMemoryBytes,flags);
|
||||
for(int i = 0; i<MAX_BLOCK_HEAP_INFOS; i++) {
|
||||
if(blockHeapInfos[i].startAddress == NULL) {
|
||||
blockHeapInfos[i].handle = result;
|
||||
blockHeapInfos[i].tracking = tracking;
|
||||
blockHeapInfos[i].startAddress = startAddress;
|
||||
blockHeapInfos[i].endAddress = endAddress;
|
||||
blockHeapInfos[i].initTrackMem = initTrackMemory;
|
||||
blockHeapInfos[i].initTrackMemBytes = initTrackMemoryBytes;
|
||||
blockHeapInfos[i].flags = flags;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
WUPS_MUST_REPLACE(MEMInitBlockHeap, WUPS_LOADER_LIBRARY_COREINIT, MEMInitBlockHeap);
|
||||
WUPS_MUST_REPLACE(MEMSetBaseHeapHandle, WUPS_LOADER_LIBRARY_COREINIT, MEMSetBaseHeapHandle);
|
||||
WUPS_MUST_REPLACE(MEMDestroyUnitHeap, WUPS_LOADER_LIBRARY_COREINIT, MEMDestroyUnitHeap);
|
||||
WUPS_MUST_REPLACE(MEMDestroyFrmHeap, WUPS_LOADER_LIBRARY_COREINIT, MEMDestroyFrmHeap);
|
||||
WUPS_MUST_REPLACE(MEMDestroyExpHeap, WUPS_LOADER_LIBRARY_COREINIT, MEMDestroyExpHeap);
|
||||
WUPS_MUST_REPLACE(MEMCreateUnitHeapEx, WUPS_LOADER_LIBRARY_COREINIT, MEMCreateUnitHeapEx);
|
||||
WUPS_MUST_REPLACE(MEMCreateExpHeapEx, WUPS_LOADER_LIBRARY_COREINIT, MEMCreateExpHeapEx);
|
||||
WUPS_MUST_REPLACE(MEMCreateUserHeapHandle, WUPS_LOADER_LIBRARY_COREINIT, MEMCreateUserHeapHandle);
|
||||
WUPS_MUST_REPLACE(MEMCreateFrmHeapEx, WUPS_LOADER_LIBRARY_COREINIT, MEMCreateFrmHeapEx);
|
||||
|
||||
/*
|
||||
Unused stuff that might get useful in the future.
|
||||
|
||||
void * allocateFromExpHeap(s32 * usedHandle, u32 size, u32 align){
|
||||
void * result = NULL;
|
||||
for(int i = 0;i<MAX_EXP_HEAP_INFOS;i++){
|
||||
if(expHeapPointer[i].handle != 0){
|
||||
result = MEMAllocFromExpHeapEx(expHeapPointer[i].handle, size, align);
|
||||
if(result != NULL){
|
||||
*usedHandle = expHeapPointer[i].handle;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void * allocateFromFrmHeap(s32 * usedHandle, u32 size, u32 align){
|
||||
void * result = NULL;
|
||||
for(int i = 0;i<MAX_FRM_HEAP_INFOS;i++){
|
||||
if(frmHeapPointer[i].handle != 0){
|
||||
result = MEMAllocFromFrmHeapEx(frmHeapPointer[i].handle, size, align);
|
||||
if(result != NULL){
|
||||
*usedHandle = frmHeapPointer[i].handle;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void freeToExpHeap(s32 usedHandle, void * addr){
|
||||
MEMFreeToExpHeap(usedHandle, addr);
|
||||
}
|
||||
allocatorExpInfo allocatorExpPointer[MAX_ALLOCATOR_EXP_INFOS] __attribute__((section(".data")));
|
||||
|
||||
typedef struct allocatorExpInfo_{
|
||||
void * allocator;
|
||||
s32 heap;
|
||||
s32 align;
|
||||
} allocatorExpInfo;
|
||||
|
||||
DECL(void , MEMInitAllocatorForExpHeap, void* allocator, s32 heap, s32 align){
|
||||
for(int i = 0;i<MAX_ALLOCATOR_EXP_INFOS;i++){
|
||||
if(allocatorExpPointer[i].allocator == 0){
|
||||
allocatorExpPointer[i].allocator = (void*)allocator;
|
||||
allocatorExpPointer[i].heap = heap;
|
||||
allocatorExpPointer[i].align = align;
|
||||
break;
|
||||
}
|
||||
}
|
||||
real_MEMInitAllocatorForExpHeap(allocator,heap,align);
|
||||
return;
|
||||
}
|
||||
*/
|
Loading…
Reference in New Issue
Block a user