From 2705a91c13e53dcbd7dd79f70bd14a672004448a Mon Sep 17 00:00:00 2001 From: Maschell Date: Wed, 29 Apr 2020 18:02:36 +0200 Subject: [PATCH] First iteration of the WUPS-Backend as a .rpx/module for the SetupPayload - Function replacements are not implemented yet - Serveral features like the config menu are missing Still WIP --- .gitignore | 11 +- Makefile | 198 +- README.md | 7 +- .../common}/dynamic_linking_defines.h | 21 +- source/common/module_defines.h | 58 + source/common/plugin_defines.h | 95 + source/common/relocation_defines.h | 20 + source/common/replacement_defines.h | 25 + source/crt0.s | 29 + source/elfio/elf_types.hpp | 851 ++++ source/elfio/elfio.hpp | 932 +++++ source/elfio/elfio_dump.hpp | 976 +++++ source/elfio/elfio_dynamic.hpp | 257 ++ source/elfio/elfio_header.hpp | 145 + source/elfio/elfio_note.hpp | 170 + source/elfio/elfio_relocation.hpp | 333 ++ source/elfio/elfio_section.hpp | 360 ++ source/elfio/elfio_segment.hpp | 246 ++ source/elfio/elfio_strings.hpp | 100 + source/elfio/elfio_symbols.hpp | 282 ++ source/elfio/elfio_utils.hpp | 209 + source/hooks.cpp | 103 + source/hooks.h | 7 + src/kernel/kernel.S => source/kernel/kernel.s | 10 +- {src => source}/kernel/kernel_defs.h | 7 + source/kernel/kernel_utils.c | 91 + {src => source}/kernel/kernel_utils.h | 0 source/main.cpp | 192 + {src => source}/patcher/hooks_patcher.cpp | 0 {src => source}/patcher/hooks_patcher.h | 0 .../patcher/hooks_patcher_static.cpp | 145 +- .../patcher/hooks_patcher_static.h | 0 source/plugin/DynamicLinkingHelper.cpp | 104 + {src => source}/plugin/DynamicLinkingHelper.h | 52 +- {src => source}/plugin/FunctionData.h | 26 +- {src => source}/plugin/HookData.h | 12 +- .../plugin/ImportRPLInformation.h | 37 +- source/plugin/PluginContainer.h | 56 + source/plugin/PluginContainerPersistence.cpp | 296 ++ source/plugin/PluginContainerPersistence.h | 10 + source/plugin/PluginData.cpp | 76 + source/plugin/PluginData.h | 68 + source/plugin/PluginDataFactory.cpp | 112 + .../plugin/PluginDataFactory.h | 32 +- source/plugin/PluginInformation.h | 95 + source/plugin/PluginInformationFactory.cpp | 349 ++ source/plugin/PluginInformationFactory.h | 35 + source/plugin/PluginMetaInformation.h | 96 + .../plugin/PluginMetaInformationFactory.cpp | 108 + .../plugin/PluginMetaInformationFactory.h | 25 +- {src => source}/plugin/RelocationData.h | 51 +- .../CMutex.h => source/plugin/SectionInfo.h | 78 +- source/utils/ElfUtils.cpp | 159 + source/utils/ElfUtils.h | 50 + {src => source}/utils/StringTools.cpp | 48 +- source/utils/StringTools.h | 80 + {src => source}/utils/function_patcher.h | 4 +- {src => source}/utils/function_patcher_.cpp | 184 +- {src => source}/utils/logger.c | 39 +- {src => source}/utils/logger.h | 18 +- src/utils/_utils.c => source/utils/utils.c | 3 +- source/utils/utils.h | 40 + src/common/retain_vars.cpp | 24 - src/common/retain_vars.h | 32 - src/dynamic_libs/coreinit.c | 166 - src/dynamic_libs/coreinit.h | 253 -- src/dynamic_libs/fs_defs.h | 93 - src/dynamic_libs/fs_functions.c | 141 - src/dynamic_libs/fs_functions.h | 99 - src/dynamic_libs/gx2_functions.c | 187 - src/dynamic_libs/gx2_functions.h | 213 - src/dynamic_libs/gx2_types.h | 696 ---- src/dynamic_libs/socket_functions.c | 118 - src/dynamic_libs/socket_functions.h | 124 - src/dynamic_libs/vpad_functions.c | 170 - src/dynamic_libs/vpad_functions.h | 207 - src/entry.cpp | 276 -- src/fs/CFile.cpp | 174 - src/fs/CFile.hpp | 61 - src/fs/DirList.cpp | 212 - src/fs/DirList.h | 103 - src/fs/FSOSUtils.cpp | 56 - src/fs/FSOSUtils.h | 13 - src/fs/FSUtils.cpp | 144 - src/fs/FSUtils.h | 15 - src/fs/disc_io.h | 67 - src/fs/sd_fat_devoptab.cpp | 1035 ----- src/fs/sd_fat_devoptab.h | 40 - src/kernel/kernel_utils.c | 204 - src/kernel_hooks.S | 29 - src/libelf/_elftc.h | 430 -- src/libelf/_libelf.h | 223 -- src/libelf/_libelf_ar.h | 56 - src/libelf/_libelf_config.h | 193 - src/libelf/elf.c | 40 - src/libelf/elf_begin.c | 91 - src/libelf/elf_cntl.c | 58 - src/libelf/elf_data.c | 254 -- src/libelf/elf_end.c | 97 - src/libelf/elf_errmsg.c | 85 - src/libelf/elf_errno.c | 43 - src/libelf/elf_fill.c | 39 - src/libelf/elf_flag.c | 198 - src/libelf/elf_getarhdr.c | 47 - src/libelf/elf_getarsym.c | 58 - src/libelf/elf_getbase.c | 48 - src/libelf/elf_getident.c | 68 - src/libelf/elf_hash.c | 56 - src/libelf/elf_kind.c | 44 - src/libelf/elf_memory.c | 47 - src/libelf/elf_next.c | 62 - src/libelf/elf_open.c | 67 - src/libelf/elf_phnum.c | 67 - src/libelf/elf_rand.c | 59 - src/libelf/elf_rawfile.c | 53 - src/libelf/elf_scn.c | 233 -- src/libelf/elf_shnum.c | 67 - src/libelf/elf_shstrndx.c | 82 - src/libelf/elf_strptr.c | 132 - src/libelf/elf_update.c | 1204 ------ src/libelf/elf_version.c | 52 - src/libelf/elfdefinitions.h | 2560 ------------ src/libelf/gelf.h | 106 - src/libelf/gelf_cap.c | 151 - src/libelf/gelf_checksum.c | 58 - src/libelf/gelf_dyn.c | 150 - src/libelf/gelf_ehdr.c | 168 - src/libelf/gelf_fsize.c | 62 - src/libelf/gelf_getclass.c | 39 - src/libelf/gelf_move.c | 157 - src/libelf/gelf_phdr.c | 178 - src/libelf/gelf_rel.c | 159 - src/libelf/gelf_rela.c | 162 - src/libelf/gelf_shdr.c | 131 - src/libelf/gelf_sym.c | 160 - src/libelf/gelf_syminfo.c | 151 - src/libelf/gelf_symshndx.c | 136 - src/libelf/gelf_xlate.c | 81 - src/libelf/libelf.h | 250 -- src/libelf/libelf_align.c | 137 - src/libelf/libelf_allocate.c | 212 - src/libelf/libelf_ar.c | 461 --- src/libelf/libelf_ar_util.c | 359 -- src/libelf/libelf_checksum.c | 100 - src/libelf/libelf_convert.c | 3465 ----------------- src/libelf/libelf_data.c | 88 - src/libelf/libelf_ehdr.c | 204 - src/libelf/libelf_extended.c | 136 - src/libelf/libelf_fsize.c | 197 - src/libelf/libelf_memory.c | 96 - src/libelf/libelf_msize.c | 196 - src/libelf/libelf_open.c | 240 -- src/libelf/libelf_phdr.c | 156 - src/libelf/libelf_shdr.c | 56 - src/libelf/libelf_xlate.c | 150 - src/link.ld | 33 - src/memory/memory.cpp | 137 - src/memory/memory_mapping.cpp | 770 ---- src/memory/memory_mapping.h | 207 - src/patcher/function_patcher.cpp | 394 -- src/patcher/function_patcher.h | 102 - src/plugin/DynamicLinkingHelper.cpp | 207 - src/plugin/ElfTools.cpp | 501 --- src/plugin/ElfTools.h | 52 - src/plugin/ImportRPLInformation.h | 79 - src/plugin/PluginData.cpp | 43 - src/plugin/PluginData.h | 165 - src/plugin/PluginInformation.cpp | 424 -- src/plugin/PluginInformation.h | 151 - src/plugin/PluginLoader.cpp | 544 --- src/plugin/PluginLoader.h | 180 - src/settings/ConfigSettings.cpp | 260 -- src/settings/ConfigSettings.h | 246 -- src/system/CThread.h | 141 - src/utils.cpp | 166 - src/utils.h | 21 - src/utils/ConfigInformation.cpp | 117 - src/utils/ConfigInformation.h | 61 - src/utils/ConfigUtils.cpp | 399 -- src/utils/ConfigUtils.h | 87 - src/utils/ScreenUtils.cpp | 71 - src/utils/ScreenUtils.h | 50 - src/utils/StringTools.h | 82 - src/utils/ipc.cpp | 291 -- src/utils/ipc.h | 58 - src/utils/overlay_helper.cpp | 174 - src/utils/overlay_helper.h | 24 - src/utils/utils.h | 51 - 188 files changed, 7644 insertions(+), 27184 deletions(-) rename {src/plugin => source/common}/dynamic_linking_defines.h (79%) create mode 100644 source/common/module_defines.h create mode 100644 source/common/plugin_defines.h create mode 100644 source/common/relocation_defines.h create mode 100644 source/common/replacement_defines.h create mode 100644 source/crt0.s create mode 100644 source/elfio/elf_types.hpp create mode 100644 source/elfio/elfio.hpp create mode 100644 source/elfio/elfio_dump.hpp create mode 100644 source/elfio/elfio_dynamic.hpp create mode 100644 source/elfio/elfio_header.hpp create mode 100644 source/elfio/elfio_note.hpp create mode 100644 source/elfio/elfio_relocation.hpp create mode 100644 source/elfio/elfio_section.hpp create mode 100644 source/elfio/elfio_segment.hpp create mode 100644 source/elfio/elfio_strings.hpp create mode 100644 source/elfio/elfio_symbols.hpp create mode 100644 source/elfio/elfio_utils.hpp create mode 100644 source/hooks.cpp create mode 100644 source/hooks.h rename src/kernel/kernel.S => source/kernel/kernel.s (92%) rename {src => source}/kernel/kernel_defs.h (62%) create mode 100644 source/kernel/kernel_utils.c rename {src => source}/kernel/kernel_utils.h (100%) create mode 100644 source/main.cpp rename {src => source}/patcher/hooks_patcher.cpp (100%) rename {src => source}/patcher/hooks_patcher.h (100%) rename {src => source}/patcher/hooks_patcher_static.cpp (66%) rename {src => source}/patcher/hooks_patcher_static.h (100%) create mode 100644 source/plugin/DynamicLinkingHelper.cpp rename {src => source}/plugin/DynamicLinkingHelper.h (55%) rename {src => source}/plugin/FunctionData.h (72%) rename {src => source}/plugin/HookData.h (88%) rename src/memory/memory.h => source/plugin/ImportRPLInformation.h (63%) create mode 100644 source/plugin/PluginContainer.h create mode 100644 source/plugin/PluginContainerPersistence.cpp create mode 100644 source/plugin/PluginContainerPersistence.h create mode 100644 source/plugin/PluginData.cpp create mode 100644 source/plugin/PluginData.h create mode 100644 source/plugin/PluginDataFactory.cpp rename src/utils/mem_utils.cpp => source/plugin/PluginDataFactory.h (56%) create mode 100644 source/plugin/PluginInformation.h create mode 100644 source/plugin/PluginInformationFactory.cpp create mode 100644 source/plugin/PluginInformationFactory.h create mode 100644 source/plugin/PluginMetaInformation.h create mode 100644 source/plugin/PluginMetaInformationFactory.cpp rename src/utils/mem_utils.h => source/plugin/PluginMetaInformationFactory.h (73%) rename {src => source}/plugin/RelocationData.h (58%) rename src/system/CMutex.h => source/plugin/SectionInfo.h (52%) create mode 100644 source/utils/ElfUtils.cpp create mode 100644 source/utils/ElfUtils.h rename {src => source}/utils/StringTools.cpp (86%) create mode 100644 source/utils/StringTools.h rename {src => source}/utils/function_patcher.h (97%) rename {src => source}/utils/function_patcher_.cpp (78%) rename {src => source}/utils/logger.c (73%) rename {src => source}/utils/logger.h (63%) rename src/utils/_utils.c => source/utils/utils.c (96%) create mode 100644 source/utils/utils.h delete mode 100644 src/common/retain_vars.cpp delete mode 100644 src/common/retain_vars.h delete mode 100644 src/dynamic_libs/coreinit.c delete mode 100644 src/dynamic_libs/coreinit.h delete mode 100644 src/dynamic_libs/fs_defs.h delete mode 100644 src/dynamic_libs/fs_functions.c delete mode 100644 src/dynamic_libs/fs_functions.h delete mode 100644 src/dynamic_libs/gx2_functions.c delete mode 100644 src/dynamic_libs/gx2_functions.h delete mode 100644 src/dynamic_libs/gx2_types.h delete mode 100644 src/dynamic_libs/socket_functions.c delete mode 100644 src/dynamic_libs/socket_functions.h delete mode 100644 src/dynamic_libs/vpad_functions.c delete mode 100644 src/dynamic_libs/vpad_functions.h delete mode 100644 src/entry.cpp delete mode 100644 src/fs/CFile.cpp delete mode 100644 src/fs/CFile.hpp delete mode 100644 src/fs/DirList.cpp delete mode 100644 src/fs/DirList.h delete mode 100644 src/fs/FSOSUtils.cpp delete mode 100644 src/fs/FSOSUtils.h delete mode 100644 src/fs/FSUtils.cpp delete mode 100644 src/fs/FSUtils.h delete mode 100644 src/fs/disc_io.h delete mode 100644 src/fs/sd_fat_devoptab.cpp delete mode 100644 src/fs/sd_fat_devoptab.h delete mode 100644 src/kernel/kernel_utils.c delete mode 100644 src/kernel_hooks.S delete mode 100644 src/libelf/_elftc.h delete mode 100644 src/libelf/_libelf.h delete mode 100644 src/libelf/_libelf_ar.h delete mode 100644 src/libelf/_libelf_config.h delete mode 100644 src/libelf/elf.c delete mode 100644 src/libelf/elf_begin.c delete mode 100644 src/libelf/elf_cntl.c delete mode 100644 src/libelf/elf_data.c delete mode 100644 src/libelf/elf_end.c delete mode 100644 src/libelf/elf_errmsg.c delete mode 100644 src/libelf/elf_errno.c delete mode 100644 src/libelf/elf_fill.c delete mode 100644 src/libelf/elf_flag.c delete mode 100644 src/libelf/elf_getarhdr.c delete mode 100644 src/libelf/elf_getarsym.c delete mode 100644 src/libelf/elf_getbase.c delete mode 100644 src/libelf/elf_getident.c delete mode 100644 src/libelf/elf_hash.c delete mode 100644 src/libelf/elf_kind.c delete mode 100644 src/libelf/elf_memory.c delete mode 100644 src/libelf/elf_next.c delete mode 100644 src/libelf/elf_open.c delete mode 100644 src/libelf/elf_phnum.c delete mode 100644 src/libelf/elf_rand.c delete mode 100644 src/libelf/elf_rawfile.c delete mode 100644 src/libelf/elf_scn.c delete mode 100644 src/libelf/elf_shnum.c delete mode 100644 src/libelf/elf_shstrndx.c delete mode 100644 src/libelf/elf_strptr.c delete mode 100644 src/libelf/elf_update.c delete mode 100644 src/libelf/elf_version.c delete mode 100644 src/libelf/elfdefinitions.h delete mode 100644 src/libelf/gelf.h delete mode 100644 src/libelf/gelf_cap.c delete mode 100644 src/libelf/gelf_checksum.c delete mode 100644 src/libelf/gelf_dyn.c delete mode 100644 src/libelf/gelf_ehdr.c delete mode 100644 src/libelf/gelf_fsize.c delete mode 100644 src/libelf/gelf_getclass.c delete mode 100644 src/libelf/gelf_move.c delete mode 100644 src/libelf/gelf_phdr.c delete mode 100644 src/libelf/gelf_rel.c delete mode 100644 src/libelf/gelf_rela.c delete mode 100644 src/libelf/gelf_shdr.c delete mode 100644 src/libelf/gelf_sym.c delete mode 100644 src/libelf/gelf_syminfo.c delete mode 100644 src/libelf/gelf_symshndx.c delete mode 100644 src/libelf/gelf_xlate.c delete mode 100644 src/libelf/libelf.h delete mode 100644 src/libelf/libelf_align.c delete mode 100644 src/libelf/libelf_allocate.c delete mode 100644 src/libelf/libelf_ar.c delete mode 100644 src/libelf/libelf_ar_util.c delete mode 100644 src/libelf/libelf_checksum.c delete mode 100644 src/libelf/libelf_convert.c delete mode 100644 src/libelf/libelf_data.c delete mode 100644 src/libelf/libelf_ehdr.c delete mode 100644 src/libelf/libelf_extended.c delete mode 100644 src/libelf/libelf_fsize.c delete mode 100644 src/libelf/libelf_memory.c delete mode 100644 src/libelf/libelf_msize.c delete mode 100644 src/libelf/libelf_open.c delete mode 100644 src/libelf/libelf_phdr.c delete mode 100644 src/libelf/libelf_shdr.c delete mode 100644 src/libelf/libelf_xlate.c delete mode 100644 src/link.ld delete mode 100644 src/memory/memory.cpp delete mode 100644 src/memory/memory_mapping.cpp delete mode 100644 src/memory/memory_mapping.h delete mode 100644 src/patcher/function_patcher.cpp delete mode 100644 src/patcher/function_patcher.h delete mode 100644 src/plugin/DynamicLinkingHelper.cpp delete mode 100644 src/plugin/ElfTools.cpp delete mode 100644 src/plugin/ElfTools.h delete mode 100644 src/plugin/ImportRPLInformation.h delete mode 100644 src/plugin/PluginData.cpp delete mode 100644 src/plugin/PluginData.h delete mode 100644 src/plugin/PluginInformation.cpp delete mode 100644 src/plugin/PluginInformation.h delete mode 100644 src/plugin/PluginLoader.cpp delete mode 100644 src/plugin/PluginLoader.h delete mode 100644 src/settings/ConfigSettings.cpp delete mode 100644 src/settings/ConfigSettings.h delete mode 100644 src/system/CThread.h delete mode 100644 src/utils.cpp delete mode 100644 src/utils.h delete mode 100644 src/utils/ConfigInformation.cpp delete mode 100644 src/utils/ConfigInformation.h delete mode 100644 src/utils/ConfigUtils.cpp delete mode 100644 src/utils/ConfigUtils.h delete mode 100644 src/utils/ScreenUtils.cpp delete mode 100644 src/utils/ScreenUtils.h delete mode 100644 src/utils/StringTools.h delete mode 100644 src/utils/ipc.cpp delete mode 100644 src/utils/ipc.h delete mode 100644 src/utils/overlay_helper.cpp delete mode 100644 src/utils/overlay_helper.h delete mode 100644 src/utils/utils.h diff --git a/.gitignore b/.gitignore index caef985..1bc8861 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ -*.elf -*.rpx -*.bin -hook.h -build/ *.cbp -WiiUPluginLoaderBackend.layout +*.elf +*.layout +*.rpx +build/ +*.save-failed diff --git a/Makefile b/Makefile index 64d2bed..5826cc4 100644 --- a/Makefile +++ b/Makefile @@ -3,19 +3,14 @@ #------------------------------------------------------------------------------- ifeq ($(strip $(DEVKITPRO)),) -$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=/devkitPro") -endif - -ifeq ($(strip $(DEVKITPPC)),) -$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=/devkitPro/devkitPPC") +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=/devkitpro") endif TOPDIR ?= $(CURDIR) -include $(DEVKITPPC)/base_rules - -MACHDEP = -DESPRESSO -mcpu=750 -meabi -mhard-float +include $(DEVKITPRO)/wut/share/wut_rules +WUPS_ROOT := $(DEVKITPRO)/wups #------------------------------------------------------------------------------- # TARGET is the name of the output # BUILD is the directory where object files & intermediate files will be placed @@ -23,160 +18,129 @@ MACHDEP = -DESPRESSO -mcpu=750 -meabi -mhard-float # DATA is a list of directories containing data files # INCLUDES is a list of directories containing header files #------------------------------------------------------------------------------- -TARGET := hook_payload +TARGET := PluginBackend BUILD := build -BUILD_DBG := $(TARGET)_dbg -SOURCES := src \ - src/common \ - src/libelf \ - src/fs \ - src/dynamic_libs \ - src/kernel \ - src/memory \ - src/plugin \ - src/patcher \ - src/settings \ - src/system \ - src/utils - +SOURCES := source \ + source/elfio \ + source/kernel \ + source/patcher \ + source/plugin \ + source/utils DATA := data -INCLUDES := src \ - src/libelf +INCLUDES := source #------------------------------------------------------------------------------- # options for code generation #------------------------------------------------------------------------------- -CFLAGS := -g -Wall -O0 -ffunction-sections \ +CFLAGS := -g -Wall -O0 -ffunction-sections -std=c++17 \ $(MACHDEP) -CFLAGS += $(INCLUDE) -D__WIIU__ -D_GNU_SOURCE +CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__ CXXFLAGS := $(CFLAGS) -ASFLAGS := -g -mregnames $(ARCH) -LDFLAGS = -g $(ARCH) -nostartfiles -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,-wrap,valloc,-wrap,_valloc_r,-wrap,_pvalloc_r,--gc-sections +ASFLAGS := -g $(ARCH) +LDFLAGS = -g $(ARCH) $(RPXSPECS) --entry=_start -Wl,-Map,$(notdir $*.map) -LIBS := +LIBS := -lwut -lwups #------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level # containing include and lib #------------------------------------------------------------------------------- -LIBDIRS := $(DEVKITPRO)/wups +LIBDIRS := $(PORTLIBS) $(WUT_ROOT) $(WUPS_ROOT) -#--------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- # 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 := $(CC) -else - export LD := $(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) - -#--------------------------------------------------------------------------------- -# build a list of library paths -#--------------------------------------------------------------------------------- -export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) +#------------------------------------------------------------------------------- export OUTPUT := $(CURDIR)/$(TARGET) -.PHONY: $(BUILD) clean install +export TOPDIR := $(CURDIR) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#------------------------------------------------------------------------------- + export LD := $(CC) +#------------------------------------------------------------------------------- +else +#------------------------------------------------------------------------------- + export LD := $(CXX) +#------------------------------------------------------------------------------- +endif +#------------------------------------------------------------------------------- + +export OFILES_BIN := $(addsuffix .o,$(BINFILES)) +export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) +export OFILES := $(OFILES_BIN) $(OFILES_SRC) +export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES))) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +.PHONY: $(BUILD) clean all + +#------------------------------------------------------------------------------- +all: $(BUILD) -#--------------------------------------------------------------------------------- $(BUILD): @[ -d $@ ] || mkdir -p $@ @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile -#--------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- clean: - @rm -fr $(BUILD) $(OUTPUT).elf $(BUILD_DBG).elf + @echo clean ... + @rm -fr $(BUILD) $(TARGET).rpx $(TARGET).elf -#--------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- else +.PHONY: all DEPENDS := $(OFILES:.o=.d) -#--------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- # main targets -#--------------------------------------------------------------------------------- -$(OUTPUT).elf: $(OFILES) +#------------------------------------------------------------------------------- +all : $(OUTPUT).rpx -#--------------------------------------------------------------------------------- -# This rule links in binary data with the .jpg extension -#--------------------------------------------------------------------------------- -%.elf: link.ld $(OFILES) - @echo "linking ... $(TARGET).elf" - @$(LD) -n -T $^ $(LDFLAGS) -o ../$(BUILD_DBG).elf $(LIBPATHS) $(LIBS) - @$(OBJCOPY) -S -R .comment -R .gnu.attributes ../$(BUILD_DBG).elf $@ +$(OUTPUT).rpx : $(OUTPUT).elf +$(OUTPUT).elf : $(OFILES) -#--------------------------------------------------------------------------------- -%.a: -#--------------------------------------------------------------------------------- - @echo $(notdir $@) - @rm -f $@ - @$(AR) -rc $@ $^ +$(OFILES_SRC) : $(HFILES_BIN) -#--------------------------------------------------------------------------------- -%.o: %.cpp +#------------------------------------------------------------------------------- +# you need a rule like this for each extension you use as binary data +#------------------------------------------------------------------------------- +%.bin.o %_bin.h : %.bin +#------------------------------------------------------------------------------- @echo $(notdir $<) - @$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER) + @$(bin2o) #--------------------------------------------------------------------------------- -%.o: %.c - @echo $(notdir $<) - @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(CFLAGS) -c $< -o $@ $(ERROR_FILTER) - -#--------------------------------------------------------------------------------- -%.o: %.S +%.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 $(@) - -#--------------------------------------------------------------------------------- -%.ttf.o : %.ttf - @echo $(notdir $<) - @bin2s -a 32 $< | $(AS) -o $(@) - -include $(DEPENDS) -#--------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- endif -#--------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- diff --git a/README.md b/README.md index 96607d0..7ff4751 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This is the Backend for the [WiiUPluginSystem](https://github.com/Maschell/WiiUPluginSystem). Check out the readme for more information about the Plugin System. ## Usage -Put the `hook_payload.elf` in the `sd:/wiiu` folder of your sd card and load it via the [SystemMenuHook](https://github.com/wiiu-env/SystemMenuHook). +Put the `PluginBackend.rpx` in the `sd:/wiiu/modules` folder of your sd card and load it via the [SetupPayload](https://github.com/wiiu-env/SetupPayload). Plugins needs to be placed into the following folder: @@ -35,5 +35,6 @@ DEVKITPPC=/opt/devkitpro/devkitPPC # Credits -Maschell -orboditilt \ No newline at end of file +- Maschell +- orboditilt +- https://github.com/serge1/ELFIO \ No newline at end of file diff --git a/src/plugin/dynamic_linking_defines.h b/source/common/dynamic_linking_defines.h similarity index 79% rename from src/plugin/dynamic_linking_defines.h rename to source/common/dynamic_linking_defines.h index 9522fd6..2a87d80 100644 --- a/src/plugin/dynamic_linking_defines.h +++ b/source/common/dynamic_linking_defines.h @@ -15,33 +15,31 @@ * along with this program. If not, see . ****************************************************************************/ -#ifndef _DYNAMIC_LINKING_DEFINES_H_ -#define _DYNAMIC_LINKING_DEFINES_H_ +#pragma once + +#include +#include #ifdef __cplusplus extern "C" { #endif -#include -#include - -#define DYN_LINK_FUNCTION_NAME_LENGTH 255 -#define DYN_LINK_IMPORT_NAME_LENGTH 150 +#define DYN_LINK_FUNCTION_NAME_LENGTH 351 +#define DYN_LINK_IMPORT_NAME_LENGTH 50 #define DYN_LINK_FUNCTION_LIST_LENGTH 500 #define DYN_LINK_IMPORT_LIST_LENGTH 50 -#define DYN_LINK_RELOCATION_LIST_LENGTH 5000 + +#define DYN_LINK_TRAMPOLIN_LIST_LENGTH DYN_LINK_FUNCTION_LIST_LENGTH typedef struct _dyn_linking_function_t { char functionName[DYN_LINK_FUNCTION_NAME_LENGTH+1]; void * address; - uint32_t big_jump[6]; } dyn_linking_function_t; typedef struct _dyn_linking_import_t { char importName[DYN_LINK_IMPORT_NAME_LENGTH+1]; bool isData = false; - uint32_t handle = 0; } dyn_linking_import_t; typedef struct _dyn_linking_relocation_entry_t { @@ -54,7 +52,6 @@ typedef struct _dyn_linking_relocation_entry_t { } dyn_linking_relocation_entry_t; typedef struct _dyn_linking_relocation_data_t { - dyn_linking_relocation_entry_t entries[DYN_LINK_RELOCATION_LIST_LENGTH]; dyn_linking_function_t functions[DYN_LINK_FUNCTION_LIST_LENGTH]; dyn_linking_import_t imports[DYN_LINK_IMPORT_LIST_LENGTH]; } dyn_linking_relocation_data_t; @@ -62,5 +59,3 @@ typedef struct _dyn_linking_relocation_data_t { #ifdef __cplusplus } #endif - -#endif /* _DYNAMIC_LINKING_DEFINES_H_ */ diff --git a/source/common/module_defines.h b/source/common/module_defines.h new file mode 100644 index 0000000..f44fe89 --- /dev/null +++ b/source/common/module_defines.h @@ -0,0 +1,58 @@ +/**************************************************************************** + * Copyright (C) 2018-2019 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 . + ****************************************************************************/ + +#pragma once + +#include +#include +#include "dynamic_linking_defines.h" +#include "relocation_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAXIMUM_MODULE_PATH_NAME_LENGTH 256 +#define MAXIMUM_MODULE_NAME_LENGTH 51 + +#define DYN_LINK_RELOCATION_LIST_LENGTH 500 + +struct module_information_single_t { + char path[MAXIMUM_MODULE_PATH_NAME_LENGTH] = ""; // Path where the module is stored + dyn_linking_relocation_entry_t linking_entries[DYN_LINK_RELOCATION_LIST_LENGTH]; + int32_t priority; // Priority of this module + uint32_t bssAddr; + uint32_t bssSize; + uint32_t sbssAddr; + uint32_t sbssSize; + uint32_t entrypoint; + uint32_t startAddress; + uint32_t endAddress; +}; + +#define MAXIMUM_MODULES 8 + +struct module_information_t { + int32_t number_used_modules = 0; // Number of used function. Maximum is MAXIMUM_MODULES + dyn_linking_relocation_data_t linking_data; + relocation_trampolin_entry_t trampolines[DYN_LINK_TRAMPOLIN_LIST_LENGTH]; + module_information_single_t module_data[MAXIMUM_MODULES]; +}; + +#ifdef __cplusplus +} +#endif diff --git a/source/common/plugin_defines.h b/source/common/plugin_defines.h new file mode 100644 index 0000000..b373e64 --- /dev/null +++ b/source/common/plugin_defines.h @@ -0,0 +1,95 @@ +/**************************************************************************** + * Copyright (C) 2018-2019 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 . + ****************************************************************************/ + +#pragma once + +#include +#include +#include "dynamic_linking_defines.h" +#include "relocation_defines.h" +#include "replacement_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAXIMUM_PLUGIN_SECTION_LENGTH 10 +#define MAXIMUM_PLUGIN_SECTION_NAME_LENGTH 20 + +#define MAXIMUM_PLUGIN_PATH_NAME_LENGTH 256 +#define MAXIMUM_PLUGIN_NAME_LENGTH 51 +#define MAXIMUM_PLUGIN_DESCRIPTION_LENGTH 255 +#define MAXIMUM_PLUGIN_META_FIELD_LENGTH 51 + +#define DYN_LINK_RELOCATION_LIST_LENGTH 500 + +#define MAXIMUM_HOOKS_PER_PLUGIN 25 +#define MAXIMUM_FUNCTION_PER_PLUGIN 100 + +struct plugin_section_info_t { + char name[MAXIMUM_PLUGIN_SECTION_NAME_LENGTH] = ""; + uint32_t addr; + uint32_t size; +}; + +struct plugin_meta_info_t { + char name[MAXIMUM_PLUGIN_META_FIELD_LENGTH] = ""; + char author[MAXIMUM_PLUGIN_META_FIELD_LENGTH] = ""; + char version[MAXIMUM_PLUGIN_META_FIELD_LENGTH] = ""; + char license[MAXIMUM_PLUGIN_META_FIELD_LENGTH] = ""; + char buildTimestamp[MAXIMUM_PLUGIN_META_FIELD_LENGTH] = ""; + char descripion[MAXIMUM_PLUGIN_DESCRIPTION_LENGTH] = ""; + uint32_t size; +}; + +struct plugin_info_t { + dyn_linking_relocation_entry_t linking_entries[DYN_LINK_RELOCATION_LIST_LENGTH]; + plugin_section_info_t sectionInfos[MAXIMUM_PLUGIN_SECTION_LENGTH]; + uint32_t number_used_functions; // Number of used function. Maximum is MAXIMUM_FUNCTION_PER_PLUGIN + replacement_data_function_t functions[MAXIMUM_FUNCTION_PER_PLUGIN]; // Replacement information for each function. + uint32_t number_used_hooks; // Number of used hooks. Maximum is MAXIMUM_HOOKS_PER_PLUGIN + replacement_data_hook_t hooks[MAXIMUM_HOOKS_PER_PLUGIN]; // Replacement information for each function. + uint8_t trampolinId; +}; + +struct plugin_data_t { + char * buffer = NULL; + size_t bufferLength = 0; + int memoryType = 0; + int heapHandle = 0; +}; + +struct plugin_information_single_t { + plugin_meta_info_t meta; + plugin_info_t info; + plugin_data_t data; + int32_t priority; // Priority of this plugin + +}; + +#define MAXIMUM_PLUGINS 32 + +struct plugin_information_t { + int32_t number_used_plugins = 0; // Number of used plugins. Maximum is MAXIMUM_PLUGINS + plugin_information_single_t plugin_data[MAXIMUM_PLUGINS]; + relocation_trampolin_entry_t trampolines[DYN_LINK_TRAMPOLIN_LIST_LENGTH]; + dyn_linking_relocation_data_t linking_data; // RPL and function name list +}; + +#ifdef __cplusplus +} +#endif diff --git a/source/common/relocation_defines.h b/source/common/relocation_defines.h new file mode 100644 index 0000000..5efdf79 --- /dev/null +++ b/source/common/relocation_defines.h @@ -0,0 +1,20 @@ +#pragma once +#include + +typedef enum RelocationTrampolinStatus{ + RELOC_TRAMP_FREE = 0, + RELOC_TRAMP_FIXED = 1, + RELOC_TRAMP_IMPORT_IN_PROGRESS = 2, + RELOC_TRAMP_IMPORT_DONE = 3, +} RelocationTrampolinStatus; + +typedef enum RelocationType{ + RELOC_TYPE_FIXED = 0, + RELOC_TYPE_IMPORT = 1 +} RelocationType; + +typedef struct relocation_trampolin_entry_t { + uint32_t id; + uint32_t trampolin[4]; + RelocationTrampolinStatus status = RELOC_TRAMP_FREE; +} relocation_trampolin_entry_t; diff --git a/source/common/replacement_defines.h b/source/common/replacement_defines.h new file mode 100644 index 0000000..f66f30c --- /dev/null +++ b/source/common/replacement_defines.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +#define FUNCTION_PATCHER_METHOD_STORE_SIZE 13 +#define MAXIMUM_FUNCTION_NAME_LENGTH 83 + +struct replacement_data_function_t { + uint32_t physicalAddr; /* [needs to be filled] */ + uint32_t virtualAddr; /* [needs to be filled] */ + uint32_t replaceAddr; /* [needs to be filled] Address of our replacement function */ + uint32_t replaceCall; /* [needs to be filled] Address to access the real_function */ + wups_loader_library_type_t library; /* [needs to be filled] rpl where the function we want to replace is. */ + char function_name[MAXIMUM_FUNCTION_NAME_LENGTH]; /* [needs to be filled] name of the function we want to replace */ + uint32_t realAddr; /* [will be filled] Address of the real function we want to replace. */ + volatile uint32_t replace_data [FUNCTION_PATCHER_METHOD_STORE_SIZE]; /* [will be filled] Space for us to store some jump instructions */ + uint32_t restoreInstruction; /* [will be filled] Copy of the instruction we replaced to jump to our code. */ + uint8_t functionType; /* [will be filled] */ + uint8_t alreadyPatched; /* [will be filled] */ +}; + +struct replacement_data_hook_t { + void * func_pointer = NULL; /* [will be filled] */ + wups_loader_hook_type_t type; /* [will be filled] */ +}; diff --git a/source/crt0.s b/source/crt0.s new file mode 100644 index 0000000..595a028 --- /dev/null +++ b/source/crt0.s @@ -0,0 +1,29 @@ +.extern main +.extern exit +.extern __init_wut +.extern __fini_wut + +.global _start +_start: + stwu 1, -0x28(1) + mflr 0 + stw 0, 0x2C(1) + stw 31, 0x24(1) + or 31, 1, 1 + stw 3, 0x18(31) + stw 4, 0x1C(31) + bl __init_wut + lwz 4, 0x1C(31) + lwz 3, 0x18(31) + bl main + or 9, 3, 3 + stw 9, 0x8(31) + bl __fini_wut + lwz 9, 0x8(31) + or 3, 9, 9 + addi 11, 31, 0x28 + lwz 0, 0x4(11) + mtlr 0 + lwz 31, -0x4(11) + or 1, 11, 11 + blr \ No newline at end of file diff --git a/source/elfio/elf_types.hpp b/source/elfio/elf_types.hpp new file mode 100644 index 0000000..63d025a --- /dev/null +++ b/source/elfio/elf_types.hpp @@ -0,0 +1,851 @@ +/* +Copyright (C) 2001-2015 by Serge Lamikhov-Center + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef ELFTYPES_H +#define ELFTYPES_H + +#ifndef ELFIO_NO_OWN_TYPES + #if !defined(ELFIO_NO_CSTDINT) && !defined(ELFIO_NO_INTTYPES) + #include + #else + typedef unsigned char uint8_t; + typedef signed char int8_t; + typedef unsigned short uint16_t; + typedef signed short int16_t; + #ifdef _MSC_VER + typedef unsigned __int32 uint32_t; + typedef signed __int32 int32_t; + typedef unsigned __int64 uint64_t; + typedef signed __int64 int64_t; + #else + typedef unsigned int uint32_t; + typedef signed int int32_t; + typedef unsigned long long uint64_t; + typedef signed long long int64_t; + #endif // _MSC_VER + #endif // ELFIO_NO_CSTDINT +#endif // ELFIO_NO_OWN_TYPES + +namespace ELFIO { + +// Attention! Platform depended definitions. +typedef uint16_t Elf_Half; +typedef uint32_t Elf_Word; +typedef int32_t Elf_Sword; +typedef uint64_t Elf_Xword; +typedef int64_t Elf_Sxword; + +typedef uint32_t Elf32_Addr; +typedef uint32_t Elf32_Off; +typedef uint64_t Elf64_Addr; +typedef uint64_t Elf64_Off; + +#define Elf32_Half Elf_Half +#define Elf64_Half Elf_Half +#define Elf32_Word Elf_Word +#define Elf64_Word Elf_Word +#define Elf32_Sword Elf_Sword +#define Elf64_Sword Elf_Sword + +/////////////////////// +// ELF Header Constants + +// File type +#define ET_NONE 0 +#define ET_REL 1 +#define ET_EXEC 2 +#define ET_DYN 3 +#define ET_CORE 4 +#define ET_LOOS 0xFE00 +#define ET_HIOS 0xFEFF +#define ET_LOPROC 0xFF00 +#define ET_HIPROC 0xFFFF + + +#define EM_NONE 0 // No machine +#define EM_M32 1 // AT&T WE 32100 +#define EM_SPARC 2 // SUN SPARC +#define EM_386 3 // Intel 80386 +#define EM_68K 4 // Motorola m68k family +#define EM_88K 5 // Motorola m88k family +#define EM_486 6 // Intel 80486// Reserved for future use +#define EM_860 7 // Intel 80860 +#define EM_MIPS 8 // MIPS R3000 (officially, big-endian only) +#define EM_S370 9 // IBM System/370 +#define EM_MIPS_RS3_LE 10 // MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated +#define EM_res011 11 // Reserved +#define EM_res012 12 // Reserved +#define EM_res013 13 // Reserved +#define EM_res014 14 // Reserved +#define EM_PARISC 15 // HPPA +#define EM_res016 16 // Reserved +#define EM_VPP550 17 // Fujitsu VPP500 +#define EM_SPARC32PLUS 18 // Sun's "v8plus" +#define EM_960 19 // Intel 80960 +#define EM_PPC 20 // PowerPC +#define EM_PPC64 21 // 64-bit PowerPC +#define EM_S390 22 // IBM S/390 +#define EM_SPU 23 // Sony/Toshiba/IBM SPU +#define EM_res024 24 // Reserved +#define EM_res025 25 // Reserved +#define EM_res026 26 // Reserved +#define EM_res027 27 // Reserved +#define EM_res028 28 // Reserved +#define EM_res029 29 // Reserved +#define EM_res030 30 // Reserved +#define EM_res031 31 // Reserved +#define EM_res032 32 // Reserved +#define EM_res033 33 // Reserved +#define EM_res034 34 // Reserved +#define EM_res035 35 // Reserved +#define EM_V800 36 // NEC V800 series +#define EM_FR20 37 // Fujitsu FR20 +#define EM_RH32 38 // TRW RH32 +#define EM_MCORE 39 // Motorola M*Core // May also be taken by Fujitsu MMA +#define EM_RCE 39 // Old name for MCore +#define EM_ARM 40 // ARM +#define EM_OLD_ALPHA 41 // Digital Alpha +#define EM_SH 42 // Renesas (formerly Hitachi) / SuperH SH +#define EM_SPARCV9 43 // SPARC v9 64-bit +#define EM_TRICORE 44 // Siemens Tricore embedded processor +#define EM_ARC 45 // ARC Cores +#define EM_H8_300 46 // Renesas (formerly Hitachi) H8/300 +#define EM_H8_300H 47 // Renesas (formerly Hitachi) H8/300H +#define EM_H8S 48 // Renesas (formerly Hitachi) H8S +#define EM_H8_500 49 // Renesas (formerly Hitachi) H8/500 +#define EM_IA_64 50 // Intel IA-64 Processor +#define EM_MIPS_X 51 // Stanford MIPS-X +#define EM_COLDFIRE 52 // Motorola Coldfire +#define EM_68HC12 53 // Motorola M68HC12 +#define EM_MMA 54 // Fujitsu Multimedia Accelerator +#define EM_PCP 55 // Siemens PCP +#define EM_NCPU 56 // Sony nCPU embedded RISC processor +#define EM_NDR1 57 // Denso NDR1 microprocesspr +#define EM_STARCORE 58 // Motorola Star*Core processor +#define EM_ME16 59 // Toyota ME16 processor +#define EM_ST100 60 // STMicroelectronics ST100 processor +#define EM_TINYJ 61 // Advanced Logic Corp. TinyJ embedded processor +#define EM_X86_64 62 // Advanced Micro Devices X86-64 processor +#define EM_PDSP 63 // Sony DSP Processor +#define EM_PDP10 64 // Digital Equipment Corp. PDP-10 +#define EM_PDP11 65 // Digital Equipment Corp. PDP-11 +#define EM_FX66 66 // Siemens FX66 microcontroller +#define EM_ST9PLUS 67 // STMicroelectronics ST9+ 8/16 bit microcontroller +#define EM_ST7 68 // STMicroelectronics ST7 8-bit microcontroller +#define EM_68HC16 69 // Motorola MC68HC16 Microcontroller +#define EM_68HC11 70 // Motorola MC68HC11 Microcontroller +#define EM_68HC08 71 // Motorola MC68HC08 Microcontroller +#define EM_68HC05 72 // Motorola MC68HC05 Microcontroller +#define EM_SVX 73 // Silicon Graphics SVx +#define EM_ST19 74 // STMicroelectronics ST19 8-bit cpu +#define EM_VAX 75 // Digital VAX +#define EM_CRIS 76 // Axis Communications 32-bit embedded processor +#define EM_JAVELIN 77 // Infineon Technologies 32-bit embedded cpu +#define EM_FIREPATH 78 // Element 14 64-bit DSP processor +#define EM_ZSP 79 // LSI Logic's 16-bit DSP processor +#define EM_MMIX 80 // Donald Knuth's educational 64-bit processor +#define EM_HUANY 81 // Harvard's machine-independent format +#define EM_PRISM 82 // SiTera Prism +#define EM_AVR 83 // Atmel AVR 8-bit microcontroller +#define EM_FR30 84 // Fujitsu FR30 +#define EM_D10V 85 // Mitsubishi D10V +#define EM_D30V 86 // Mitsubishi D30V +#define EM_V850 87 // NEC v850 +#define EM_M32R 88 // Renesas M32R (formerly Mitsubishi M32R) +#define EM_MN10300 89 // Matsushita MN10300 +#define EM_MN10200 90 // Matsushita MN10200 +#define EM_PJ 91 // picoJava +#define EM_OPENRISC 92 // OpenRISC 32-bit embedded processor +#define EM_ARC_A5 93 // ARC Cores Tangent-A5 +#define EM_XTENSA 94 // Tensilica Xtensa Architecture +#define EM_VIDEOCORE 95 // Alphamosaic VideoCore processor +#define EM_TMM_GPP 96 // Thompson Multimedia General Purpose Processor +#define EM_NS32K 97 // National Semiconductor 32000 series +#define EM_TPC 98 // Tenor Network TPC processor +#define EM_SNP1K 99 // Trebia SNP 1000 processor +#define EM_ST200 100 // STMicroelectronics ST200 microcontroller +#define EM_IP2K 101 // Ubicom IP2022 micro controller +#define EM_MAX 102 // MAX Processor +#define EM_CR 103 // National Semiconductor CompactRISC +#define EM_F2MC16 104 // Fujitsu F2MC16 +#define EM_MSP430 105 // TI msp430 micro controller +#define EM_BLACKFIN 106 // ADI Blackfin +#define EM_SE_C33 107 // S1C33 Family of Seiko Epson processors +#define EM_SEP 108 // Sharp embedded microprocessor +#define EM_ARCA 109 // Arca RISC Microprocessor +#define EM_UNICORE 110 // Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University +#define EM_EXCESS 111 // eXcess: 16/32/64-bit configurable embedded CPU +#define EM_DXP 112 // Icera Semiconductor Inc. Deep Execution Processor +#define EM_ALTERA_NIOS2 113 // Altera Nios II soft-core processor +#define EM_CRX 114 // National Semiconductor CRX +#define EM_XGATE 115 // Motorola XGATE embedded processor +#define EM_C166 116 // Infineon C16x/XC16x processor +#define EM_M16C 117 // Renesas M16C series microprocessors +#define EM_DSPIC30F 118 // Microchip Technology dsPIC30F Digital Signal Controller +#define EM_CE 119 // Freescale Communication Engine RISC core +#define EM_M32C 120 // Renesas M32C series microprocessors +#define EM_res121 121 // Reserved +#define EM_res122 122 // Reserved +#define EM_res123 123 // Reserved +#define EM_res124 124 // Reserved +#define EM_res125 125 // Reserved +#define EM_res126 126 // Reserved +#define EM_res127 127 // Reserved +#define EM_res128 128 // Reserved +#define EM_res129 129 // Reserved +#define EM_res130 130 // Reserved +#define EM_TSK3000 131 // Altium TSK3000 core +#define EM_RS08 132 // Freescale RS08 embedded processor +#define EM_res133 133 // Reserved +#define EM_ECOG2 134 // Cyan Technology eCOG2 microprocessor +#define EM_SCORE 135 // Sunplus Score +#define EM_SCORE7 135 // Sunplus S+core7 RISC processor +#define EM_DSP24 136 // New Japan Radio (NJR) 24-bit DSP Processor +#define EM_VIDEOCORE3 137 // Broadcom VideoCore III processor +#define EM_LATTICEMICO32 138 // RISC processor for Lattice FPGA architecture +#define EM_SE_C17 139 // Seiko Epson C17 family +#define EM_TI_C6000 140 // Texas Instruments TMS320C6000 DSP family +#define EM_TI_C2000 141 // Texas Instruments TMS320C2000 DSP family +#define EM_TI_C5500 142 // Texas Instruments TMS320C55x DSP family +#define EM_res143 143 // Reserved +#define EM_res144 144 // Reserved +#define EM_res145 145 // Reserved +#define EM_res146 146 // Reserved +#define EM_res147 147 // Reserved +#define EM_res148 148 // Reserved +#define EM_res149 149 // Reserved +#define EM_res150 150 // Reserved +#define EM_res151 151 // Reserved +#define EM_res152 152 // Reserved +#define EM_res153 153 // Reserved +#define EM_res154 154 // Reserved +#define EM_res155 155 // Reserved +#define EM_res156 156 // Reserved +#define EM_res157 157 // Reserved +#define EM_res158 158 // Reserved +#define EM_res159 159 // Reserved +#define EM_MMDSP_PLUS 160 // STMicroelectronics 64bit VLIW Data Signal Processor +#define EM_CYPRESS_M8C 161 // Cypress M8C microprocessor +#define EM_R32C 162 // Renesas R32C series microprocessors +#define EM_TRIMEDIA 163 // NXP Semiconductors TriMedia architecture family +#define EM_QDSP6 164 // QUALCOMM DSP6 Processor +#define EM_8051 165 // Intel 8051 and variants +#define EM_STXP7X 166 // STMicroelectronics STxP7x family +#define EM_NDS32 167 // Andes Technology compact code size embedded RISC processor family +#define EM_ECOG1 168 // Cyan Technology eCOG1X family +#define EM_ECOG1X 168 // Cyan Technology eCOG1X family +#define EM_MAXQ30 169 // Dallas Semiconductor MAXQ30 Core Micro-controllers +#define EM_XIMO16 170 // New Japan Radio (NJR) 16-bit DSP Processor +#define EM_MANIK 171 // M2000 Reconfigurable RISC Microprocessor +#define EM_CRAYNV2 172 // Cray Inc. NV2 vector architecture +#define EM_RX 173 // Renesas RX family +#define EM_METAG 174 // Imagination Technologies META processor architecture +#define EM_MCST_ELBRUS 175 // MCST Elbrus general purpose hardware architecture +#define EM_ECOG16 176 // Cyan Technology eCOG16 family +#define EM_CR16 177 // National Semiconductor CompactRISC 16-bit processor +#define EM_ETPU 178 // Freescale Extended Time Processing Unit +#define EM_SLE9X 179 // Infineon Technologies SLE9X core +#define EM_L1OM 180 // Intel L1OM +#define EM_INTEL181 181 // Reserved by Intel +#define EM_INTEL182 182 // Reserved by Intel +#define EM_res183 183 // Reserved by ARM +#define EM_res184 184 // Reserved by ARM +#define EM_AVR32 185 // Atmel Corporation 32-bit microprocessor family +#define EM_STM8 186 // STMicroeletronics STM8 8-bit microcontroller +#define EM_TILE64 187 // Tilera TILE64 multicore architecture family +#define EM_TILEPRO 188 // Tilera TILEPro multicore architecture family +#define EM_MICROBLAZE 189 // Xilinx MicroBlaze 32-bit RISC soft processor core +#define EM_CUDA 190 // NVIDIA CUDA architecture +#define EM_TILEGX 191 // Tilera TILE-Gx multicore architecture family +#define EM_CLOUDSHIELD 192 // CloudShield architecture family +#define EM_COREA_1ST 193 // KIPO-KAIST Core-A 1st generation processor family +#define EM_COREA_2ND 194 // KIPO-KAIST Core-A 2nd generation processor family +#define EM_ARC_COMPACT2 195 // Synopsys ARCompact V2 +#define EM_OPEN8 196 // Open8 8-bit RISC soft processor core +#define EM_RL78 197 // Renesas RL78 family +#define EM_VIDEOCORE5 198 // Broadcom VideoCore V processor +#define EM_78KOR 199 // Renesas 78KOR family +#define EM_56800EX 200 // Freescale 56800EX Digital Signal Controller (DSC) +#define EM_BA1 201 // Beyond BA1 CPU architecture +#define EM_BA2 202 // Beyond BA2 CPU architecture +#define EM_XCORE 203 // XMOS xCORE processor family +#define EM_MCHP_PIC 204 // Microchip 8-bit PIC(r) family +#define EM_INTEL205 205 // Reserved by Intel +#define EM_INTEL206 206 // Reserved by Intel +#define EM_INTEL207 207 // Reserved by Intel +#define EM_INTEL208 208 // Reserved by Intel +#define EM_INTEL209 209 // Reserved by Intel +#define EM_KM32 210 // KM211 KM32 32-bit processor +#define EM_KMX32 211 // KM211 KMX32 32-bit processor +#define EM_KMX16 212 // KM211 KMX16 16-bit processor +#define EM_KMX8 213 // KM211 KMX8 8-bit processor +#define EM_KVARC 214 // KM211 KVARC processor +#define EM_CDP 215 // Paneve CDP architecture family +#define EM_COGE 216 // Cognitive Smart Memory Processor +#define EM_COOL 217 // iCelero CoolEngine +#define EM_NORC 218 // Nanoradio Optimized RISC +#define EM_CSR_KALIMBA 219 // CSR Kalimba architecture family +#define EM_Z80 220 // Zilog Z80 +#define EM_VISIUM 221 // Controls and Data Services VISIUMcore processor +#define EM_FT32 222 // FTDI Chip FT32 high performance 32-bit RISC architecture +#define EM_MOXIE 223 // Moxie processor family +#define EM_AMDGPU 224 // AMD GPU architecture +#define EM_RISCV 243 // RISC-V +#define EM_LANAI 244 // Lanai processor +#define EM_CEVA 245 // CEVA Processor Architecture Family +#define EM_CEVA_X2 246 // CEVA X2 Processor Family +#define EM_BPF 247 // Linux BPF – in-kernel virtual machine + +// File version +#define EV_NONE 0 +#define EV_CURRENT 1 + +// Identification index +#define EI_MAG0 0 +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define EI_OSABI 7 +#define EI_ABIVERSION 8 +#define EI_PAD 9 +#define EI_NIDENT 16 + +// Magic number +#define ELFMAG0 0x7F +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' + +// File class +#define ELFCLASSNONE 0 +#define ELFCLASS32 1 +#define ELFCLASS64 2 + +// Encoding +#define ELFDATANONE 0 +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 + +// OS extensions +#define ELFOSABI_NONE 0 // No extensions or unspecified +#define ELFOSABI_HPUX 1 // Hewlett-Packard HP-UX +#define ELFOSABI_NETBSD 2 // NetBSD +#define ELFOSABI_LINUX 3 // Linux +#define ELFOSABI_SOLARIS 6 // Sun Solaris +#define ELFOSABI_AIX 7 // AIX +#define ELFOSABI_IRIX 8 // IRIX +#define ELFOSABI_FREEBSD 9 // FreeBSD +#define ELFOSABI_TRU64 10 // Compaq TRU64 UNIX +#define ELFOSABI_MODESTO 11 // Novell Modesto +#define ELFOSABI_OPENBSD 12 // Open BSD +#define ELFOSABI_OPENVMS 13 // Open VMS +#define ELFOSABI_NSK 14 // Hewlett-Packard Non-Stop Kernel +#define ELFOSABI_AROS 15 // Amiga Research OS +#define ELFOSABI_FENIXOS 16 // The FenixOS highly scalable multi-core OS +// 64-255 Architecture-specific value range +#define ELFOSABI_AMDGPU_HSA 64 // AMDGPU OS for HSA compatible compute + // kernels. +#define ELFOSABI_AMDGPU_PAL 65 // AMDGPU OS for AMD PAL compatible graphics + // shaders and compute kernels. +#define ELFOSABI_AMDGPU_MESA3D 66 // AMDGPU OS for Mesa3D compatible graphics + // shaders and compute kernels. + + +// AMDGPU specific e_flags +#define EF_AMDGPU_MACH 0x0ff // AMDGPU processor selection mask. +#define EF_AMDGPU_XNACK 0x100 // Indicates if the XNACK target feature is + // enabled for all code contained in the ELF. +// AMDGPU processors +#define EF_AMDGPU_MACH_NONE 0x000 // Unspecified processor. +#define EF_AMDGPU_MACH_R600_R600 0x001 +#define EF_AMDGPU_MACH_R600_R630 0x002 +#define EF_AMDGPU_MACH_R600_RS880 0x003 +#define EF_AMDGPU_MACH_R600_RV670 0x004 +#define EF_AMDGPU_MACH_R600_RV710 0x005 +#define EF_AMDGPU_MACH_R600_RV730 0x006 +#define EF_AMDGPU_MACH_R600_RV770 0x007 +#define EF_AMDGPU_MACH_R600_CEDAR 0x008 +#define EF_AMDGPU_MACH_R600_CYPRESS 0x009 +#define EF_AMDGPU_MACH_R600_JUNIPER 0x00a +#define EF_AMDGPU_MACH_R600_REDWOOD 0x00b +#define EF_AMDGPU_MACH_R600_SUMO 0x00c +#define EF_AMDGPU_MACH_R600_BARTS 0x00d +#define EF_AMDGPU_MACH_R600_CAICOS 0x00e +#define EF_AMDGPU_MACH_R600_CAYMAN 0x00f +#define EF_AMDGPU_MACH_R600_TURKS 0x010 +#define EF_AMDGPU_MACH_R600_RESERVED_FIRST 0x011 +#define EF_AMDGPU_MACH_R600_RESERVED_LAST 0x01f +#define EF_AMDGPU_MACH_R600_FIRST EF_AMDGPU_MACH_R600_R600 +#define EF_AMDGPU_MACH_R600_LAST EF_AMDGPU_MACH_R600_TURKS +#define EF_AMDGPU_MACH_AMDGCN_GFX600 0x020 +#define EF_AMDGPU_MACH_AMDGCN_GFX601 0x021 +#define EF_AMDGPU_MACH_AMDGCN_GFX700 0x022 +#define EF_AMDGPU_MACH_AMDGCN_GFX701 0x023 +#define EF_AMDGPU_MACH_AMDGCN_GFX702 0x024 +#define EF_AMDGPU_MACH_AMDGCN_GFX703 0x025 +#define EF_AMDGPU_MACH_AMDGCN_GFX704 0x026 +#define EF_AMDGPU_MACH_AMDGCN_GFX801 0x028 +#define EF_AMDGPU_MACH_AMDGCN_GFX802 0x029 +#define EF_AMDGPU_MACH_AMDGCN_GFX803 0x02a +#define EF_AMDGPU_MACH_AMDGCN_GFX810 0x02b +#define EF_AMDGPU_MACH_AMDGCN_GFX900 0x02c +#define EF_AMDGPU_MACH_AMDGCN_GFX902 0x02d +#define EF_AMDGPU_MACH_AMDGCN_GFX904 0x02e +#define EF_AMDGPU_MACH_AMDGCN_GFX906 0x02f +#define EF_AMDGPU_MACH_AMDGCN_RESERVED0 0x027 +#define EF_AMDGPU_MACH_AMDGCN_RESERVED1 0x030 +#define EF_AMDGPU_MACH_AMDGCN_FIRST EF_AMDGPU_MACH_AMDGCN_GFX600 +#define EF_AMDGPU_MACH_AMDGCN_LAST EF_AMDGPU_MACH_AMDGCN_GFX906 + +///////////////////// +// Sections constants + +// Section indexes +#define SHN_UNDEF 0 +#define SHN_LORESERVE 0xFF00 +#define SHN_LOPROC 0xFF00 +#define SHN_HIPROC 0xFF1F +#define SHN_LOOS 0xFF20 +#define SHN_HIOS 0xFF3F +#define SHN_ABS 0xFFF1 +#define SHN_COMMON 0xFFF2 +#define SHN_XINDEX 0xFFFF +#define SHN_HIRESERVE 0xFFFF + +// Section types +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 +#define SHT_INIT_ARRAY 14 +#define SHT_FINI_ARRAY 15 +#define SHT_PREINIT_ARRAY 16 +#define SHT_GROUP 17 +#define SHT_SYMTAB_SHNDX 18 +#define SHT_LOOS 0x60000000 +#define SHT_HIOS 0x6fffffff +#define SHT_LOPROC 0x70000000 +#define SHT_HIPROC 0x7FFFFFFF +#define SHT_LOUSER 0x80000000 +#define SHT_HIUSER 0xFFFFFFFF + +// Section attribute flags +#define SHF_WRITE 0x1 +#define SHF_ALLOC 0x2 +#define SHF_EXECINSTR 0x4 +#define SHF_MERGE 0x10 +#define SHF_STRINGS 0x20 +#define SHF_INFO_LINK 0x40 +#define SHF_LINK_ORDER 0x80 +#define SHF_OS_NONCONFORMING 0x100 +#define SHF_GROUP 0x200 +#define SHF_TLS 0x400 +#define SHF_MASKOS 0x0ff00000 +#define SHF_MASKPROC 0xF0000000 + +// Section group flags +#define GRP_COMDAT 0x1 +#define GRP_MASKOS 0x0ff00000 +#define GRP_MASKPROC 0xf0000000 + +// Symbol binding +#define STB_LOCAL 0 +#define STB_GLOBAL 1 +#define STB_WEAK 2 +#define STB_LOOS 10 +#define STB_HIOS 12 +#define STB_MULTIDEF 13 +#define STB_LOPROC 13 +#define STB_HIPROC 15 + +// Note types +#define NT_AMDGPU_METADATA 1 +#define NT_AMD_AMDGPU_HSA_METADATA 10 +#define NT_AMD_AMDGPU_ISA 11 +#define NT_AMD_AMDGPU_PAL_METADATA 12 + +// Symbol types +#define STT_NOTYPE 0 +#define STT_OBJECT 1 +#define STT_FUNC 2 +#define STT_SECTION 3 +#define STT_FILE 4 +#define STT_COMMON 5 +#define STT_TLS 6 +#define STT_LOOS 10 +#define STT_AMDGPU_HSA_KERNEL 10 +#define STT_HIOS 12 +#define STT_LOPROC 13 +#define STT_HIPROC 15 + +// Symbol visibility +#define STV_DEFAULT 0 +#define STV_INTERNAL 1 +#define STV_HIDDEN 2 +#define STV_PROTECTED 3 + +// Undefined name +#define STN_UNDEF 0 + +// Relocation types +#define R_386_NONE 0 +#define R_X86_64_NONE 0 +#define R_AMDGPU_NONE 0 +#define R_386_32 1 +#define R_X86_64_64 1 +#define R_AMDGPU_ABS32_LO 1 +#define R_386_PC32 2 +#define R_X86_64_PC32 2 +#define R_AMDGPU_ABS32_HI 2 +#define R_386_GOT32 3 +#define R_X86_64_GOT32 3 +#define R_AMDGPU_ABS64 3 +#define R_386_PLT32 4 +#define R_X86_64_PLT32 4 +#define R_AMDGPU_REL32 4 +#define R_386_COPY 5 +#define R_X86_64_COPY 5 +#define R_AMDGPU_REL64 5 +#define R_386_GLOB_DAT 6 +#define R_X86_64_GLOB_DAT 6 +#define R_AMDGPU_ABS32 6 +#define R_386_JMP_SLOT 7 +#define R_X86_64_JUMP_SLOT 7 +#define R_AMDGPU_GOTPCREL 7 +#define R_386_RELATIVE 8 +#define R_X86_64_RELATIVE 8 +#define R_AMDGPU_GOTPCREL32_LO 8 +#define R_386_GOTOFF 9 +#define R_X86_64_GOTPCREL 9 +#define R_AMDGPU_GOTPCREL32_HI 9 +#define R_386_GOTPC 10 +#define R_X86_64_32 10 +#define R_AMDGPU_REL32_LO 10 +#define R_386_32PLT 11 +#define R_X86_64_32S 11 +#define R_AMDGPU_REL32_HI 11 +#define R_X86_64_16 12 +#define R_X86_64_PC16 13 +#define R_AMDGPU_RELATIVE64 13 +#define R_386_TLS_TPOFF 14 +#define R_X86_64_8 14 +#define R_386_TLS_IE 15 +#define R_X86_64_PC8 15 +#define R_386_TLS_GOTIE 16 +#define R_X86_64_DTPMOD64 16 +#define R_386_TLS_LE 17 +#define R_X86_64_DTPOFF64 17 +#define R_386_TLS_GD 18 +#define R_X86_64_TPOFF64 18 +#define R_386_TLS_LDM 19 +#define R_X86_64_TLSGD 19 +#define R_386_16 20 +#define R_X86_64_TLSLD 20 +#define R_386_PC16 21 +#define R_X86_64_DTPOFF32 21 +#define R_386_8 22 +#define R_X86_64_GOTTPOFF 22 +#define R_386_PC8 23 +#define R_X86_64_TPOFF32 23 +#define R_386_TLS_GD_32 24 +#define R_X86_64_PC64 24 +#define R_386_TLS_GD_PUSH 25 +#define R_X86_64_GOTOFF64 25 +#define R_386_TLS_GD_CALL 26 +#define R_X86_64_GOTPC32 26 +#define R_386_TLS_GD_POP 27 +#define R_X86_64_GOT64 27 +#define R_386_TLS_LDM_32 28 +#define R_X86_64_GOTPCREL64 28 +#define R_386_TLS_LDM_PUSH 29 +#define R_X86_64_GOTPC64 29 +#define R_386_TLS_LDM_CALL 30 +#define R_X86_64_GOTPLT64 30 +#define R_386_TLS_LDM_POP 31 +#define R_X86_64_PLTOFF64 31 +#define R_386_TLS_LDO_32 32 +#define R_386_TLS_IE_32 33 +#define R_386_TLS_LE_32 34 +#define R_X86_64_GOTPC32_TLSDESC 34 +#define R_386_TLS_DTPMOD32 35 +#define R_X86_64_TLSDESC_CALL 35 +#define R_386_TLS_DTPOFF32 36 +#define R_X86_64_TLSDESC 36 +#define R_386_TLS_TPOFF32 37 +#define R_X86_64_IRELATIVE 37 +#define R_386_SIZE32 38 +#define R_386_TLS_GOTDESC 39 +#define R_386_TLS_DESC_CALL 40 +#define R_386_TLS_DESC 41 +#define R_386_IRELATIVE 42 +#define R_386_GOT32X 43 +#define R_X86_64_GNU_VTINHERIT 250 +#define R_X86_64_GNU_VTENTRY 251 + +// Segment types +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_TLS 7 +#define PT_LOOS 0x60000000 +#define PT_HIOS 0x6fffffff +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7FFFFFFF + +// Segment flags +#define PF_X 1 // Execute +#define PF_W 2 // Write +#define PF_R 4 // Read +#define PF_MASKOS 0x0ff00000 // Unspecified +#define PF_MASKPROC 0xf0000000 // Unspecified + +// Dynamic Array Tags +#define DT_NULL 0 +#define DT_NEEDED 1 +#define DT_PLTRELSZ 2 +#define DT_PLTGOT 3 +#define DT_HASH 4 +#define DT_STRTAB 5 +#define DT_SYMTAB 6 +#define DT_RELA 7 +#define DT_RELASZ 8 +#define DT_RELAENT 9 +#define DT_STRSZ 10 +#define DT_SYMENT 11 +#define DT_INIT 12 +#define DT_FINI 13 +#define DT_SONAME 14 +#define DT_RPATH 15 +#define DT_SYMBOLIC 16 +#define DT_REL 17 +#define DT_RELSZ 18 +#define DT_RELENT 19 +#define DT_PLTREL 20 +#define DT_DEBUG 21 +#define DT_TEXTREL 22 +#define DT_JMPREL 23 +#define DT_BIND_NOW 24 +#define DT_INIT_ARRAY 25 +#define DT_FINI_ARRAY 26 +#define DT_INIT_ARRAYSZ 27 +#define DT_FINI_ARRAYSZ 28 +#define DT_RUNPATH 29 +#define DT_FLAGS 30 +#define DT_ENCODING 32 +#define DT_PREINIT_ARRAY 32 +#define DT_PREINIT_ARRAYSZ 33 +#define DT_MAXPOSTAGS 34 +#define DT_LOOS 0x6000000D +#define DT_HIOS 0x6ffff000 +#define DT_LOPROC 0x70000000 +#define DT_HIPROC 0x7FFFFFFF + +// DT_FLAGS values +#define DF_ORIGIN 0x1 +#define DF_SYMBOLIC 0x2 +#define DF_TEXTREL 0x4 +#define DF_BIND_NOW 0x8 +#define DF_STATIC_TLS 0x10 + + +// ELF file header +struct Elf32_Ehdr { + unsigned char e_ident[EI_NIDENT]; + Elf_Half e_type; + Elf_Half e_machine; + Elf_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf_Word e_flags; + Elf_Half e_ehsize; + Elf_Half e_phentsize; + Elf_Half e_phnum; + Elf_Half e_shentsize; + Elf_Half e_shnum; + Elf_Half e_shstrndx; +}; + +struct Elf64_Ehdr { + unsigned char e_ident[EI_NIDENT]; + Elf_Half e_type; + Elf_Half e_machine; + Elf_Word e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + Elf_Word e_flags; + Elf_Half e_ehsize; + Elf_Half e_phentsize; + Elf_Half e_phnum; + Elf_Half e_shentsize; + Elf_Half e_shnum; + Elf_Half e_shstrndx; +}; + + +// Section header +struct Elf32_Shdr { + Elf_Word sh_name; + Elf_Word sh_type; + Elf_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf_Word sh_size; + Elf_Word sh_link; + Elf_Word sh_info; + Elf_Word sh_addralign; + Elf_Word sh_entsize; +}; + +struct Elf64_Shdr { + Elf_Word sh_name; + Elf_Word sh_type; + Elf_Xword sh_flags; + Elf64_Addr sh_addr; + Elf64_Off sh_offset; + Elf_Xword sh_size; + Elf_Word sh_link; + Elf_Word sh_info; + Elf_Xword sh_addralign; + Elf_Xword sh_entsize; +}; + + +// Segment header +struct Elf32_Phdr { + Elf_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf_Word p_filesz; + Elf_Word p_memsz; + Elf_Word p_flags; + Elf_Word p_align; +}; + +struct Elf64_Phdr { + Elf_Word p_type; + Elf_Word p_flags; + Elf64_Off p_offset; + Elf64_Addr p_vaddr; + Elf64_Addr p_paddr; + Elf_Xword p_filesz; + Elf_Xword p_memsz; + Elf_Xword p_align; +}; + + +// Symbol table entry +struct Elf32_Sym { + Elf_Word st_name; + Elf32_Addr st_value; + Elf_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf_Half st_shndx; +}; + +struct Elf64_Sym { + Elf_Word st_name; + unsigned char st_info; + unsigned char st_other; + Elf_Half st_shndx; + Elf64_Addr st_value; + Elf_Xword st_size; +}; + + +#define ELF_ST_BIND(i) ((i)>>4) +#define ELF_ST_TYPE(i) ((i)&0xf) +#define ELF_ST_INFO(b,t) (((b)<<4)+((t)&0xf)) + +#define ELF_ST_VISIBILITY(o) ((o)&0x3) + + +// Relocation entries +struct Elf32_Rel { + Elf32_Addr r_offset; + Elf_Word r_info; +}; + +struct Elf32_Rela { + Elf32_Addr r_offset; + Elf_Word r_info; + Elf_Sword r_addend; +}; + +struct Elf64_Rel { + Elf64_Addr r_offset; + Elf_Xword r_info; +}; + +struct Elf64_Rela { + Elf64_Addr r_offset; + Elf_Xword r_info; + Elf_Sxword r_addend; +}; + + +#define ELF32_R_SYM(i) ((i)>>8) +#define ELF32_R_TYPE(i) ((unsigned char)(i)) +#define ELF32_R_INFO(s,t) (((s)<<8 )+(unsigned char)(t)) + +#define ELF64_R_SYM(i) ((i)>>32) +#define ELF64_R_TYPE(i) ((i)&0xffffffffL) +#define ELF64_R_INFO(s,t) ((((int64_t)(s))<<32)+((t)&0xffffffffL)) + +// Dynamic structure +struct Elf32_Dyn { + Elf_Sword d_tag; + union { + Elf_Word d_val; + Elf32_Addr d_ptr; + } d_un; +}; + +struct Elf64_Dyn { + Elf_Sxword d_tag; + union { + Elf_Xword d_val; + Elf64_Addr d_ptr; + } d_un; +}; + +} // namespace ELFIO + +#endif // ELFTYPES_H diff --git a/source/elfio/elfio.hpp b/source/elfio/elfio.hpp new file mode 100644 index 0000000..db3b6af --- /dev/null +++ b/source/elfio/elfio.hpp @@ -0,0 +1,932 @@ +/* +Copyright (C) 2001-2015 by Serge Lamikhov-Center + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef ELFIO_HPP +#define ELFIO_HPP + +#ifdef _MSC_VER +#pragma warning ( push ) +#pragma warning(disable:4996) +#pragma warning(disable:4355) +#pragma warning(disable:4244) +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define ELFIO_HEADER_ACCESS_GET( TYPE, FNAME ) \ +TYPE \ +get_##FNAME() const \ +{ \ + return header? header->get_##FNAME() : 0; \ +} + +#define ELFIO_HEADER_ACCESS_GET_SET( TYPE, FNAME ) \ +TYPE \ +get_##FNAME() const \ +{ \ + return header? header->get_##FNAME() : 0; \ +} \ +void \ +set_##FNAME( TYPE val ) \ +{ \ + if (header) { \ + header->set_##FNAME( val ); \ + } \ +} \ + +struct membuf : std::streambuf { + membuf(char* begin, char* end) { + this->setg(begin, begin, end); + } + + pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which = std::ios_base::in) override { + if (dir == std::ios_base::cur) + gbump(off); + else if (dir == std::ios_base::end) + setg(eback(), egptr() + off, egptr()); + else if (dir == std::ios_base::beg) + setg(eback(), eback() + off, egptr()); + return gptr() - eback(); + } + + pos_type seekpos(pos_type sp, std::ios_base::openmode which) override { + return seekoff(sp - pos_type(off_type(0)), std::ios_base::beg, which); + } +}; + +namespace ELFIO { + +//------------------------------------------------------------------------------ +class elfio { +public: +//------------------------------------------------------------------------------ + elfio() : sections( this ), segments( this ) { + header = 0; + current_file_pos = 0; + create( ELFCLASS32, ELFDATA2LSB ); + } + +//------------------------------------------------------------------------------ + ~elfio() { + clean(); + } + +//------------------------------------------------------------------------------ + void create( unsigned char file_class, unsigned char encoding ) { + clean(); + convertor.setup( encoding ); + header = create_header( file_class, encoding ); + create_mandatory_sections(); + } + + +//------------------------------------------------------------------------------ + bool load(char * buffer, size_t length) { + membuf sbuf(buffer, buffer + length); + std::istream in(&sbuf); + return load(in); + } + +//------------------------------------------------------------------------------ + bool load( const std::string& file_name ) { + std::ifstream stream; + stream.open( file_name.c_str(), std::ios::in | std::ios::binary ); + if ( !stream ) { + return false; + } + + return load(stream); + } + +//------------------------------------------------------------------------------ + bool load( std::istream &stream ) { + clean(); + + unsigned char e_ident[EI_NIDENT]; + // Read ELF file signature + stream.read( reinterpret_cast( &e_ident ), sizeof( e_ident ) ); + + // Is it ELF file? + if ( stream.gcount() != sizeof( e_ident ) || + e_ident[EI_MAG0] != ELFMAG0 || + e_ident[EI_MAG1] != ELFMAG1 || + e_ident[EI_MAG2] != ELFMAG2 || + e_ident[EI_MAG3] != ELFMAG3 ) { + return false; + } + + if ( ( e_ident[EI_CLASS] != ELFCLASS64 ) && + ( e_ident[EI_CLASS] != ELFCLASS32 )) { + return false; + } + + convertor.setup( e_ident[EI_DATA] ); + header = create_header( e_ident[EI_CLASS], e_ident[EI_DATA] ); + if ( 0 == header ) { + return false; + } + if ( !header->load( stream ) ) { + return false; + } + + load_sections( stream ); + bool is_still_good = load_segments( stream ); + return is_still_good; + } + +//------------------------------------------------------------------------------ + bool save( const std::string& file_name ) { + std::ofstream stream; + stream.open( file_name.c_str(), std::ios::out | std::ios::binary ); + if ( !stream ) { + return false; + } + + return save(stream); + } + +//------------------------------------------------------------------------------ + bool save( std::ostream &stream ) { + if ( !stream || !header) { + return false; + } + + bool is_still_good = true; + // Define layout specific header fields + // The position of the segment table is fixed after the header. + // The position of the section table is variable and needs to be fixed + // before saving. + header->set_segments_num( segments.size() ); + header->set_segments_offset( segments.size() ? header->get_header_size() : 0 ); + header->set_sections_num( sections.size() ); + header->set_sections_offset( 0 ); + + // Layout the first section right after the segment table + current_file_pos = header->get_header_size() + + header->get_segment_entry_size() * header->get_segments_num(); + + calc_segment_alignment(); + + is_still_good = layout_segments_and_their_sections(); + is_still_good = is_still_good && layout_sections_without_segments(); + is_still_good = is_still_good && layout_section_table(); + + is_still_good = is_still_good && save_header( stream ); + is_still_good = is_still_good && save_sections( stream ); + is_still_good = is_still_good && save_segments( stream ); + + return is_still_good; + } + +//------------------------------------------------------------------------------ + // ELF header access functions + ELFIO_HEADER_ACCESS_GET( unsigned char, class ); + ELFIO_HEADER_ACCESS_GET( unsigned char, elf_version ); + ELFIO_HEADER_ACCESS_GET( unsigned char, encoding ); + ELFIO_HEADER_ACCESS_GET( Elf_Word, version ); + ELFIO_HEADER_ACCESS_GET( Elf_Half, header_size ); + ELFIO_HEADER_ACCESS_GET( Elf_Half, section_entry_size ); + ELFIO_HEADER_ACCESS_GET( Elf_Half, segment_entry_size ); + + ELFIO_HEADER_ACCESS_GET_SET( unsigned char, os_abi ); + ELFIO_HEADER_ACCESS_GET_SET( unsigned char, abi_version ); + ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, type ); + ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, machine ); + ELFIO_HEADER_ACCESS_GET_SET( Elf_Word, flags ); + ELFIO_HEADER_ACCESS_GET_SET( Elf64_Addr, entry ); + ELFIO_HEADER_ACCESS_GET_SET( Elf64_Off, sections_offset ); + ELFIO_HEADER_ACCESS_GET_SET( Elf64_Off, segments_offset ); + ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, section_name_str_index ); + +//------------------------------------------------------------------------------ + const endianess_convertor& get_convertor() const { + return convertor; + } + +//------------------------------------------------------------------------------ + Elf_Xword get_default_entry_size( Elf_Word section_type ) const { + switch( section_type ) { + case SHT_RELA: + if ( header->get_class() == ELFCLASS64 ) { + return sizeof( Elf64_Rela ); + } else { + return sizeof( Elf32_Rela ); + } + case SHT_REL: + if ( header->get_class() == ELFCLASS64 ) { + return sizeof( Elf64_Rel ); + } else { + return sizeof( Elf32_Rel ); + } + case SHT_SYMTAB: + if ( header->get_class() == ELFCLASS64 ) { + return sizeof( Elf64_Sym ); + } else { + return sizeof( Elf32_Sym ); + } + case SHT_DYNAMIC: + if ( header->get_class() == ELFCLASS64 ) { + return sizeof( Elf64_Dyn ); + } else { + return sizeof( Elf32_Dyn ); + } + default: + return 0; + } + } + +//------------------------------------------------------------------------------ +private: + bool is_offset_in_section( Elf64_Off offset, const section* sec ) const { + return offset >= sec->get_offset() && offset < sec->get_offset()+sec->get_size(); + } + +//------------------------------------------------------------------------------ +public: + + //! returns an empty string if no problems are detected, + //! or a string containing an error message if problems are found + std::string validate() const { + + // check for overlapping sections in the file + for ( int i = 0; i < sections.size(); ++i) { + for ( int j = i+1; j < sections.size(); ++j ) { + const section* a = sections[i]; + const section* b = sections[j]; + if ( !(a->get_type() & SHT_NOBITS) + && !(b->get_type() & SHT_NOBITS) + && (a->get_size() > 0) + && (b->get_size() > 0) + && (a->get_offset() > 0) + && (b->get_offset() > 0)) { + if ( is_offset_in_section( a->get_offset(), b ) + || is_offset_in_section( a->get_offset()+a->get_size()-1, b ) + || is_offset_in_section( b->get_offset(), a ) + || is_offset_in_section( b->get_offset()+b->get_size()-1, a )) { + return "Sections " + a->get_name() + " and " + b->get_name() + " overlap in file"; + } + } + } + } + + // more checks to be added here... + + return ""; + } + +//------------------------------------------------------------------------------ +private: +//------------------------------------------------------------------------------ + void clean() { + delete header; + header = 0; + + std::vector::const_iterator it; + for ( it = sections_.begin(); it != sections_.end(); ++it ) { + delete *it; + } + sections_.clear(); + + std::vector::const_iterator it1; + for ( it1 = segments_.begin(); it1 != segments_.end(); ++it1 ) { + delete *it1; + } + segments_.clear(); + } + +//------------------------------------------------------------------------------ + elf_header* create_header( unsigned char file_class, unsigned char encoding ) { + elf_header* new_header = 0; + + if ( file_class == ELFCLASS64 ) { + new_header = new elf_header_impl< Elf64_Ehdr >( &convertor, + encoding ); + } else if ( file_class == ELFCLASS32 ) { + new_header = new elf_header_impl< Elf32_Ehdr >( &convertor, + encoding ); + } else { + return 0; + } + + return new_header; + } + +//------------------------------------------------------------------------------ + section* create_section() { + section* new_section; + unsigned char file_class = get_class(); + + if ( file_class == ELFCLASS64 ) { + new_section = new section_impl( &convertor ); + } else if ( file_class == ELFCLASS32 ) { + new_section = new section_impl( &convertor ); + } else { + return 0; + } + + new_section->set_index( (Elf_Half)sections_.size() ); + sections_.push_back( new_section ); + + return new_section; + } + + +//------------------------------------------------------------------------------ + segment* create_segment() { + segment* new_segment; + unsigned char file_class = header->get_class(); + + if ( file_class == ELFCLASS64 ) { + new_segment = new segment_impl( &convertor ); + } else if ( file_class == ELFCLASS32 ) { + new_segment = new segment_impl( &convertor ); + } else { + return 0; + } + + new_segment->set_index( (Elf_Half)segments_.size() ); + segments_.push_back( new_segment ); + + return new_segment; + } + +//------------------------------------------------------------------------------ + void create_mandatory_sections() { + // Create null section without calling to 'add_section' as no string + // section containing section names exists yet + section* sec0 = create_section(); + sec0->set_index( 0 ); + sec0->set_name( "" ); + sec0->set_name_string_offset( 0 ); + + set_section_name_str_index( 1 ); + section* shstrtab = sections.add( ".shstrtab" ); + shstrtab->set_type( SHT_STRTAB ); + shstrtab->set_addr_align( 1 ); + } + +//------------------------------------------------------------------------------ + Elf_Half load_sections( std::istream& stream ) { + Elf_Half entry_size = header->get_section_entry_size(); + Elf_Half num = header->get_sections_num(); + Elf64_Off offset = header->get_sections_offset(); + + for ( Elf_Half i = 0; i < num; ++i ) { + section* sec = create_section(); + sec->load( stream, (std::streamoff)offset + i * entry_size ); + sec->set_index( i ); + // To mark that the section is not permitted to reassign address + // during layout calculation + sec->set_address( sec->get_address() ); + } + + Elf_Half shstrndx = get_section_name_str_index(); + + if ( SHN_UNDEF != shstrndx ) { + string_section_accessor str_reader( sections[shstrndx] ); + for ( Elf_Half i = 0; i < num; ++i ) { + Elf_Word section_offset = sections[i]->get_name_string_offset(); + const char* p = str_reader.get_string( section_offset ); + if ( p != 0 ) { + sections[i]->set_name( p ); + } + } + } + + return num; + } + +//------------------------------------------------------------------------------ + //! Checks whether the addresses of the section entirely fall within the given segment. + //! It doesn't matter if the addresses are memory addresses, or file offsets, + //! they just need to be in the same address space + bool is_sect_in_seg ( Elf64_Off sect_begin, Elf_Xword sect_size, Elf64_Off seg_begin, Elf64_Off seg_end ) { + return seg_begin <= sect_begin + && sect_begin + sect_size <= seg_end + && sect_begin < seg_end; // this is important criteria when sect_size == 0 + // Example: seg_begin=10, seg_end=12 (-> covering the bytes 10 and 11) + // sect_begin=12, sect_size=0 -> shall return false! + } + +//------------------------------------------------------------------------------ + bool load_segments( std::istream& stream ) { + Elf_Half entry_size = header->get_segment_entry_size(); + Elf_Half num = header->get_segments_num(); + Elf64_Off offset = header->get_segments_offset(); + + for ( Elf_Half i = 0; i < num; ++i ) { + segment* seg; + unsigned char file_class = header->get_class(); + + if ( file_class == ELFCLASS64 ) { + seg = new segment_impl( &convertor ); + } else if ( file_class == ELFCLASS32 ) { + seg = new segment_impl( &convertor ); + } else { + return false; + } + + seg->load( stream, (std::streamoff)offset + i * entry_size ); + seg->set_index( i ); + + // Add sections to the segments (similar to readelfs algorithm) + Elf64_Off segBaseOffset = seg->get_offset(); + Elf64_Off segEndOffset = segBaseOffset + seg->get_file_size(); + Elf64_Off segVBaseAddr = seg->get_virtual_address(); + Elf64_Off segVEndAddr = segVBaseAddr + seg->get_memory_size(); + for( Elf_Half j = 0; j < sections.size(); ++j ) { + const section* psec = sections[j]; + + // SHF_ALLOC sections are matched based on the virtual address + // otherwise the file offset is matched + if( psec->get_flags() & SHF_ALLOC + ? is_sect_in_seg( psec->get_address(), psec->get_size(), segVBaseAddr, segVEndAddr ) + : is_sect_in_seg( psec->get_offset(), psec->get_size(), segBaseOffset, segEndOffset )) { + // Alignment of segment shall not be updated, to preserve original value + // It will be re-calculated on saving. + seg->add_section_index( psec->get_index(), 0 ); + } + } + + // Add section into the segments' container + segments_.push_back( seg ); + } + + return true; + } + +//------------------------------------------------------------------------------ + bool save_header( std::ostream& stream ) { + return header->save( stream ); + } + +//------------------------------------------------------------------------------ + bool save_sections( std::ostream& stream ) { + for ( unsigned int i = 0; i < sections_.size(); ++i ) { + section *sec = sections_.at(i); + + std::streampos headerPosition = + (std::streamoff)header->get_sections_offset() + + header->get_section_entry_size() * sec->get_index(); + + sec->save(stream,headerPosition,sec->get_offset()); + } + return true; + } + +//------------------------------------------------------------------------------ + bool save_segments( std::ostream& stream ) { + for ( unsigned int i = 0; i < segments_.size(); ++i ) { + segment *seg = segments_.at(i); + + std::streampos headerPosition = header->get_segments_offset() + + header->get_segment_entry_size()*seg->get_index(); + + seg->save( stream, headerPosition, seg->get_offset() ); + } + return true; + } + +//------------------------------------------------------------------------------ + bool is_section_without_segment( unsigned int section_index ) { + bool found = false; + + for ( unsigned int j = 0; !found && ( j < segments.size() ); ++j ) { + for ( unsigned int k = 0; + !found && ( k < segments[j]->get_sections_num() ); + ++k ) { + found = segments[j]->get_section_index_at( k ) == section_index; + } + } + + return !found; + } + +//------------------------------------------------------------------------------ + bool is_subsequence_of( segment* seg1, segment* seg2 ) { + // Return 'true' if sections of seg1 are a subset of sections in seg2 + const std::vector& sections1 = seg1->get_sections(); + const std::vector& sections2 = seg2->get_sections(); + + bool found = false; + if ( sections1.size() < sections2.size() ) { + found = std::includes( sections2.begin(), sections2.end(), + sections1.begin(), sections1.end() ); + } + + return found; + } + +//------------------------------------------------------------------------------ + std::vector get_ordered_segments( ) { + std::vector res; + std::deque worklist; + + res.reserve(segments.size()); + std::copy( segments_.begin(), segments_.end(), + std::back_inserter( worklist )) ; + + // Bring the segments which start at address 0 to the front + size_t nextSlot = 0; + for( size_t i = 0; i < worklist.size(); ++i ) { + if( i != nextSlot && worklist[i]->is_offset_initialized() + && worklist[i]->get_offset() == 0 ) { + if (worklist[nextSlot]->get_offset() == 0) { + ++nextSlot; + } + std::swap(worklist[i],worklist[nextSlot]); + ++nextSlot; + } + } + + while ( !worklist.empty() ) { + segment *seg = worklist.front(); + worklist.pop_front(); + + size_t i = 0; + for ( ; i < worklist.size(); ++i ) { + if ( is_subsequence_of( seg, worklist[i] ) ) { + break; + } + } + + if ( i < worklist.size() ) + worklist.push_back(seg); + else + res.push_back(seg); + } + + return res; + } + + +//------------------------------------------------------------------------------ + bool layout_sections_without_segments( ) { + for ( unsigned int i = 0; i < sections_.size(); ++i ) { + if ( is_section_without_segment( i ) ) { + section *sec = sections_[i]; + + Elf_Xword section_align = sec->get_addr_align(); + if ( section_align > 1 && current_file_pos % section_align != 0 ) { + current_file_pos += section_align - + current_file_pos % section_align; + } + + if ( 0 != sec->get_index() ) + sec->set_offset(current_file_pos); + + if ( SHT_NOBITS != sec->get_type() && + SHT_NULL != sec->get_type() ) { + current_file_pos += sec->get_size(); + } + } + } + + return true; + } + + +//------------------------------------------------------------------------------ + void calc_segment_alignment( ) { + for( std::vector::iterator s = segments_.begin(); s != segments_.end(); ++s ) { + segment* seg = *s; + for ( int i = 0; i < seg->get_sections_num(); ++i ) { + section* sect = sections_[ seg->get_section_index_at(i) ]; + if ( sect->get_addr_align() > seg->get_align() ) { + seg->set_align( sect->get_addr_align() ); + } + } + } + } + +//------------------------------------------------------------------------------ + bool layout_segments_and_their_sections( ) { + std::vector worklist; + std::vector section_generated(sections.size(),false); + + // Get segments in a order in where segments which contain a + // sub sequence of other segments are located at the end + worklist = get_ordered_segments(); + + for ( unsigned int i = 0; i < worklist.size(); ++i ) { + Elf_Xword segment_memory = 0; + Elf_Xword segment_filesize = 0; + Elf_Xword seg_start_pos = current_file_pos; + segment* seg = worklist[i]; + + // Special case: PHDR segment + // This segment contains the program headers but no sections + if ( seg->get_type() == PT_PHDR && seg->get_sections_num() == 0 ) { + seg_start_pos = header->get_segments_offset(); + segment_memory = segment_filesize = + header->get_segment_entry_size() * header->get_segments_num(); + } + // Special case: + // Segments which start with the NULL section and have further sections + else if ( seg->get_sections_num() > 1 + && sections[seg->get_section_index_at( 0 )]->get_type() == SHT_NULL ) { + seg_start_pos = 0; + if ( seg->get_sections_num() ) { + segment_memory = segment_filesize = current_file_pos; + } + } + // New segments with not generated sections + // have to be aligned + else if ( seg->get_sections_num() + && !section_generated[seg->get_section_index_at( 0 )] ) { + Elf_Xword align = seg->get_align() > 0 ? seg->get_align() : 1; + Elf64_Off cur_page_alignment = current_file_pos % align; + Elf64_Off req_page_alignment = seg->get_virtual_address() % align; + Elf64_Off error = req_page_alignment - cur_page_alignment; + + current_file_pos += ( seg->get_align() + error ) % align; + seg_start_pos = current_file_pos; + } else if ( seg->get_sections_num() ) { + seg_start_pos = sections[seg->get_section_index_at( 0 )]->get_offset(); + } + + // Write segment's data + for ( unsigned int j = 0; j < seg->get_sections_num(); ++j ) { + Elf_Half index = seg->get_section_index_at( j ); + + section* sec = sections[ index ]; + + // The NULL section is always generated + if ( SHT_NULL == sec->get_type()) { + section_generated[index] = true; + continue; + } + + Elf_Xword secAlign = 0; + // Fix up the alignment + if ( !section_generated[index] && sec->is_address_initialized() + && SHT_NOBITS != sec->get_type() + && SHT_NULL != sec->get_type() + && 0 != sec->get_size() ) { + // Align the sections based on the virtual addresses + // when possible (this is what matters for execution) + Elf64_Off req_offset = sec->get_address() - seg->get_virtual_address(); + Elf64_Off cur_offset = current_file_pos - seg_start_pos; + if ( req_offset < cur_offset) { + // something has gone awfully wrong, abort! + // secAlign would turn out negative, seeking backwards and overwriting previous data + return false; + } + secAlign = req_offset - cur_offset; + } else if (!section_generated[index] && !sec->is_address_initialized() ) { + // If no address has been specified then only the section + // alignment constraint has to be matched + Elf_Xword align = sec->get_addr_align(); + if (align == 0) { + align = 1; + } + Elf64_Off error = current_file_pos % align; + secAlign = ( align - error ) % align; + } else if (section_generated[index] ) { + // Alignment for already generated sections + secAlign = sec->get_offset() - seg_start_pos - segment_filesize; + } + + // Determine the segment file and memory sizes + // Special case .tbss section (NOBITS) in non TLS segment + if ( (sec->get_flags() & SHF_ALLOC) + && !( (sec->get_flags() & SHF_TLS) && (seg->get_type() != PT_TLS) + && ( SHT_NOBITS == sec->get_type())) ) + segment_memory += sec->get_size() + secAlign; + if ( SHT_NOBITS != sec->get_type() && SHT_NULL != sec->get_type() ) + segment_filesize += sec->get_size() + secAlign; + + // Nothing to be done when generating nested segments + if(section_generated[index]) { + continue; + } + + current_file_pos += secAlign; + + // Set the section addresses when missing + if ( !sec->is_address_initialized() ) + sec->set_address( seg->get_virtual_address() + + current_file_pos - seg_start_pos); + + if ( 0 != sec->get_index() ) + sec->set_offset(current_file_pos); + + if ( SHT_NOBITS != sec->get_type() && SHT_NULL != sec->get_type() ) + current_file_pos += sec->get_size(); + section_generated[index] = true; + } + + seg->set_file_size( segment_filesize ); + + // If we already have a memory size from loading an elf file (value > 0), + // it must not shrink! + // Memory size may be bigger than file size and it is the loader's job to do something + // with the surplus bytes in memory, like initializing them with a defined value. + if ( seg->get_memory_size() < segment_memory ) { + seg->set_memory_size( segment_memory ); + } + + seg->set_offset(seg_start_pos); + } + + return true; + } + +//------------------------------------------------------------------------------ + bool layout_section_table() { + // Simply place the section table at the end for now + Elf64_Off alignmentError = current_file_pos % 4; + current_file_pos += ( 4 - alignmentError ) % 4; + header->set_sections_offset(current_file_pos); + return true; + } + + +//------------------------------------------------------------------------------ +public: + friend class Sections; + class Sections { + public: +//------------------------------------------------------------------------------ + Sections( elfio* parent_ ) : + parent( parent_ ) { + } + +//------------------------------------------------------------------------------ + Elf_Half size() const { + return (Elf_Half)parent->sections_.size(); + } + +//------------------------------------------------------------------------------ + section* operator[]( unsigned int index ) const { + section* sec = 0; + + if ( index < parent->sections_.size() ) { + sec = parent->sections_[index]; + } + + return sec; + } + +//------------------------------------------------------------------------------ + section* operator[]( const std::string& name ) const { + section* sec = 0; + + std::vector::const_iterator it; + for ( it = parent->sections_.begin(); + it != parent->sections_.end(); + ++it ) { + if ( (*it)->get_name() == name ) { + sec = *it; + break; + } + } + + return sec; + } + +//------------------------------------------------------------------------------ + section* add( const std::string& name ) { + section* new_section = parent->create_section(); + new_section->set_name( name ); + + Elf_Half str_index = parent->get_section_name_str_index(); + section* string_table( parent->sections_[str_index] ); + string_section_accessor str_writer( string_table ); + Elf_Word pos = str_writer.add_string( name ); + new_section->set_name_string_offset( pos ); + + return new_section; + } + +//------------------------------------------------------------------------------ + std::vector::iterator begin() { + return parent->sections_.begin(); + } + +//------------------------------------------------------------------------------ + std::vector::iterator end() { + return parent->sections_.end(); + } + +//------------------------------------------------------------------------------ + std::vector::const_iterator begin() const { + return parent->sections_.cbegin(); + } + +//------------------------------------------------------------------------------ + std::vector::const_iterator end() const { + return parent->sections_.cend(); + } + +//------------------------------------------------------------------------------ + private: + elfio* parent; + } sections; + +//------------------------------------------------------------------------------ +public: + friend class Segments; + class Segments { + public: +//------------------------------------------------------------------------------ + Segments( elfio* parent_ ) : + parent( parent_ ) { + } + +//------------------------------------------------------------------------------ + Elf_Half size() const { + return (Elf_Half)parent->segments_.size(); + } + +//------------------------------------------------------------------------------ + segment* operator[]( unsigned int index ) const { + return parent->segments_[index]; + } + + +//------------------------------------------------------------------------------ + segment* add() { + return parent->create_segment(); + } + +//------------------------------------------------------------------------------ + std::vector::iterator begin() { + return parent->segments_.begin(); + } + +//------------------------------------------------------------------------------ + std::vector::iterator end() { + return parent->segments_.end(); + } + +//------------------------------------------------------------------------------ + std::vector::const_iterator begin() const { + return parent->segments_.cbegin(); + } + +//------------------------------------------------------------------------------ + std::vector::const_iterator end() const { + return parent->segments_.cend(); + } + +//------------------------------------------------------------------------------ + private: + elfio* parent; + } segments; + +//------------------------------------------------------------------------------ +private: + elf_header* header; + std::vector sections_; + std::vector segments_; + endianess_convertor convertor; + + Elf_Xword current_file_pos; +}; + +} // namespace ELFIO + +#include +#include +#include +#include + +#ifdef _MSC_VER +#pragma warning ( pop ) +#endif + +#endif // ELFIO_HPP diff --git a/source/elfio/elfio_dump.hpp b/source/elfio/elfio_dump.hpp new file mode 100644 index 0000000..4ace665 --- /dev/null +++ b/source/elfio/elfio_dump.hpp @@ -0,0 +1,976 @@ +/* +Copyright (C) 2001-2015 by Serge Lamikhov-Center + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef ELFIO_DUMP_HPP +#define ELFIO_DUMP_HPP + +#include +#include +#include +#include +#include +#include + +namespace ELFIO { + + +static struct class_table_t { + const char key; + const char* str; +} class_table [] = +{ + { ELFCLASS32, "ELF32" }, + { ELFCLASS64, "ELF64" }, +}; + + +static struct endian_table_t { + const char key; + const char* str; +} endian_table [] = +{ + { ELFDATANONE, "None" }, + { ELFDATA2LSB, "Little endian" }, + { ELFDATA2MSB, "Big endian" }, +}; + + +static struct version_table_t { + const Elf64_Word key; + const char* str; +} version_table [] = +{ + { EV_NONE , "None" }, + { EV_CURRENT, "Current" }, +}; + + +static struct type_table_t { + const Elf32_Half key; + const char* str; +} type_table [] = +{ + { ET_NONE, "No file type" }, + { ET_REL , "Relocatable file" }, + { ET_EXEC, "Executable file" }, + { ET_DYN , "Shared object file" }, + { ET_CORE, "Core file" }, +}; + + +static struct machine_table_t { + const Elf64_Half key; + const char* str; +} machine_table [] = +{ + { EM_NONE , "No machine" }, + { EM_M32 , "AT&T WE 32100" }, + { EM_SPARC , "SUN SPARC" }, + { EM_386 , "Intel 80386" }, + { EM_68K , "Motorola m68k family" }, + { EM_88K , "Motorola m88k family" }, + { EM_486 , "Intel 80486// Reserved for future use" }, + { EM_860 , "Intel 80860" }, + { EM_MIPS , "MIPS R3000 (officially, big-endian only)" }, + { EM_S370 , "IBM System/370" }, + { EM_MIPS_RS3_LE , "MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated" }, + { EM_res011 , "Reserved" }, + { EM_res012 , "Reserved" }, + { EM_res013 , "Reserved" }, + { EM_res014 , "Reserved" }, + { EM_PARISC , "HPPA" }, + { EM_res016 , "Reserved" }, + { EM_VPP550 , "Fujitsu VPP500" }, + { EM_SPARC32PLUS , "Sun's v8plus" }, + { EM_960 , "Intel 80960" }, + { EM_PPC , "PowerPC" }, + { EM_PPC64 , "64-bit PowerPC" }, + { EM_S390 , "IBM S/390" }, + { EM_SPU , "Sony/Toshiba/IBM SPU" }, + { EM_res024 , "Reserved" }, + { EM_res025 , "Reserved" }, + { EM_res026 , "Reserved" }, + { EM_res027 , "Reserved" }, + { EM_res028 , "Reserved" }, + { EM_res029 , "Reserved" }, + { EM_res030 , "Reserved" }, + { EM_res031 , "Reserved" }, + { EM_res032 , "Reserved" }, + { EM_res033 , "Reserved" }, + { EM_res034 , "Reserved" }, + { EM_res035 , "Reserved" }, + { EM_V800 , "NEC V800 series" }, + { EM_FR20 , "Fujitsu FR20" }, + { EM_RH32 , "TRW RH32" }, + { EM_MCORE , "Motorola M*Core // May also be taken by Fujitsu MMA" }, + { EM_RCE , "Old name for MCore" }, + { EM_ARM , "ARM" }, + { EM_OLD_ALPHA , "Digital Alpha" }, + { EM_SH , "Renesas (formerly Hitachi) / SuperH SH" }, + { EM_SPARCV9 , "SPARC v9 64-bit" }, + { EM_TRICORE , "Siemens Tricore embedded processor" }, + { EM_ARC , "ARC Cores" }, + { EM_H8_300 , "Renesas (formerly Hitachi) H8/300" }, + { EM_H8_300H , "Renesas (formerly Hitachi) H8/300H" }, + { EM_H8S , "Renesas (formerly Hitachi) H8S" }, + { EM_H8_500 , "Renesas (formerly Hitachi) H8/500" }, + { EM_IA_64 , "Intel IA-64 Processor" }, + { EM_MIPS_X , "Stanford MIPS-X" }, + { EM_COLDFIRE , "Motorola Coldfire" }, + { EM_68HC12 , "Motorola M68HC12" }, + { EM_MMA , "Fujitsu Multimedia Accelerator" }, + { EM_PCP , "Siemens PCP" }, + { EM_NCPU , "Sony nCPU embedded RISC processor" }, + { EM_NDR1 , "Denso NDR1 microprocesspr" }, + { EM_STARCORE , "Motorola Star*Core processor" }, + { EM_ME16 , "Toyota ME16 processor" }, + { EM_ST100 , "STMicroelectronics ST100 processor" }, + { EM_TINYJ , "Advanced Logic Corp. TinyJ embedded processor" }, + { EM_X86_64 , "Advanced Micro Devices X86-64 processor" }, + { EM_PDSP , "Sony DSP Processor" }, + { EM_PDP10 , "Digital Equipment Corp. PDP-10" }, + { EM_PDP11 , "Digital Equipment Corp. PDP-11" }, + { EM_FX66 , "Siemens FX66 microcontroller" }, + { EM_ST9PLUS , "STMicroelectronics ST9+ 8/16 bit microcontroller" }, + { EM_ST7 , "STMicroelectronics ST7 8-bit microcontroller" }, + { EM_68HC16 , "Motorola MC68HC16 Microcontroller" }, + { EM_68HC11 , "Motorola MC68HC11 Microcontroller" }, + { EM_68HC08 , "Motorola MC68HC08 Microcontroller" }, + { EM_68HC05 , "Motorola MC68HC05 Microcontroller" }, + { EM_SVX , "Silicon Graphics SVx" }, + { EM_ST19 , "STMicroelectronics ST19 8-bit cpu" }, + { EM_VAX , "Digital VAX" }, + { EM_CRIS , "Axis Communications 32-bit embedded processor" }, + { EM_JAVELIN , "Infineon Technologies 32-bit embedded cpu" }, + { EM_FIREPATH , "Element 14 64-bit DSP processor" }, + { EM_ZSP , "LSI Logic's 16-bit DSP processor" }, + { EM_MMIX , "Donald Knuth's educational 64-bit processor" }, + { EM_HUANY , "Harvard's machine-independent format" }, + { EM_PRISM , "SiTera Prism" }, + { EM_AVR , "Atmel AVR 8-bit microcontroller" }, + { EM_FR30 , "Fujitsu FR30" }, + { EM_D10V , "Mitsubishi D10V" }, + { EM_D30V , "Mitsubishi D30V" }, + { EM_V850 , "NEC v850" }, + { EM_M32R , "Renesas M32R (formerly Mitsubishi M32R)" }, + { EM_MN10300 , "Matsushita MN10300" }, + { EM_MN10200 , "Matsushita MN10200" }, + { EM_PJ , "picoJava" }, + { EM_OPENRISC , "OpenRISC 32-bit embedded processor" }, + { EM_ARC_A5 , "ARC Cores Tangent-A5" }, + { EM_XTENSA , "Tensilica Xtensa Architecture" }, + { EM_VIDEOCORE , "Alphamosaic VideoCore processor" }, + { EM_TMM_GPP , "Thompson Multimedia General Purpose Processor" }, + { EM_NS32K , "National Semiconductor 32000 series" }, + { EM_TPC , "Tenor Network TPC processor" }, + { EM_SNP1K , "Trebia SNP 1000 processor" }, + { EM_ST200 , "STMicroelectronics ST200 microcontroller" }, + { EM_IP2K , "Ubicom IP2022 micro controller" }, + { EM_MAX , "MAX Processor" }, + { EM_CR , "National Semiconductor CompactRISC" }, + { EM_F2MC16 , "Fujitsu F2MC16" }, + { EM_MSP430 , "TI msp430 micro controller" }, + { EM_BLACKFIN , "ADI Blackfin" }, + { EM_SE_C33 , "S1C33 Family of Seiko Epson processors" }, + { EM_SEP , "Sharp embedded microprocessor" }, + { EM_ARCA , "Arca RISC Microprocessor" }, + { EM_UNICORE , "Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University" }, + { EM_EXCESS , "eXcess: 16/32/64-bit configurable embedded CPU" }, + { EM_DXP , "Icera Semiconductor Inc. Deep Execution Processor" }, + { EM_ALTERA_NIOS2 , "Altera Nios II soft-core processor" }, + { EM_CRX , "National Semiconductor CRX" }, + { EM_XGATE , "Motorola XGATE embedded processor" }, + { EM_C166 , "Infineon C16x/XC16x processor" }, + { EM_M16C , "Renesas M16C series microprocessors" }, + { EM_DSPIC30F , "Microchip Technology dsPIC30F Digital Signal Controller" }, + { EM_CE , "Freescale Communication Engine RISC core" }, + { EM_M32C , "Renesas M32C series microprocessors" }, + { EM_res121 , "Reserved" }, + { EM_res122 , "Reserved" }, + { EM_res123 , "Reserved" }, + { EM_res124 , "Reserved" }, + { EM_res125 , "Reserved" }, + { EM_res126 , "Reserved" }, + { EM_res127 , "Reserved" }, + { EM_res128 , "Reserved" }, + { EM_res129 , "Reserved" }, + { EM_res130 , "Reserved" }, + { EM_TSK3000 , "Altium TSK3000 core" }, + { EM_RS08 , "Freescale RS08 embedded processor" }, + { EM_res133 , "Reserved" }, + { EM_ECOG2 , "Cyan Technology eCOG2 microprocessor" }, + { EM_SCORE , "Sunplus Score" }, + { EM_SCORE7 , "Sunplus S+core7 RISC processor" }, + { EM_DSP24 , "New Japan Radio (NJR) 24-bit DSP Processor" }, + { EM_VIDEOCORE3 , "Broadcom VideoCore III processor" }, + { EM_LATTICEMICO32, "RISC processor for Lattice FPGA architecture" }, + { EM_SE_C17 , "Seiko Epson C17 family" }, + { EM_TI_C6000 , "Texas Instruments TMS320C6000 DSP family" }, + { EM_TI_C2000 , "Texas Instruments TMS320C2000 DSP family" }, + { EM_TI_C5500 , "Texas Instruments TMS320C55x DSP family" }, + { EM_res143 , "Reserved" }, + { EM_res144 , "Reserved" }, + { EM_res145 , "Reserved" }, + { EM_res146 , "Reserved" }, + { EM_res147 , "Reserved" }, + { EM_res148 , "Reserved" }, + { EM_res149 , "Reserved" }, + { EM_res150 , "Reserved" }, + { EM_res151 , "Reserved" }, + { EM_res152 , "Reserved" }, + { EM_res153 , "Reserved" }, + { EM_res154 , "Reserved" }, + { EM_res155 , "Reserved" }, + { EM_res156 , "Reserved" }, + { EM_res157 , "Reserved" }, + { EM_res158 , "Reserved" }, + { EM_res159 , "Reserved" }, + { EM_MMDSP_PLUS , "STMicroelectronics 64bit VLIW Data Signal Processor" }, + { EM_CYPRESS_M8C , "Cypress M8C microprocessor" }, + { EM_R32C , "Renesas R32C series microprocessors" }, + { EM_TRIMEDIA , "NXP Semiconductors TriMedia architecture family" }, + { EM_QDSP6 , "QUALCOMM DSP6 Processor" }, + { EM_8051 , "Intel 8051 and variants" }, + { EM_STXP7X , "STMicroelectronics STxP7x family" }, + { EM_NDS32 , "Andes Technology compact code size embedded RISC processor family" }, + { EM_ECOG1 , "Cyan Technology eCOG1X family" }, + { EM_ECOG1X , "Cyan Technology eCOG1X family" }, + { EM_MAXQ30 , "Dallas Semiconductor MAXQ30 Core Micro-controllers" }, + { EM_XIMO16 , "New Japan Radio (NJR) 16-bit DSP Processor" }, + { EM_MANIK , "M2000 Reconfigurable RISC Microprocessor" }, + { EM_CRAYNV2 , "Cray Inc. NV2 vector architecture" }, + { EM_RX , "Renesas RX family" }, + { EM_METAG , "Imagination Technologies META processor architecture" }, + { EM_MCST_ELBRUS , "MCST Elbrus general purpose hardware architecture" }, + { EM_ECOG16 , "Cyan Technology eCOG16 family" }, + { EM_CR16 , "National Semiconductor CompactRISC 16-bit processor" }, + { EM_ETPU , "Freescale Extended Time Processing Unit" }, + { EM_SLE9X , "Infineon Technologies SLE9X core" }, + { EM_L1OM , "Intel L1OM" }, + { EM_INTEL181 , "Reserved by Intel" }, + { EM_INTEL182 , "Reserved by Intel" }, + { EM_res183 , "Reserved by ARM" }, + { EM_res184 , "Reserved by ARM" }, + { EM_AVR32 , "Atmel Corporation 32-bit microprocessor family" }, + { EM_STM8 , "STMicroeletronics STM8 8-bit microcontroller" }, + { EM_TILE64 , "Tilera TILE64 multicore architecture family" }, + { EM_TILEPRO , "Tilera TILEPro multicore architecture family" }, + { EM_MICROBLAZE , "Xilinx MicroBlaze 32-bit RISC soft processor core" }, + { EM_CUDA , "NVIDIA CUDA architecture " }, +}; + + +static struct section_type_table_t { + const Elf64_Half key; + const char* str; +} section_type_table [] = +{ + { SHT_NULL , "NULL" }, + { SHT_PROGBITS , "PROGBITS" }, + { SHT_SYMTAB , "SYMTAB" }, + { SHT_STRTAB , "STRTAB" }, + { SHT_RELA , "RELA" }, + { SHT_HASH , "HASH" }, + { SHT_DYNAMIC , "DYNAMIC" }, + { SHT_NOTE , "NOTE" }, + { SHT_NOBITS , "NOBITS" }, + { SHT_REL , "REL" }, + { SHT_SHLIB , "SHLIB" }, + { SHT_DYNSYM , "DYNSYM" }, + { SHT_INIT_ARRAY , "INIT_ARRAY" }, + { SHT_FINI_ARRAY , "FINI_ARRAY" }, + { SHT_PREINIT_ARRAY, "PREINIT_ARRAY" }, + { SHT_GROUP , "GROUP" }, + { SHT_SYMTAB_SHNDX , "SYMTAB_SHNDX " }, +}; + + +static struct segment_type_table_t { + const Elf_Word key; + const char* str; +} segment_type_table [] = +{ + { PT_NULL , "NULL" }, + { PT_LOAD , "LOAD" }, + { PT_DYNAMIC, "DYNAMIC" }, + { PT_INTERP , "INTERP" }, + { PT_NOTE , "NOTE" }, + { PT_SHLIB , "SHLIB" }, + { PT_PHDR , "PHDR" }, + { PT_TLS , "TLS" }, +}; + + +static struct segment_flag_table_t { + const Elf_Word key; + const char* str; +} segment_flag_table [] = +{ + { 0, "" }, + { 1, "X" }, + { 2, "W" }, + { 3, "WX" }, + { 4, "R" }, + { 5, "RX" }, + { 6, "RW" }, + { 7, "RWX" }, +}; + + +static struct symbol_bind_t { + const Elf_Word key; + const char* str; +} symbol_bind_table [] = +{ + { STB_LOCAL , "LOCAL" }, + { STB_GLOBAL , "GLOBAL" }, + { STB_WEAK , "WEAK" }, + { STB_LOOS , "LOOS" }, + { STB_HIOS , "HIOS" }, + { STB_MULTIDEF, "MULTIDEF" }, + { STB_LOPROC , "LOPROC" }, + { STB_HIPROC , "HIPROC" }, +}; + + +static struct symbol_type_t { + const Elf_Word key; + const char* str; +} symbol_type_table [] = +{ + { STT_NOTYPE , "NOTYPE" }, + { STT_OBJECT , "OBJECT" }, + { STT_FUNC , "FUNC" }, + { STT_SECTION, "SECTION" }, + { STT_FILE , "FILE" }, + { STT_COMMON , "COMMON" }, + { STT_TLS , "TLS" }, + { STT_LOOS , "LOOS" }, + { STT_HIOS , "HIOS" }, + { STT_LOPROC , "LOPROC" }, + { STT_HIPROC , "HIPROC" }, +}; + + +static struct dynamic_tag_t { + const Elf_Word key; + const char* str; +} dynamic_tag_table [] = +{ + { DT_NULL , "NULL" }, + { DT_NEEDED , "NEEDED" }, + { DT_PLTRELSZ , "PLTRELSZ" }, + { DT_PLTGOT , "PLTGOT" }, + { DT_HASH , "HASH" }, + { DT_STRTAB , "STRTAB" }, + { DT_SYMTAB , "SYMTAB" }, + { DT_RELA , "RELA" }, + { DT_RELASZ , "RELASZ" }, + { DT_RELAENT , "RELAENT" }, + { DT_STRSZ , "STRSZ" }, + { DT_SYMENT , "SYMENT" }, + { DT_INIT , "INIT" }, + { DT_FINI , "FINI" }, + { DT_SONAME , "SONAME" }, + { DT_RPATH , "RPATH" }, + { DT_SYMBOLIC , "SYMBOLIC" }, + { DT_REL , "REL" }, + { DT_RELSZ , "RELSZ" }, + { DT_RELENT , "RELENT" }, + { DT_PLTREL , "PLTREL" }, + { DT_DEBUG , "DEBUG" }, + { DT_TEXTREL , "TEXTREL" }, + { DT_JMPREL , "JMPREL" }, + { DT_BIND_NOW , "BIND_NOW" }, + { DT_INIT_ARRAY , "INIT_ARRAY" }, + { DT_FINI_ARRAY , "FINI_ARRAY" }, + { DT_INIT_ARRAYSZ , "INIT_ARRAYSZ" }, + { DT_FINI_ARRAYSZ , "FINI_ARRAYSZ" }, + { DT_RUNPATH , "RUNPATH" }, + { DT_FLAGS , "FLAGS" }, + { DT_ENCODING , "ENCODING" }, + { DT_PREINIT_ARRAY , "PREINIT_ARRAY" }, + { DT_PREINIT_ARRAYSZ, "PREINIT_ARRAYSZ" }, + { DT_MAXPOSTAGS , "MAXPOSTAGS" }, +}; + +static const ELFIO::Elf_Xword MAX_DATA_ENTRIES = 64; + +//------------------------------------------------------------------------------ +class dump +{ +#define DUMP_DEC_FORMAT( width ) std::setw(width) << std::setfill( ' ' ) << \ + std::dec << std::right +#define DUMP_HEX_FORMAT( width ) std::setw(width) << std::setfill( '0' ) << \ + std::hex << std::right +#define DUMP_STR_FORMAT( width ) std::setw(width) << std::setfill( ' ' ) << \ + std::hex << std::left + + public: +//------------------------------------------------------------------------------ + static void + header( std::ostream& out, const elfio& reader ) + { + if (!reader.get_header_size()) + { + return; + } + out << "ELF Header" << std::endl << std::endl + << " Class: " << str_class( reader.get_class() ) << std::endl + << " Encoding: " << str_endian( reader.get_encoding() ) << std::endl + << " ELFVersion: " << str_version( reader.get_elf_version() ) << std::endl + << " Type: " << str_type( reader.get_type() ) << std::endl + << " Machine: " << str_machine( reader.get_machine() ) << std::endl + << " Version: " << str_version( reader.get_version() ) << std::endl + << " Entry: " << "0x" << std::hex << reader.get_entry() << std::endl + << " Flags: " << "0x" << std::hex << reader.get_flags() << std::endl + << std::endl; + } + +//------------------------------------------------------------------------------ + static void + section_headers( std::ostream& out, const elfio& reader ) + { + Elf_Half n = reader.sections.size(); + + if ( n == 0 ) { + return; + } + + out << "Section Headers:" << std::endl; + if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit + out << "[ Nr ] Type Addr Size ES Flg Lk Inf Al Name" << std::endl; + } + else { // Output for 64-bit + out << "[ Nr ] Type Addr Size ES Flg" << std::endl + << " Lk Inf Al Name" << std::endl; + } + + for ( Elf_Half i = 0; i < n; ++i ) { // For all sections + section* sec = reader.sections[i]; + section_header( out, i, sec, reader.get_class() ); + } + + out << "Key to Flags: W (write), A (alloc), X (execute)\n\n" + << std::endl; + } + +//------------------------------------------------------------------------------ + static void + section_header( std::ostream& out, Elf_Half no, const section* sec, + unsigned char elf_class ) + { + std::ios_base::fmtflags original_flags = out.flags(); + + if ( elf_class == ELFCLASS32 ) { // Output for 32-bit + out << "[" + << DUMP_DEC_FORMAT( 5 ) << no + << "] " + << DUMP_STR_FORMAT( 17 ) << str_section_type( sec->get_type() ) << " " + << DUMP_HEX_FORMAT( 8 ) << sec->get_address() << " " + << DUMP_HEX_FORMAT( 8 ) << sec->get_size() << " " + << DUMP_HEX_FORMAT( 2 ) << sec->get_entry_size() << " " + << DUMP_STR_FORMAT( 3 ) << section_flags( sec->get_flags() ) << " " + << DUMP_HEX_FORMAT( 2 ) << sec->get_link() << " " + << DUMP_HEX_FORMAT( 3 ) << sec->get_info() << " " + << DUMP_HEX_FORMAT( 2 ) << sec->get_addr_align() << " " + << DUMP_STR_FORMAT( 17 ) << sec->get_name() << " " + << std::endl; + } + else { // Output for 64-bit + out << "[" + << DUMP_DEC_FORMAT( 5 ) << no + << "] " + << DUMP_STR_FORMAT( 17 ) << str_section_type( sec->get_type() ) << " " + << DUMP_HEX_FORMAT( 16 ) << sec->get_address() << " " + << DUMP_HEX_FORMAT( 16 ) << sec->get_size() << " " + << DUMP_HEX_FORMAT( 4 ) << sec->get_entry_size() << " " + << DUMP_STR_FORMAT( 3 ) << section_flags( sec->get_flags() ) << " " + << std::endl + << " " + << DUMP_HEX_FORMAT( 4 ) << sec->get_link() << " " + << DUMP_HEX_FORMAT( 4 ) << sec->get_info() << " " + << DUMP_HEX_FORMAT( 4 ) << sec->get_addr_align() << " " + << DUMP_STR_FORMAT( 17 ) << sec->get_name() << " " + << std::endl; + } + + out.flags(original_flags); + + return; + } + +//------------------------------------------------------------------------------ + static void + segment_headers( std::ostream& out, const elfio& reader ) + { + Elf_Half n = reader.segments.size(); + if ( n == 0 ) { + return; + } + + out << "Segment headers:" << std::endl; + if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit + out << "[ Nr ] Type VirtAddr PhysAddr FileSize Mem.Size Flags Align" + << std::endl; + } + else { // Output for 64-bit + out << "[ Nr ] Type VirtAddr PhysAddr Flags" << std::endl + << " FileSize Mem.Size Align" + << std::endl; + } + + for ( Elf_Half i = 0; i < n; ++i ) { + segment* seg = reader.segments[i]; + segment_header( out, i, seg, reader.get_class() ); + } + + out << std::endl; + } + +//------------------------------------------------------------------------------ + static void + segment_header( std::ostream& out, Elf_Half no, const segment* seg, + unsigned int elf_class ) + { + std::ios_base::fmtflags original_flags = out.flags(); + + if ( elf_class == ELFCLASS32 ) { // Output for 32-bit + out << "[" + << DUMP_DEC_FORMAT( 5 ) << no + << "] " + << DUMP_STR_FORMAT( 14 ) << str_segment_type( seg->get_type() ) << " " + << DUMP_HEX_FORMAT( 8 ) << seg->get_virtual_address() << " " + << DUMP_HEX_FORMAT( 8 ) << seg->get_physical_address() << " " + << DUMP_HEX_FORMAT( 8 ) << seg->get_file_size() << " " + << DUMP_HEX_FORMAT( 8 ) << seg->get_memory_size() << " " + << DUMP_STR_FORMAT( 8 ) << str_segment_flag( seg->get_flags() ) << " " + << DUMP_HEX_FORMAT( 8 ) << seg->get_align() << " " + << std::endl; + } + else { // Output for 64-bit + out << "[" + << DUMP_DEC_FORMAT( 5 ) << no + << "] " + << DUMP_STR_FORMAT( 14 ) << str_segment_type( seg->get_type() ) << " " + << DUMP_HEX_FORMAT( 16 ) << seg->get_virtual_address() << " " + << DUMP_HEX_FORMAT( 16 ) << seg->get_physical_address() << " " + << DUMP_STR_FORMAT( 16 ) << str_segment_flag( seg->get_flags() ) << " " + << std::endl + << " " + << DUMP_HEX_FORMAT( 16 ) << seg->get_file_size() << " " + << DUMP_HEX_FORMAT( 16 ) << seg->get_memory_size() << " " + << DUMP_HEX_FORMAT( 16 ) << seg->get_align() << " " + << std::endl; + } + + out.flags(original_flags); + } + +//------------------------------------------------------------------------------ + static void + symbol_tables( std::ostream& out, const elfio& reader ) + { + Elf_Half n = reader.sections.size(); + for ( Elf_Half i = 0; i < n; ++i ) { // For all sections + section* sec = reader.sections[i]; + if ( SHT_SYMTAB == sec->get_type() || SHT_DYNSYM == sec->get_type() ) { + symbol_section_accessor symbols( reader, sec ); + + Elf_Xword sym_no = symbols.get_symbols_num(); + if ( sym_no > 0 ) { + out << "Symbol table (" << sec->get_name() << ")" << std::endl; + if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit + out << "[ Nr ] Value Size Type Bind Sect Name" + << std::endl; + } + else { // Output for 64-bit + out << "[ Nr ] Value Size Type Bind Sect" << std::endl + << " Name" + << std::endl; + } + for ( Elf_Half i = 0; i < sym_no; ++i ) { + std::string name; + Elf64_Addr value = 0; + Elf_Xword size = 0; + unsigned char bind = 0; + unsigned char type = 0; + Elf_Half section = 0; + unsigned char other = 0; + symbols.get_symbol( i, name, value, size, bind, type, section, other ); + symbol_table( out, i, name, value, size, bind, type, section, reader.get_class() ); + } + + out << std::endl; + } + } + } + } + +//------------------------------------------------------------------------------ + static void + symbol_table( std::ostream& out, + Elf_Half no, + std::string& name, + Elf64_Addr value, + Elf_Xword size, + unsigned char bind, + unsigned char type, + Elf_Half section, + unsigned int elf_class ) + { + std::ios_base::fmtflags original_flags = out.flags(); + + if ( elf_class == ELFCLASS32 ) { // Output for 32-bit + out << "[" + << DUMP_DEC_FORMAT( 5 ) << no + << "] " + << DUMP_HEX_FORMAT( 8 ) << value << " " + << DUMP_HEX_FORMAT( 8 ) << size << " " + << DUMP_STR_FORMAT( 7 ) << str_symbol_type( type ) << " " + << DUMP_STR_FORMAT( 8 ) << str_symbol_bind( bind ) << " " + << DUMP_DEC_FORMAT( 5 ) << section << " " + << DUMP_STR_FORMAT( 1 ) << name << " " + << std::endl; + } + else { // Output for 64-bit + out << "[" + << DUMP_DEC_FORMAT( 5 ) << no + << "] " + << DUMP_HEX_FORMAT( 16 ) << value << " " + << DUMP_HEX_FORMAT( 16 ) << size << " " + << DUMP_STR_FORMAT( 7 ) << str_symbol_type( type ) << " " + << DUMP_STR_FORMAT( 8 ) << str_symbol_bind( bind ) << " " + << DUMP_DEC_FORMAT( 5 ) << section << " " + << std::endl + << " " + << DUMP_STR_FORMAT( 1 ) << name << " " + << std::endl; + } + + out.flags(original_flags); + } + +//------------------------------------------------------------------------------ + static void + notes( std::ostream& out, const elfio& reader ) + { + Elf_Half no = reader.sections.size(); + for ( Elf_Half i = 0; i < no; ++i ) { // For all sections + section* sec = reader.sections[i]; + if ( SHT_NOTE == sec->get_type() ) { // Look at notes + note_section_accessor notes( reader, sec ); + int no_notes = notes.get_notes_num(); + if ( no > 0 ) { + out << "Note section (" << sec->get_name() << ")" << std::endl + << " No Type Name" + << std::endl; + for ( int j = 0; j < no_notes; ++j ) { // For all notes + Elf_Word type; + std::string name; + void* desc; + Elf_Word descsz; + + if ( notes.get_note(j, type, name, desc, descsz) ) { + // 'name' usually contains \0 at the end. Try to fix it + name = name.c_str(); + note( out, j, type, name ); + } + } + + out << std::endl; + } + } + } + } + +//------------------------------------------------------------------------------ + static void + note( std::ostream& out, + int no, + Elf_Word type, + const std::string& name ) + { + out << " [" + << DUMP_DEC_FORMAT( 2 ) << no + << "] " + << DUMP_HEX_FORMAT( 8 ) << type << " " + << DUMP_STR_FORMAT( 1 ) << name + << std::endl; + } + +//------------------------------------------------------------------------------ + static void + dynamic_tags( std::ostream& out, const elfio& reader ) + { + Elf_Half n = reader.sections.size(); + for ( Elf_Half i = 0; i < n; ++i ) { // For all sections + section* sec = reader.sections[i]; + if ( SHT_DYNAMIC == sec->get_type() ) { + dynamic_section_accessor dynamic( reader, sec ); + + Elf_Xword dyn_no = dynamic.get_entries_num(); + if ( dyn_no > 0 ) { + out << "Dynamic section (" << sec->get_name() << ")" << std::endl; + out << "[ Nr ] Tag Name/Value" << std::endl; + for ( Elf_Xword i = 0; i < dyn_no; ++i ) { + Elf_Xword tag = 0; + Elf_Xword value = 0; + std::string str; + dynamic.get_entry( i, tag, value, str ); + dynamic_tag( out, i, tag, value, str, reader.get_class() ); + if ( DT_NULL == tag ) { + break; + } + } + + out << std::endl; + } + } + } + } + +//------------------------------------------------------------------------------ + static void + dynamic_tag( std::ostream& out, + Elf_Xword no, + Elf_Xword tag, + Elf_Xword value, + std::string str, + unsigned int /*elf_class*/ ) + { + out << "[" + << DUMP_DEC_FORMAT( 5 ) << no + << "] " + << DUMP_STR_FORMAT( 16 ) << str_dynamic_tag( tag ) << " "; + if ( str.empty() ) { + out << DUMP_HEX_FORMAT( 16 ) << value << " "; + } + else { + out << DUMP_STR_FORMAT( 32 ) << str << " "; + } + out << std::endl; + } + +//------------------------------------------------------------------------------ + static void + section_data( std::ostream& out, const section* sec ) + { + std::ios_base::fmtflags original_flags = out.flags(); + + out << sec->get_name() << std::endl; + const char* pdata = sec->get_data(); + if ( pdata ){ + ELFIO::Elf_Xword i; + for ( i = 0; i < std::min( sec->get_size(), MAX_DATA_ENTRIES ); ++i ) { + if ( i % 16 == 0 ) { + out << "[" << DUMP_HEX_FORMAT( 8 ) << i << "]"; + } + + out << " " << DUMP_HEX_FORMAT( 2 ) << ( pdata[i] & 0x000000FF ); + + if ( i % 16 == 15 ) { + out << std::endl; + } + } + if ( i % 16 != 0 ) { + out << std::endl; + } + + out.flags(original_flags); + } + + return; + } + +//------------------------------------------------------------------------------ + static void + section_datas( std::ostream& out, const elfio& reader ) + { + Elf_Half n = reader.sections.size(); + + if ( n == 0 ) { + return; + } + + out << "Section Data:" << std::endl; + + for ( Elf_Half i = 1; i < n; ++i ) { // For all sections + section* sec = reader.sections[i]; + if ( sec->get_type() == SHT_NOBITS ) { + continue; + } + section_data( out, sec ); + } + + out << std::endl; + } + +//------------------------------------------------------------------------------ + static void + segment_data( std::ostream& out, Elf_Half no, const segment* seg ) + { + std::ios_base::fmtflags original_flags = out.flags(); + + out << "Segment # " << no << std::endl; + const char* pdata = seg->get_data(); + if ( pdata ) { + ELFIO::Elf_Xword i; + for ( i = 0; i < std::min( seg->get_file_size(), MAX_DATA_ENTRIES ); ++i ) { + if ( i % 16 == 0 ) { + out << "[" << DUMP_HEX_FORMAT( 8 ) << i << "]"; + } + + out << " " << DUMP_HEX_FORMAT( 2 ) << ( pdata[i] & 0x000000FF ); + + if ( i % 16 == 15 ) { + out << std::endl; + } + } + if ( i % 16 != 0 ) { + out << std::endl; + } + + out.flags(original_flags); + } + + return; + } + +//------------------------------------------------------------------------------ + static void + segment_datas( std::ostream& out, const elfio& reader ) + { + Elf_Half n = reader.segments.size(); + + if ( n == 0 ) { + return; + } + + out << "Segment Data:" << std::endl; + + for ( Elf_Half i = 0; i < n; ++i ) { // For all sections + segment* seg = reader.segments[i]; + segment_data( out, i, seg ); + } + + out << std::endl; + } + + private: +//------------------------------------------------------------------------------ + template< typename T, typename K > + std::string + static + find_value_in_table( const T& table, const K& key ) + { + std::string res = "?"; + for ( unsigned int i = 0; i < sizeof( table )/sizeof( table[0] ); ++i ) { + if ( table[i].key == key ) { + res = table[i].str; + break; + } + } + + return res; + } + + +//------------------------------------------------------------------------------ + template< typename T, typename K > + static + std::string + format_assoc( const T& table, const K& key ) + { + std::string str = find_value_in_table( table, key ); + if ( str == "?" ) { + std::ostringstream oss; + oss << str << " (0x" << std::hex << key << ")"; + str = oss.str(); + } + + return str; + } + + +//------------------------------------------------------------------------------ + template< typename T > + static + std::string + format_assoc( const T& table, const char key ) + { + return format_assoc( table, (const int)key ); + } + + +//------------------------------------------------------------------------------ + static + std::string + section_flags( Elf_Xword flags ) + { + std::string ret = ""; + if ( flags & SHF_WRITE ) { + ret += "W"; + } + if ( flags & SHF_ALLOC ) { + ret += "A"; + } + if ( flags & SHF_EXECINSTR ) { + ret += "X"; + } + + return ret; + } + + +//------------------------------------------------------------------------------ +#define STR_FUNC_TABLE( name ) \ + template< typename T > \ + static \ + std::string \ + str_##name( const T key ) \ + { \ + return format_assoc( name##_table, key ); \ + } + + STR_FUNC_TABLE( class ) + STR_FUNC_TABLE( endian ) + STR_FUNC_TABLE( version ) + STR_FUNC_TABLE( type ) + STR_FUNC_TABLE( machine ) + STR_FUNC_TABLE( section_type ) + STR_FUNC_TABLE( segment_type ) + STR_FUNC_TABLE( segment_flag ) + STR_FUNC_TABLE( symbol_bind ) + STR_FUNC_TABLE( symbol_type ) + STR_FUNC_TABLE( dynamic_tag ) + +#undef STR_FUNC_TABLE +#undef DUMP_DEC_FORMAT +#undef DUMP_HEX_FORMAT +#undef DUMP_STR_FORMAT +}; // class dump + + +}; // namespace ELFIO + +#endif // ELFIO_DUMP_HPP diff --git a/source/elfio/elfio_dynamic.hpp b/source/elfio/elfio_dynamic.hpp new file mode 100644 index 0000000..42f2680 --- /dev/null +++ b/source/elfio/elfio_dynamic.hpp @@ -0,0 +1,257 @@ +/* +Copyright (C) 2001-2015 by Serge Lamikhov-Center + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef ELFIO_DYNAMIC_HPP +#define ELFIO_DYNAMIC_HPP + +namespace ELFIO { + +//------------------------------------------------------------------------------ +template< class S > +class dynamic_section_accessor_template +{ + public: +//------------------------------------------------------------------------------ + dynamic_section_accessor_template( const elfio& elf_file_, S* section_ ) : + elf_file( elf_file_ ), + dynamic_section( section_ ) + { + } + +//------------------------------------------------------------------------------ + Elf_Xword + get_entries_num() const + { + Elf_Xword nRet = 0; + + if ( 0 != dynamic_section->get_entry_size() ) { + nRet = dynamic_section->get_size() / dynamic_section->get_entry_size(); + } + + return nRet; + } + +//------------------------------------------------------------------------------ + bool + get_entry( Elf_Xword index, + Elf_Xword& tag, + Elf_Xword& value, + std::string& str ) const + { + if ( index >= get_entries_num() ) { // Is index valid + return false; + } + + if ( elf_file.get_class() == ELFCLASS32 ) { + generic_get_entry_dyn< Elf32_Dyn >( index, tag, value ); + } + else { + generic_get_entry_dyn< Elf64_Dyn >( index, tag, value ); + } + + // If the tag may have a string table reference, prepare the string + if ( tag == DT_NEEDED || + tag == DT_SONAME || + tag == DT_RPATH || + tag == DT_RUNPATH ) { + string_section_accessor strsec = + elf_file.sections[ get_string_table_index() ]; + const char* result = strsec.get_string( value ); + if ( 0 == result ) { + str.clear(); + return false; + } + str = result; + } + else { + str.clear(); + } + + return true; + } + +//------------------------------------------------------------------------------ + void + add_entry( Elf_Xword tag, + Elf_Xword value ) + { + if ( elf_file.get_class() == ELFCLASS32 ) { + generic_add_entry< Elf32_Dyn >( tag, value ); + } + else { + generic_add_entry< Elf64_Dyn >( tag, value ); + } + } + +//------------------------------------------------------------------------------ + void + add_entry( Elf_Xword tag, + const std::string& str ) + { + string_section_accessor strsec = + elf_file.sections[ get_string_table_index() ]; + Elf_Xword value = strsec.add_string( str ); + add_entry( tag, value ); + } + +//------------------------------------------------------------------------------ + private: +//------------------------------------------------------------------------------ + Elf_Half + get_string_table_index() const + { + return (Elf_Half)dynamic_section->get_link(); + } + +//------------------------------------------------------------------------------ + template< class T > + void + generic_get_entry_dyn( Elf_Xword index, + Elf_Xword& tag, + Elf_Xword& value ) const + { + const endianess_convertor& convertor = elf_file.get_convertor(); + + // Check unusual case when dynamic section has no data + if( dynamic_section->get_data() == 0 || + ( index + 1 ) * dynamic_section->get_entry_size() > dynamic_section->get_size() ) { + tag = DT_NULL; + value = 0; + return; + } + + const T* pEntry = reinterpret_cast( + dynamic_section->get_data() + + index * dynamic_section->get_entry_size() ); + tag = convertor( pEntry->d_tag ); + switch ( tag ) { + case DT_NULL: + case DT_SYMBOLIC: + case DT_TEXTREL: + case DT_BIND_NOW: + value = 0; + break; + case DT_NEEDED: + case DT_PLTRELSZ: + case DT_RELASZ: + case DT_RELAENT: + case DT_STRSZ: + case DT_SYMENT: + case DT_SONAME: + case DT_RPATH: + case DT_RELSZ: + case DT_RELENT: + case DT_PLTREL: + case DT_INIT_ARRAYSZ: + case DT_FINI_ARRAYSZ: + case DT_RUNPATH: + case DT_FLAGS: + case DT_PREINIT_ARRAYSZ: + value = convertor( pEntry->d_un.d_val ); + break; + case DT_PLTGOT: + case DT_HASH: + case DT_STRTAB: + case DT_SYMTAB: + case DT_RELA: + case DT_INIT: + case DT_FINI: + case DT_REL: + case DT_DEBUG: + case DT_JMPREL: + case DT_INIT_ARRAY: + case DT_FINI_ARRAY: + case DT_PREINIT_ARRAY: + default: + value = convertor( pEntry->d_un.d_ptr ); + break; + } + } + +//------------------------------------------------------------------------------ + template< class T > + void + generic_add_entry( Elf_Xword tag, Elf_Xword value ) + { + const endianess_convertor& convertor = elf_file.get_convertor(); + + T entry; + + switch ( tag ) { + case DT_NULL: + case DT_SYMBOLIC: + case DT_TEXTREL: + case DT_BIND_NOW: + value = 0; + case DT_NEEDED: + case DT_PLTRELSZ: + case DT_RELASZ: + case DT_RELAENT: + case DT_STRSZ: + case DT_SYMENT: + case DT_SONAME: + case DT_RPATH: + case DT_RELSZ: + case DT_RELENT: + case DT_PLTREL: + case DT_INIT_ARRAYSZ: + case DT_FINI_ARRAYSZ: + case DT_RUNPATH: + case DT_FLAGS: + case DT_PREINIT_ARRAYSZ: + entry.d_un.d_val = convertor( value ); + break; + case DT_PLTGOT: + case DT_HASH: + case DT_STRTAB: + case DT_SYMTAB: + case DT_RELA: + case DT_INIT: + case DT_FINI: + case DT_REL: + case DT_DEBUG: + case DT_JMPREL: + case DT_INIT_ARRAY: + case DT_FINI_ARRAY: + case DT_PREINIT_ARRAY: + default: + entry.d_un.d_ptr = convertor( value ); + break; + } + + entry.d_tag = convertor( tag ); + + dynamic_section->append_data( reinterpret_cast( &entry ), sizeof( entry ) ); + } + +//------------------------------------------------------------------------------ + private: + const elfio& elf_file; + S* dynamic_section; +}; + +using dynamic_section_accessor = dynamic_section_accessor_template
; +using const_dynamic_section_accessor = dynamic_section_accessor_template; + +} // namespace ELFIO + +#endif // ELFIO_DYNAMIC_HPP diff --git a/source/elfio/elfio_header.hpp b/source/elfio/elfio_header.hpp new file mode 100644 index 0000000..6f8da02 --- /dev/null +++ b/source/elfio/elfio_header.hpp @@ -0,0 +1,145 @@ +/* +Copyright (C) 2001-2015 by Serge Lamikhov-Center + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef ELF_HEADER_HPP +#define ELF_HEADER_HPP + +#include + +namespace ELFIO { + +class elf_header +{ + public: + virtual ~elf_header() {}; + virtual bool load( std::istream& stream ) = 0; + virtual bool save( std::ostream& stream ) const = 0; + + // ELF header functions + ELFIO_GET_ACCESS_DECL( unsigned char, class ); + ELFIO_GET_ACCESS_DECL( unsigned char, elf_version ); + ELFIO_GET_ACCESS_DECL( unsigned char, encoding ); + ELFIO_GET_ACCESS_DECL( Elf_Half, header_size ); + ELFIO_GET_ACCESS_DECL( Elf_Half, section_entry_size ); + ELFIO_GET_ACCESS_DECL( Elf_Half, segment_entry_size ); + + ELFIO_GET_SET_ACCESS_DECL( Elf_Word, version ); + ELFIO_GET_SET_ACCESS_DECL( unsigned char, os_abi ); + ELFIO_GET_SET_ACCESS_DECL( unsigned char, abi_version ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Half, type ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Half, machine ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags ); + ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, entry ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Half, sections_num ); + ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, sections_offset ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Half, segments_num ); + ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, segments_offset ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Half, section_name_str_index ); +}; + + +template< class T > struct elf_header_impl_types; +template<> struct elf_header_impl_types { + typedef Elf32_Phdr Phdr_type; + typedef Elf32_Shdr Shdr_type; + static const unsigned char file_class = ELFCLASS32; +}; +template<> struct elf_header_impl_types { + typedef Elf64_Phdr Phdr_type; + typedef Elf64_Shdr Shdr_type; + static const unsigned char file_class = ELFCLASS64; +}; + +template< class T > class elf_header_impl : public elf_header +{ + public: + elf_header_impl( endianess_convertor* convertor_, + unsigned char encoding ) + { + convertor = convertor_; + + std::fill_n( reinterpret_cast( &header ), sizeof( header ), '\0' ); + + header.e_ident[EI_MAG0] = ELFMAG0; + header.e_ident[EI_MAG1] = ELFMAG1; + header.e_ident[EI_MAG2] = ELFMAG2; + header.e_ident[EI_MAG3] = ELFMAG3; + header.e_ident[EI_CLASS] = elf_header_impl_types::file_class; + header.e_ident[EI_DATA] = encoding; + header.e_ident[EI_VERSION] = EV_CURRENT; + header.e_version = (*convertor)( (Elf_Word)EV_CURRENT ); + header.e_ehsize = ( sizeof( header ) ); + header.e_ehsize = (*convertor)( header.e_ehsize ); + header.e_shstrndx = (*convertor)( (Elf_Half)1 ); + header.e_phentsize = sizeof( typename elf_header_impl_types::Phdr_type ); + header.e_shentsize = sizeof( typename elf_header_impl_types::Shdr_type ); + header.e_phentsize = (*convertor)( header.e_phentsize ); + header.e_shentsize = (*convertor)( header.e_shentsize ); + } + + bool + load( std::istream& stream ) + { + stream.seekg( 0 ); + stream.read( reinterpret_cast( &header ), sizeof( header ) ); + + return (stream.gcount() == sizeof( header ) ); + } + + bool + save( std::ostream& stream ) const + { + stream.seekp( 0 ); + stream.write( reinterpret_cast( &header ), sizeof( header ) ); + + return stream.good(); + } + + // ELF header functions + ELFIO_GET_ACCESS( unsigned char, class, header.e_ident[EI_CLASS] ); + ELFIO_GET_ACCESS( unsigned char, elf_version, header.e_ident[EI_VERSION] ); + ELFIO_GET_ACCESS( unsigned char, encoding, header.e_ident[EI_DATA] ); + ELFIO_GET_ACCESS( Elf_Half, header_size, header.e_ehsize ); + ELFIO_GET_ACCESS( Elf_Half, section_entry_size, header.e_shentsize ); + ELFIO_GET_ACCESS( Elf_Half, segment_entry_size, header.e_phentsize ); + + ELFIO_GET_SET_ACCESS( Elf_Word, version, header.e_version); + ELFIO_GET_SET_ACCESS( unsigned char, os_abi, header.e_ident[EI_OSABI] ); + ELFIO_GET_SET_ACCESS( unsigned char, abi_version, header.e_ident[EI_ABIVERSION] ); + ELFIO_GET_SET_ACCESS( Elf_Half, type, header.e_type ); + ELFIO_GET_SET_ACCESS( Elf_Half, machine, header.e_machine ); + ELFIO_GET_SET_ACCESS( Elf_Word, flags, header.e_flags ); + ELFIO_GET_SET_ACCESS( Elf_Half, section_name_str_index, header.e_shstrndx ); + ELFIO_GET_SET_ACCESS( Elf64_Addr, entry, header.e_entry ); + ELFIO_GET_SET_ACCESS( Elf_Half, sections_num, header.e_shnum ); + ELFIO_GET_SET_ACCESS( Elf64_Off, sections_offset, header.e_shoff ); + ELFIO_GET_SET_ACCESS( Elf_Half, segments_num, header.e_phnum ); + ELFIO_GET_SET_ACCESS( Elf64_Off, segments_offset, header.e_phoff ); + + private: + T header; + endianess_convertor* convertor; +}; + +} // namespace ELFIO + +#endif // ELF_HEADER_HPP diff --git a/source/elfio/elfio_note.hpp b/source/elfio/elfio_note.hpp new file mode 100644 index 0000000..8619c73 --- /dev/null +++ b/source/elfio/elfio_note.hpp @@ -0,0 +1,170 @@ +/* +Copyright (C) 2001-2015 by Serge Lamikhov-Center + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef ELFIO_NOTE_HPP +#define ELFIO_NOTE_HPP + +namespace ELFIO { + +//------------------------------------------------------------------------------ +// There are discrepancies in documentations. SCO documentation +// (http://www.sco.com/developers/gabi/latest/ch5.pheader.html#note_section) +// requires 8 byte entries alignment for 64-bit ELF file, +// but Oracle's definition uses the same structure +// for 32-bit and 64-bit formats. +// (https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-18048.html) +// +// It looks like EM_X86_64 Linux implementation is similar to Oracle's +// definition. Therefore, the same alignment works for both formats +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +template< class S > +class note_section_accessor_template +{ + public: +//------------------------------------------------------------------------------ + note_section_accessor_template( const elfio& elf_file_, S* section_ ) : + elf_file( elf_file_ ), note_section( section_ ) + { + process_section(); + } + +//------------------------------------------------------------------------------ + Elf_Word + get_notes_num() const + { + return (Elf_Word)note_start_positions.size(); + } + +//------------------------------------------------------------------------------ + bool + get_note( Elf_Word index, + Elf_Word& type, + std::string& name, + void*& desc, + Elf_Word& descSize ) const + { + if ( index >= note_section->get_size() ) { + return false; + } + + const char* pData = note_section->get_data() + note_start_positions[index]; + int align = sizeof( Elf_Word ); + + const endianess_convertor& convertor = elf_file.get_convertor(); + type = convertor( *(const Elf_Word*)( pData + 2*align ) ); + Elf_Word namesz = convertor( *(const Elf_Word*)( pData ) ); + descSize = convertor( *(const Elf_Word*)( pData + sizeof( namesz ) ) ); + Elf_Xword max_name_size = note_section->get_size() - note_start_positions[index]; + if ( namesz > max_name_size || + namesz + descSize > max_name_size ) { + return false; + } + name.assign( pData + 3*align, namesz - 1); + if ( 0 == descSize ) { + desc = 0; + } + else { + desc = const_cast ( pData + 3*align + + ( ( namesz + align - 1 )/align )*align ); + } + + return true; + } + +//------------------------------------------------------------------------------ + void add_note( Elf_Word type, + const std::string& name, + const void* desc, + Elf_Word descSize ) + { + const endianess_convertor& convertor = elf_file.get_convertor(); + + int align = sizeof( Elf_Word ); + Elf_Word nameLen = (Elf_Word)name.size() + 1; + Elf_Word nameLenConv = convertor( nameLen ); + std::string buffer( reinterpret_cast( &nameLenConv ), align ); + Elf_Word descSizeConv = convertor( descSize ); + buffer.append( reinterpret_cast( &descSizeConv ), align ); + type = convertor( type ); + buffer.append( reinterpret_cast( &type ), align ); + buffer.append( name ); + buffer.append( 1, '\x00' ); + const char pad[] = { '\0', '\0', '\0', '\0' }; + if ( nameLen % align != 0 ) { + buffer.append( pad, align - nameLen % align ); + } + if ( desc != 0 && descSize != 0 ) { + buffer.append( reinterpret_cast( desc ), descSize ); + if ( descSize % align != 0 ) { + buffer.append( pad, align - descSize % align ); + } + } + + note_start_positions.push_back( note_section->get_size() ); + note_section->append_data( buffer ); + } + + private: +//------------------------------------------------------------------------------ + void process_section() + { + const endianess_convertor& convertor = elf_file.get_convertor(); + const char* data = note_section->get_data(); + Elf_Xword size = note_section->get_size(); + Elf_Xword current = 0; + + note_start_positions.clear(); + + // Is it empty? + if ( 0 == data || 0 == size ) { + return; + } + + int align = sizeof( Elf_Word ); + while ( current + 3*align <= size ) { + note_start_positions.push_back( current ); + Elf_Word namesz = convertor( + *(const Elf_Word*)( data + current ) ); + Elf_Word descsz = convertor( + *(const Elf_Word*)( data + current + sizeof( namesz ) ) ); + + current += 3*sizeof( Elf_Word ) + + ( ( namesz + align - 1 ) / align ) * align + + ( ( descsz + align - 1 ) / align ) * align; + } + } + +//------------------------------------------------------------------------------ + private: + const elfio& elf_file; + S* note_section; + std::vector note_start_positions; +}; + +using note_section_accessor = note_section_accessor_template
; +using const_note_section_accessor = note_section_accessor_template; + +} // namespace ELFIO + +#endif // ELFIO_NOTE_HPP diff --git a/source/elfio/elfio_relocation.hpp b/source/elfio/elfio_relocation.hpp new file mode 100644 index 0000000..4a3fab0 --- /dev/null +++ b/source/elfio/elfio_relocation.hpp @@ -0,0 +1,333 @@ +/* +Copyright (C) 2001-2015 by Serge Lamikhov-Center + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef ELFIO_RELOCATION_HPP +#define ELFIO_RELOCATION_HPP + +namespace ELFIO { + +template struct get_sym_and_type; +template<> struct get_sym_and_type< Elf32_Rel > +{ + static int get_r_sym( Elf_Xword info ) + { + return ELF32_R_SYM( (Elf_Word)info ); + } + static int get_r_type( Elf_Xword info ) + { + return ELF32_R_TYPE( (Elf_Word)info ); + } +}; +template<> struct get_sym_and_type< Elf32_Rela > +{ + static int get_r_sym( Elf_Xword info ) + { + return ELF32_R_SYM( (Elf_Word)info ); + } + static int get_r_type( Elf_Xword info ) + { + return ELF32_R_TYPE( (Elf_Word)info ); + } +}; +template<> struct get_sym_and_type< Elf64_Rel > +{ + static int get_r_sym( Elf_Xword info ) + { + return ELF64_R_SYM( info ); + } + static int get_r_type( Elf_Xword info ) + { + return ELF64_R_TYPE( info ); + } +}; +template<> struct get_sym_and_type< Elf64_Rela > +{ + static int get_r_sym( Elf_Xword info ) + { + return ELF64_R_SYM( info ); + } + static int get_r_type( Elf_Xword info ) + { + return ELF64_R_TYPE( info ); + } +}; + + +//------------------------------------------------------------------------------ +template< class S > +class relocation_section_accessor_template +{ + public: +//------------------------------------------------------------------------------ + relocation_section_accessor_template( const elfio& elf_file_, S* section_ ) : + elf_file( elf_file_ ), + relocation_section( section_ ) + { + } + +//------------------------------------------------------------------------------ + Elf_Xword + get_entries_num() const + { + Elf_Xword nRet = 0; + + if ( 0 != relocation_section->get_entry_size() ) { + nRet = relocation_section->get_size() / relocation_section->get_entry_size(); + } + + return nRet; + } + +//------------------------------------------------------------------------------ + bool + get_entry( Elf_Xword index, + Elf64_Addr& offset, + Elf_Word& symbol, + Elf_Word& type, + Elf_Sxword& addend ) const + { + if ( index >= get_entries_num() ) { // Is index valid + return false; + } + + if ( elf_file.get_class() == ELFCLASS32 ) { + if ( SHT_REL == relocation_section->get_type() ) { + generic_get_entry_rel< Elf32_Rel >( index, offset, symbol, + type, addend ); + } + else if ( SHT_RELA == relocation_section->get_type() ) { + generic_get_entry_rela< Elf32_Rela >( index, offset, symbol, + type, addend ); + } + } + else { + if ( SHT_REL == relocation_section->get_type() ) { + generic_get_entry_rel< Elf64_Rel >( index, offset, symbol, + type, addend ); + } + else if ( SHT_RELA == relocation_section->get_type() ) { + generic_get_entry_rela< Elf64_Rela >( index, offset, symbol, + type, addend ); + } + } + + return true; + } + +//------------------------------------------------------------------------------ + bool + get_entry( Elf_Xword index, + Elf64_Addr& offset, + Elf64_Addr& symbolValue, + std::string& symbolName, + Elf_Word& type, + Elf_Sxword& addend, + Elf_Half& section) const + { + // Do regular job + Elf_Word symbol; + bool ret = get_entry( index, offset, symbol, type, addend ); + + // Find the symbol + Elf_Xword size; + unsigned char bind; + unsigned char symbolType; + unsigned char other; + + symbol_section_accessor symbols( elf_file, elf_file.sections[get_symbol_table_index()] ); + ret = ret && symbols.get_symbol( symbol, symbolName, symbolValue, + size, bind, symbolType, section, other ); + + return ret; + } + +//------------------------------------------------------------------------------ + void + add_entry( Elf64_Addr offset, Elf_Xword info ) + { + if ( elf_file.get_class() == ELFCLASS32 ) { + generic_add_entry< Elf32_Rel >( offset, info ); + } + else { + generic_add_entry< Elf64_Rel >( offset, info ); + } + } + +//------------------------------------------------------------------------------ + void + add_entry( Elf64_Addr offset, Elf_Word symbol, unsigned char type ) + { + Elf_Xword info; + if ( elf_file.get_class() == ELFCLASS32 ) { + info = ELF32_R_INFO( (Elf_Xword)symbol, type ); + } + else { + info = ELF64_R_INFO((Elf_Xword)symbol, type ); + } + + add_entry( offset, info ); + } + +//------------------------------------------------------------------------------ + void + add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend ) + { + if ( elf_file.get_class() == ELFCLASS32 ) { + generic_add_entry< Elf32_Rela >( offset, info, addend ); + } + else { + generic_add_entry< Elf64_Rela >( offset, info, addend ); + } + } + +//------------------------------------------------------------------------------ + void + add_entry( Elf64_Addr offset, Elf_Word symbol, unsigned char type, + Elf_Sxword addend ) + { + Elf_Xword info; + if ( elf_file.get_class() == ELFCLASS32 ) { + info = ELF32_R_INFO( (Elf_Xword)symbol, type ); + } + else { + info = ELF64_R_INFO( (Elf_Xword)symbol, type ); + } + + add_entry( offset, info, addend ); + } + +//------------------------------------------------------------------------------ + void + add_entry( string_section_accessor str_writer, + const char* str, + symbol_section_accessor sym_writer, + Elf64_Addr value, + Elf_Word size, + unsigned char sym_info, + unsigned char other, + Elf_Half shndx, + Elf64_Addr offset, + unsigned char type ) + { + Elf_Word str_index = str_writer.add_string( str ); + Elf_Word sym_index = sym_writer.add_symbol( str_index, value, size, + sym_info, other, shndx ); + add_entry( offset, sym_index, type ); + } + +//------------------------------------------------------------------------------ + private: +//------------------------------------------------------------------------------ + Elf_Half + get_symbol_table_index() const + { + return (Elf_Half)relocation_section->get_link(); + } + +//------------------------------------------------------------------------------ + template< class T > + void + generic_get_entry_rel( Elf_Xword index, + Elf64_Addr& offset, + Elf_Word& symbol, + Elf_Word& type, + Elf_Sxword& addend ) const + { + const endianess_convertor& convertor = elf_file.get_convertor(); + + const T* pEntry = reinterpret_cast( + relocation_section->get_data() + + index * relocation_section->get_entry_size() ); + offset = convertor( pEntry->r_offset ); + Elf_Xword tmp = convertor( pEntry->r_info ); + symbol = get_sym_and_type::get_r_sym( tmp ); + type = get_sym_and_type::get_r_type( tmp ); + addend = 0; + } + +//------------------------------------------------------------------------------ + template< class T > + void + generic_get_entry_rela( Elf_Xword index, + Elf64_Addr& offset, + Elf_Word& symbol, + Elf_Word& type, + Elf_Sxword& addend ) const + { + const endianess_convertor& convertor = elf_file.get_convertor(); + + const T* pEntry = reinterpret_cast( + relocation_section->get_data() + + index * relocation_section->get_entry_size() ); + offset = convertor( pEntry->r_offset ); + Elf_Xword tmp = convertor( pEntry->r_info ); + symbol = get_sym_and_type::get_r_sym( tmp ); + type = get_sym_and_type::get_r_type( tmp ); + addend = convertor( pEntry->r_addend ); + } + +//------------------------------------------------------------------------------ + template< class T > + void + generic_add_entry( Elf64_Addr offset, Elf_Xword info ) + { + const endianess_convertor& convertor = elf_file.get_convertor(); + + T entry; + entry.r_offset = offset; + entry.r_info = info; + entry.r_offset = convertor( entry.r_offset ); + entry.r_info = convertor( entry.r_info ); + + relocation_section->append_data( reinterpret_cast( &entry ), sizeof( entry ) ); + } + +//------------------------------------------------------------------------------ + template< class T > + void + generic_add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend ) + { + const endianess_convertor& convertor = elf_file.get_convertor(); + + T entry; + entry.r_offset = offset; + entry.r_info = info; + entry.r_addend = addend; + entry.r_offset = convertor( entry.r_offset ); + entry.r_info = convertor( entry.r_info ); + entry.r_addend = convertor( entry.r_addend ); + + relocation_section->append_data( reinterpret_cast( &entry ), sizeof( entry ) ); + } + +//------------------------------------------------------------------------------ + private: + const elfio& elf_file; + S* relocation_section; +}; + +using relocation_section_accessor = relocation_section_accessor_template
; +using const_relocation_section_accessor = relocation_section_accessor_template; + +} // namespace ELFIO + +#endif // ELFIO_RELOCATION_HPP diff --git a/source/elfio/elfio_section.hpp b/source/elfio/elfio_section.hpp new file mode 100644 index 0000000..60e19df --- /dev/null +++ b/source/elfio/elfio_section.hpp @@ -0,0 +1,360 @@ +/* +Copyright (C) 2001-2015 by Serge Lamikhov-Center + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef ELFIO_SECTION_HPP +#define ELFIO_SECTION_HPP + +#include +#include +#include "utils/logger.h" +#include + +namespace ELFIO { + +class section +{ + friend class elfio; + public: + virtual ~section() {}; + + ELFIO_GET_ACCESS_DECL ( Elf_Half, index ); + ELFIO_GET_SET_ACCESS_DECL( std::string, name ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Word, type ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, flags ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Word, info ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Word, link ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, addr_align ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, entry_size ); + ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, address ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, size ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Word, name_string_offset ); + ELFIO_GET_ACCESS_DECL ( Elf64_Off, offset ); + size_t stream_size; + size_t get_stream_size() const + { + return stream_size; + } + + void set_stream_size(size_t value) + { + stream_size = value; + } + + virtual const char* get_data() const = 0; + virtual void set_data( const char* pData, Elf_Word size ) = 0; + virtual void set_data( const std::string& data ) = 0; + virtual void append_data( const char* pData, Elf_Word size ) = 0; + virtual void append_data( const std::string& data ) = 0; + + protected: + ELFIO_SET_ACCESS_DECL( Elf64_Off, offset ); + ELFIO_SET_ACCESS_DECL( Elf_Half, index ); + + virtual void load( std::istream& stream, + std::streampos header_offset ) = 0; + virtual void save( std::ostream& stream, + std::streampos header_offset, + std::streampos data_offset ) = 0; + virtual bool is_address_initialized() const = 0; +}; + + +template< class T > +class section_impl : public section +{ + public: +//------------------------------------------------------------------------------ + section_impl( const endianess_convertor* convertor_ ) : convertor( convertor_ ) + { + std::fill_n( reinterpret_cast( &header ), sizeof( header ), '\0' ); + is_address_set = false; + data = 0; + data_size = 0; + } + +//------------------------------------------------------------------------------ + ~section_impl() + { + delete [] data; + } + +//------------------------------------------------------------------------------ + // Section info functions + ELFIO_GET_SET_ACCESS( Elf_Word, type, header.sh_type ); + ELFIO_GET_SET_ACCESS( Elf_Xword, flags, header.sh_flags ); + ELFIO_GET_SET_ACCESS( Elf_Xword, size, header.sh_size ); + ELFIO_GET_SET_ACCESS( Elf_Word, link, header.sh_link ); + ELFIO_GET_SET_ACCESS( Elf_Word, info, header.sh_info ); + ELFIO_GET_SET_ACCESS( Elf_Xword, addr_align, header.sh_addralign ); + ELFIO_GET_SET_ACCESS( Elf_Xword, entry_size, header.sh_entsize ); + ELFIO_GET_SET_ACCESS( Elf_Word, name_string_offset, header.sh_name ); + ELFIO_GET_ACCESS ( Elf64_Addr, address, header.sh_addr ); + + +//------------------------------------------------------------------------------ + Elf_Half + get_index() const + { + return index; + } + + +//------------------------------------------------------------------------------ + std::string + get_name() const + { + return name; + } + +//------------------------------------------------------------------------------ + void + set_name( std::string name_ ) + { + name = name_; + } + +//------------------------------------------------------------------------------ + void + set_address( Elf64_Addr value ) + { + header.sh_addr = value; + header.sh_addr = (*convertor)( header.sh_addr ); + is_address_set = true; + } + +//------------------------------------------------------------------------------ + bool + is_address_initialized() const + { + return is_address_set; + } + +//------------------------------------------------------------------------------ + const char* + get_data() const + { + return data; + } + +//------------------------------------------------------------------------------ + void + set_data( const char* raw_data, Elf_Word size ) + { + if ( get_type() != SHT_NOBITS ) { + delete [] data; + try { + data = new char[size]; + } catch (const std::bad_alloc&) { + data = 0; + data_size = 0; + size = 0; + } + if ( 0 != data && 0 != raw_data ) { + data_size = size; + std::copy( raw_data, raw_data + size, data ); + } + } + + set_size( size ); + } + +//------------------------------------------------------------------------------ + void + set_data( const std::string& str_data ) + { + return set_data( str_data.c_str(), (Elf_Word)str_data.size() ); + } + +//------------------------------------------------------------------------------ + void + append_data( const char* raw_data, Elf_Word size ) + { + if ( get_type() != SHT_NOBITS ) { + if ( get_size() + size < data_size ) { + std::copy( raw_data, raw_data + size, data + get_size() ); + } + else { + data_size = 2*( data_size + size); + char* new_data; + try { + new_data = new char[data_size]; + } catch (const std::bad_alloc&) { + new_data = 0; + size = 0; + } + if ( 0 != new_data ) { + std::copy( data, data + get_size(), new_data ); + std::copy( raw_data, raw_data + size, new_data + get_size() ); + delete [] data; + data = new_data; + } + } + set_size( get_size() + size ); + } + } + +//------------------------------------------------------------------------------ + void + append_data( const std::string& str_data ) + { + return append_data( str_data.c_str(), (Elf_Word)str_data.size() ); + } + +//------------------------------------------------------------------------------ + protected: +//------------------------------------------------------------------------------ + ELFIO_GET_SET_ACCESS( Elf64_Off, offset, header.sh_offset ); + +//------------------------------------------------------------------------------ + void + set_index( Elf_Half value ) + { + index = value; + } + +//------------------------------------------------------------------------------ + void + load( std::istream& stream, + std::streampos header_offset ) + { + std::fill_n( reinterpret_cast( &header ), sizeof( header ), '\0' ); + + stream.seekg ( 0, stream.end ); + set_stream_size ( stream.tellg() ); + + stream.seekg( header_offset ); + stream.read( reinterpret_cast( &header ), sizeof( header ) ); + + + Elf_Xword size = get_size(); + if ( 0 == data && SHT_NULL != get_type() && SHT_NOBITS != get_type() && size < get_stream_size()) { + try { + data = new char[size + 1]; + } catch (const std::bad_alloc&) { + data = 0; + data_size = 0; + } + + if ( ( 0 != size ) && ( 0 != data ) ) { + stream.seekg( (*convertor)( header.sh_offset ) ); + if (get_flags() & 0x08000000){ + uint32_t uncompressed_size = size; + stream.read( (char *) &uncompressed_size, 4); + stream.read( data, size - 4); + + char* uncompressedData = new char[uncompressed_size + 1]; + + int ret = 0; + z_stream s; + memset(&s, 0, sizeof(s)); + + s.zalloc = Z_NULL; + s.zfree = Z_NULL; + s.opaque = Z_NULL; + + ret = inflateInit_(&s, ZLIB_VERSION, sizeof(s)); + if (ret != Z_OK) + return; + + s.avail_in = size - 4; + s.next_in = (Bytef *)data; + + s.avail_out = uncompressed_size; + s.next_out = (Bytef *)&uncompressedData[0]; + + ret = inflate(&s, Z_FINISH); + if (ret != Z_OK && ret != Z_STREAM_END){ + DEBUG_FUNCTION_LINE("NOOOO\n"); + } + + inflateEnd(&s); + + free(data); + data = uncompressedData; + data_size = uncompressed_size; + set_size(uncompressed_size); + data[data_size] = 0; // Ensure data is ended with 0 to avoid oob read + + }else{ + stream.read( data, size ); + data[size] = 0; // Ensure data is ended with 0 to avoid oob read + data_size = size; + } + }else{ + set_size(0); + DEBUG_FUNCTION_LINE("Failed to allocate memory.\n"); + } + } + } + +//------------------------------------------------------------------------------ + void + save( std::ostream& stream, + std::streampos header_offset, + std::streampos data_offset ) + { + if ( 0 != get_index() ) { + header.sh_offset = data_offset; + header.sh_offset = (*convertor)( header.sh_offset ); + } + + save_header( stream, header_offset ); + if ( get_type() != SHT_NOBITS && get_type() != SHT_NULL && + get_size() != 0 && data != 0 ) { + save_data( stream, data_offset ); + } + } + +//------------------------------------------------------------------------------ + private: +//------------------------------------------------------------------------------ + void + save_header( std::ostream& stream, + std::streampos header_offset ) const + { + stream.seekp( header_offset ); + stream.write( reinterpret_cast( &header ), sizeof( header ) ); + } + +//------------------------------------------------------------------------------ + void + save_data( std::ostream& stream, + std::streampos data_offset ) const + { + stream.seekp( data_offset ); + stream.write( get_data(), get_size() ); + } + +//------------------------------------------------------------------------------ + private: + T header; + Elf_Half index; + std::string name; + char* data; + Elf_Word data_size; + const endianess_convertor* convertor; + bool is_address_set; +}; + +} // namespace ELFIO + +#endif // ELFIO_SECTION_HPP diff --git a/source/elfio/elfio_segment.hpp b/source/elfio/elfio_segment.hpp new file mode 100644 index 0000000..642fd29 --- /dev/null +++ b/source/elfio/elfio_segment.hpp @@ -0,0 +1,246 @@ +/* +Copyright (C) 2001-2015 by Serge Lamikhov-Center + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef ELFIO_SEGMENT_HPP +#define ELFIO_SEGMENT_HPP + +#include +#include + +namespace ELFIO { + +class segment +{ + friend class elfio; + public: + virtual ~segment() {}; + + ELFIO_GET_ACCESS_DECL ( Elf_Half, index ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Word, type ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, align ); + ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, virtual_address ); + ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, physical_address ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, file_size ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, memory_size ); + ELFIO_GET_ACCESS_DECL( Elf64_Off, offset ); + + virtual const char* get_data() const = 0; + + virtual Elf_Half add_section_index( Elf_Half index, Elf_Xword addr_align ) = 0; + virtual Elf_Half get_sections_num() const = 0; + virtual Elf_Half get_section_index_at( Elf_Half num ) const = 0; + virtual bool is_offset_initialized() const = 0; + + protected: + ELFIO_SET_ACCESS_DECL( Elf64_Off, offset ); + ELFIO_SET_ACCESS_DECL( Elf_Half, index ); + + virtual const std::vector& get_sections() const = 0; + virtual void load( std::istream& stream, std::streampos header_offset ) = 0; + virtual void save( std::ostream& stream, std::streampos header_offset, + std::streampos data_offset ) = 0; +}; + + +//------------------------------------------------------------------------------ +template< class T > +class segment_impl : public segment +{ + public: +//------------------------------------------------------------------------------ + segment_impl( endianess_convertor* convertor_ ) : + stream_size( 0 ), index( 0 ), data( 0 ), convertor( convertor_ ) + { + is_offset_set = false; + std::fill_n( reinterpret_cast( &ph ), sizeof( ph ), '\0' ); + } + +//------------------------------------------------------------------------------ + virtual ~segment_impl() + { + delete [] data; + } + +//------------------------------------------------------------------------------ + // Section info functions + ELFIO_GET_SET_ACCESS( Elf_Word, type, ph.p_type ); + ELFIO_GET_SET_ACCESS( Elf_Word, flags, ph.p_flags ); + ELFIO_GET_SET_ACCESS( Elf_Xword, align, ph.p_align ); + ELFIO_GET_SET_ACCESS( Elf64_Addr, virtual_address, ph.p_vaddr ); + ELFIO_GET_SET_ACCESS( Elf64_Addr, physical_address, ph.p_paddr ); + ELFIO_GET_SET_ACCESS( Elf_Xword, file_size, ph.p_filesz ); + ELFIO_GET_SET_ACCESS( Elf_Xword, memory_size, ph.p_memsz ); + ELFIO_GET_ACCESS( Elf64_Off, offset, ph.p_offset ); + size_t stream_size; + +//------------------------------------------------------------------------------ + size_t + get_stream_size() const + { + return stream_size; + } + +//------------------------------------------------------------------------------ + void + set_stream_size(size_t value) + { + stream_size = value; + } + +//------------------------------------------------------------------------------ + Elf_Half + get_index() const + { + return index; + } + +//------------------------------------------------------------------------------ + const char* + get_data() const + { + return data; + } + +//------------------------------------------------------------------------------ + Elf_Half + add_section_index( Elf_Half sec_index, Elf_Xword addr_align ) + { + sections.push_back( sec_index ); + if ( addr_align > get_align() ) { + set_align( addr_align ); + } + + return (Elf_Half)sections.size(); + } + +//------------------------------------------------------------------------------ + Elf_Half + get_sections_num() const + { + return (Elf_Half)sections.size(); + } + +//------------------------------------------------------------------------------ + Elf_Half + get_section_index_at( Elf_Half num ) const + { + if ( num < sections.size() ) { + return sections[num]; + } + + return Elf_Half(-1); + } + +//------------------------------------------------------------------------------ + protected: +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + void + set_offset( Elf64_Off value ) + { + ph.p_offset = value; + ph.p_offset = (*convertor)( ph.p_offset ); + is_offset_set = true; + } + +//------------------------------------------------------------------------------ + bool + is_offset_initialized() const + { + return is_offset_set; + } + +//------------------------------------------------------------------------------ + const std::vector& + get_sections() const + { + return sections; + } + +//------------------------------------------------------------------------------ + void + set_index( Elf_Half value ) + { + index = value; + } + +//------------------------------------------------------------------------------ + void + load( std::istream& stream, + std::streampos header_offset ) + { + + stream.seekg ( 0, stream.end ); + set_stream_size ( stream.tellg() ); + + stream.seekg( header_offset ); + stream.read( reinterpret_cast( &ph ), sizeof( ph ) ); + is_offset_set = true; + + if ( PT_NULL != get_type() && 0 != get_file_size() ) { + stream.seekg( (*convertor)( ph.p_offset ) ); + Elf_Xword size = get_file_size(); + + if ( size > get_stream_size() ) { + data = 0; + } + else { + try { + data = new char[size + 1]; + } catch (const std::bad_alloc&) { + data = 0; + } + + if ( 0 != data ) { + stream.read( data, size ); + data[size] = 0; + } + } + } + } + +//------------------------------------------------------------------------------ + void save( std::ostream& stream, + std::streampos header_offset, + std::streampos data_offset ) + { + ph.p_offset = data_offset; + ph.p_offset = (*convertor)(ph.p_offset); + stream.seekp( header_offset ); + stream.write( reinterpret_cast( &ph ), sizeof( ph ) ); + } + +//------------------------------------------------------------------------------ + private: + T ph; + Elf_Half index; + char* data; + std::vector sections; + endianess_convertor* convertor; + bool is_offset_set; +}; + +} // namespace ELFIO + +#endif // ELFIO_SEGMENT_HPP diff --git a/source/elfio/elfio_strings.hpp b/source/elfio/elfio_strings.hpp new file mode 100644 index 0000000..552f000 --- /dev/null +++ b/source/elfio/elfio_strings.hpp @@ -0,0 +1,100 @@ +/* +Copyright (C) 2001-2015 by Serge Lamikhov-Center + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef ELFIO_STRINGS_HPP +#define ELFIO_STRINGS_HPP + +#include +#include +#include + +namespace ELFIO { + +//------------------------------------------------------------------------------ +template< class S > +class string_section_accessor_template +{ + public: +//------------------------------------------------------------------------------ + string_section_accessor_template( S* section_ ) : + string_section( section_ ) + { + } + + +//------------------------------------------------------------------------------ + const char* + get_string( Elf_Word index ) const + { + if ( string_section ) { + if ( index < string_section->get_size() ) { + const char* data = string_section->get_data(); + if ( 0 != data ) { + return data + index; + } + } + } + + return 0; + } + + +//------------------------------------------------------------------------------ + Elf_Word + add_string( const char* str ) + { + Elf_Word current_position = 0; + + if (string_section) { + // Strings are addeded to the end of the current section data + current_position = (Elf_Word)string_section->get_size(); + + if ( current_position == 0 ) { + char empty_string = '\0'; + string_section->append_data( &empty_string, 1 ); + current_position++; + } + string_section->append_data( str, (Elf_Word)std::strlen( str ) + 1 ); + } + + return current_position; + } + + +//------------------------------------------------------------------------------ + Elf_Word + add_string( const std::string& str ) + { + return add_string( str.c_str() ); + } + +//------------------------------------------------------------------------------ + private: + S* string_section; +}; + +using string_section_accessor = string_section_accessor_template
; +using const_string_section_accessor = string_section_accessor_template; + +} // namespace ELFIO + +#endif // ELFIO_STRINGS_HPP diff --git a/source/elfio/elfio_symbols.hpp b/source/elfio/elfio_symbols.hpp new file mode 100644 index 0000000..d18756a --- /dev/null +++ b/source/elfio/elfio_symbols.hpp @@ -0,0 +1,282 @@ +/* +Copyright (C) 2001-2015 by Serge Lamikhov-Center + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef ELFIO_SYMBOLS_HPP +#define ELFIO_SYMBOLS_HPP + +namespace ELFIO { + +//------------------------------------------------------------------------------ +template< class S > +class symbol_section_accessor_template +{ + public: +//------------------------------------------------------------------------------ + symbol_section_accessor_template( const elfio& elf_file_, S* symbol_section_ ) : + elf_file( elf_file_ ), + symbol_section( symbol_section_ ) + { + find_hash_section(); + } + +//------------------------------------------------------------------------------ + Elf_Xword + get_symbols_num() const + { + Elf_Xword nRet = 0; + if ( 0 != symbol_section->get_entry_size() ) { + nRet = symbol_section->get_size() / symbol_section->get_entry_size(); + } + + return nRet; + } + +//------------------------------------------------------------------------------ + bool + get_symbol( Elf_Xword index, + std::string& name, + Elf64_Addr& value, + Elf_Xword& size, + unsigned char& bind, + unsigned char& type, + Elf_Half& section_index, + unsigned char& other ) const + { + bool ret = false; + + if ( elf_file.get_class() == ELFCLASS32 ) { + ret = generic_get_symbol( index, name, value, size, bind, + type, section_index, other ); + } + else { + ret = generic_get_symbol( index, name, value, size, bind, + type, section_index, other ); + } + + return ret; + } + +//------------------------------------------------------------------------------ + bool + get_symbol( const std::string& name, + Elf64_Addr& value, + Elf_Xword& size, + unsigned char& bind, + unsigned char& type, + Elf_Half& section_index, + unsigned char& other ) const + { + bool ret = false; + + if ( 0 != get_hash_table_index() ) { + Elf_Word nbucket = *(const Elf_Word*)hash_section->get_data(); + Elf_Word nchain = *(const Elf_Word*)( hash_section->get_data() + + sizeof( Elf_Word ) ); + Elf_Word val = elf_hash( (const unsigned char*)name.c_str() ); + + Elf_Word y = *(const Elf_Word*)( hash_section->get_data() + + ( 2 + val % nbucket ) * sizeof( Elf_Word ) ); + std::string str; + get_symbol( y, str, value, size, bind, type, section_index, other ); + while ( str != name && STN_UNDEF != y && y < nchain ) { + y = *(const Elf_Word*)( hash_section->get_data() + + ( 2 + nbucket + y ) * sizeof( Elf_Word ) ); + get_symbol( y, str, value, size, bind, type, section_index, other ); + } + if ( str == name ) { + ret = true; + } + } + + return ret; + } + +//------------------------------------------------------------------------------ + Elf_Word + add_symbol( Elf_Word name, Elf64_Addr value, Elf_Xword size, + unsigned char info, unsigned char other, + Elf_Half shndx ) + { + Elf_Word nRet; + + if ( symbol_section->get_size() == 0 ) { + if ( elf_file.get_class() == ELFCLASS32 ) { + nRet = generic_add_symbol( 0, 0, 0, 0, 0, 0 ); + } + else { + nRet = generic_add_symbol( 0, 0, 0, 0, 0, 0 ); + } + } + + if ( elf_file.get_class() == ELFCLASS32 ) { + nRet = generic_add_symbol( name, value, size, info, other, + shndx ); + } + else { + nRet = generic_add_symbol( name, value, size, info, other, + shndx ); + } + + return nRet; + } + +//------------------------------------------------------------------------------ + Elf_Word + add_symbol( Elf_Word name, Elf64_Addr value, Elf_Xword size, + unsigned char bind, unsigned char type, unsigned char other, + Elf_Half shndx ) + { + return add_symbol( name, value, size, ELF_ST_INFO( bind, type ), other, shndx ); + } + +//------------------------------------------------------------------------------ + Elf_Word + add_symbol( string_section_accessor& pStrWriter, const char* str, + Elf64_Addr value, Elf_Xword size, + unsigned char info, unsigned char other, + Elf_Half shndx ) + { + Elf_Word index = pStrWriter.add_string( str ); + return add_symbol( index, value, size, info, other, shndx ); + } + +//------------------------------------------------------------------------------ + Elf_Word + add_symbol( string_section_accessor& pStrWriter, const char* str, + Elf64_Addr value, Elf_Xword size, + unsigned char bind, unsigned char type, unsigned char other, + Elf_Half shndx ) + { + return add_symbol( pStrWriter, str, value, size, ELF_ST_INFO( bind, type ), other, shndx ); + } + +//------------------------------------------------------------------------------ + private: +//------------------------------------------------------------------------------ + void + find_hash_section() + { + hash_section = 0; + hash_section_index = 0; + Elf_Half nSecNo = elf_file.sections.size(); + for ( Elf_Half i = 0; i < nSecNo && 0 == hash_section_index; ++i ) { + const section* sec = elf_file.sections[i]; + if ( sec->get_link() == symbol_section->get_index() ) { + hash_section = sec; + hash_section_index = i; + } + } + } + +//------------------------------------------------------------------------------ + Elf_Half + get_string_table_index() const + { + return (Elf_Half)symbol_section->get_link(); + } + +//------------------------------------------------------------------------------ + Elf_Half + get_hash_table_index() const + { + return hash_section_index; + } + +//------------------------------------------------------------------------------ + template< class T > + bool + generic_get_symbol( Elf_Xword index, + std::string& name, Elf64_Addr& value, + Elf_Xword& size, + unsigned char& bind, unsigned char& type, + Elf_Half& section_index, + unsigned char& other ) const + { + bool ret = false; + + if ( index < get_symbols_num() ) { + const T* pSym = reinterpret_cast( + symbol_section->get_data() + + index * symbol_section->get_entry_size() ); + + const endianess_convertor& convertor = elf_file.get_convertor(); + + section* string_section = elf_file.sections[get_string_table_index()]; + string_section_accessor str_reader( string_section ); + const char* pStr = str_reader.get_string( convertor( pSym->st_name ) ); + if ( 0 != pStr ) { + name = pStr; + } + value = convertor( pSym->st_value ); + size = convertor( pSym->st_size ); + bind = ELF_ST_BIND( pSym->st_info ); + type = ELF_ST_TYPE( pSym->st_info ); + section_index = convertor( pSym->st_shndx ); + other = pSym->st_other; + + ret = true; + } + + return ret; + } + +//------------------------------------------------------------------------------ + template< class T > + Elf_Word + generic_add_symbol( Elf_Word name, Elf64_Addr value, Elf_Xword size, + unsigned char info, unsigned char other, + Elf_Half shndx ) + { + const endianess_convertor& convertor = elf_file.get_convertor(); + + T entry; + entry.st_name = convertor( name ); + entry.st_value = value; + entry.st_value = convertor( entry.st_value ); + entry.st_size = size; + entry.st_size = convertor( entry.st_size ); + entry.st_info = convertor( info ); + entry.st_other = convertor( other ); + entry.st_shndx = convertor( shndx ); + + symbol_section->append_data( reinterpret_cast( &entry ), + sizeof( entry ) ); + + Elf_Word nRet = symbol_section->get_size() / sizeof( entry ) - 1; + + return nRet; + } + +//------------------------------------------------------------------------------ + private: + const elfio& elf_file; + S* symbol_section; + Elf_Half hash_section_index; + const section* hash_section; +}; + +using symbol_section_accessor = symbol_section_accessor_template
; +using const_symbol_section_accessor = symbol_section_accessor_template; + +} // namespace ELFIO + +#endif // ELFIO_SYMBOLS_HPP diff --git a/source/elfio/elfio_utils.hpp b/source/elfio/elfio_utils.hpp new file mode 100644 index 0000000..2baf5a7 --- /dev/null +++ b/source/elfio/elfio_utils.hpp @@ -0,0 +1,209 @@ +/* +Copyright (C) 2001-2015 by Serge Lamikhov-Center + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef ELFIO_UTILS_HPP +#define ELFIO_UTILS_HPP + +#define ELFIO_GET_ACCESS( TYPE, NAME, FIELD ) \ + TYPE get_##NAME() const \ + { \ + return (*convertor)( FIELD ); \ + } +#define ELFIO_SET_ACCESS( TYPE, NAME, FIELD ) \ + void set_##NAME( TYPE value ) \ + { \ + FIELD = value; \ + FIELD = (*convertor)( FIELD ); \ + } +#define ELFIO_GET_SET_ACCESS( TYPE, NAME, FIELD ) \ + TYPE get_##NAME() const \ + { \ + return (*convertor)( FIELD ); \ + } \ + void set_##NAME( TYPE value ) \ + { \ + FIELD = value; \ + FIELD = (*convertor)( FIELD ); \ + } + +#define ELFIO_GET_ACCESS_DECL( TYPE, NAME ) \ + virtual TYPE get_##NAME() const = 0 + +#define ELFIO_SET_ACCESS_DECL( TYPE, NAME ) \ + virtual void set_##NAME( TYPE value ) = 0 + +#define ELFIO_GET_SET_ACCESS_DECL( TYPE, NAME ) \ + virtual TYPE get_##NAME() const = 0; \ + virtual void set_##NAME( TYPE value ) = 0 + +namespace ELFIO { + +//------------------------------------------------------------------------------ +class endianess_convertor { + public: +//------------------------------------------------------------------------------ + endianess_convertor() + { + need_conversion = false; + } + +//------------------------------------------------------------------------------ + void + setup( unsigned char elf_file_encoding ) + { + need_conversion = ( elf_file_encoding != get_host_encoding() ); + } + +//------------------------------------------------------------------------------ + uint64_t + operator()( uint64_t value ) const + { + if ( !need_conversion ) { + return value; + } + value = + ( ( value & 0x00000000000000FFull ) << 56 ) | + ( ( value & 0x000000000000FF00ull ) << 40 ) | + ( ( value & 0x0000000000FF0000ull ) << 24 ) | + ( ( value & 0x00000000FF000000ull ) << 8 ) | + ( ( value & 0x000000FF00000000ull ) >> 8 ) | + ( ( value & 0x0000FF0000000000ull ) >> 24 ) | + ( ( value & 0x00FF000000000000ull ) >> 40 ) | + ( ( value & 0xFF00000000000000ull ) >> 56 ); + + return value; + } + +//------------------------------------------------------------------------------ + int64_t + operator()( int64_t value ) const + { + if ( !need_conversion ) { + return value; + } + return (int64_t)(*this)( (uint64_t)value ); + } + +//------------------------------------------------------------------------------ + uint32_t + operator()( uint32_t value ) const + { + if ( !need_conversion ) { + return value; + } + value = + ( ( value & 0x000000FF ) << 24 ) | + ( ( value & 0x0000FF00 ) << 8 ) | + ( ( value & 0x00FF0000 ) >> 8 ) | + ( ( value & 0xFF000000 ) >> 24 ); + + return value; + } + +//------------------------------------------------------------------------------ + int32_t + operator()( int32_t value ) const + { + if ( !need_conversion ) { + return value; + } + return (int32_t)(*this)( (uint32_t)value ); + } + +//------------------------------------------------------------------------------ + uint16_t + operator()( uint16_t value ) const + { + if ( !need_conversion ) { + return value; + } + value = + ( ( value & 0x00FF ) << 8 ) | + ( ( value & 0xFF00 ) >> 8 ); + + return value; + } + +//------------------------------------------------------------------------------ + int16_t + operator()( int16_t value ) const + { + if ( !need_conversion ) { + return value; + } + return (int16_t)(*this)( (uint16_t)value ); + } + +//------------------------------------------------------------------------------ + int8_t + operator()( int8_t value ) const + { + return value; + } + +//------------------------------------------------------------------------------ + uint8_t + operator()( uint8_t value ) const + { + return value; + } + +//------------------------------------------------------------------------------ + private: +//------------------------------------------------------------------------------ + unsigned char + get_host_encoding() const + { + static const int tmp = 1; + if ( 1 == *(const char*)&tmp ) { + return ELFDATA2LSB; + } + else { + return ELFDATA2MSB; + } + } + +//------------------------------------------------------------------------------ + private: + bool need_conversion; +}; + + +//------------------------------------------------------------------------------ +inline +uint32_t +elf_hash( const unsigned char *name ) +{ + uint32_t h = 0, g; + while ( *name ) { + h = (h << 4) + *name++; + g = h & 0xf0000000; + if ( g != 0 ) + h ^= g >> 24; + h &= ~g; + } + return h; +} + +} // namespace ELFIO + +#endif // ELFIO_UTILS_HPP diff --git a/source/hooks.cpp b/source/hooks.cpp new file mode 100644 index 0000000..8f7205b --- /dev/null +++ b/source/hooks.cpp @@ -0,0 +1,103 @@ +#include "hooks.h" +#include "utils/logger.h" + + + +void CallHook(plugin_information_t * pluginInformation, wups_loader_hook_type_t hook_type) { + CallHookEx(pluginInformation, hook_type,-1); +} + +bool HasHookCallHook(plugin_information_t * pluginInformation, wups_loader_hook_type_t hook_type) { + for(int32_t plugin_index=0; plugin_indexnumber_used_plugins; plugin_index++) { + plugin_information_single_t * plugin_data = &pluginInformation->plugin_data[plugin_index]; + + for(uint32_t j=0; jinfo.number_used_hooks; j++) { + replacement_data_hook_t * hook_data = &plugin_data->info.hooks[j]; + if(hook_data->type == hook_type) { + return true; + } + } + } + return false; +} + + static const char** hook_names = (const char *[]){ + "WUPS_LOADER_HOOK_INIT_OVERLAY", + "WUPS_LOADER_HOOK_INIT_KERNEL", + "WUPS_LOADER_HOOK_INIT_VID_MEM", + "WUPS_LOADER_HOOK_INIT_WUT_MALLOC", + "WUPS_LOADER_HOOK_FINI_WUT_MALLOC", + "WUPS_LOADER_HOOK_INIT_WUT_DEVOPTAB", + "WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB", + "WUPS_LOADER_HOOK_INIT_WUT_NEWLIB", + "WUPS_LOADER_HOOK_FINI_WUT_NEWLIB", + "WUPS_LOADER_HOOK_INIT_WUT_STDCPP", + "WUPS_LOADER_HOOK_FINI_WUT_STDCPP", + "WUPS_LOADER_HOOK_INIT_PLUGIN", + "WUPS_LOADER_HOOK_DEINIT_PLUGIN", + "WUPS_LOADER_HOOK_APPLICATION_START", + "WUPS_LOADER_HOOK_FUNCTIONS_PATCHED", + "WUPS_LOADER_HOOK_RELEASE_FOREGROUND", + "WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND", + "WUPS_LOADER_HOOK_APPLICATION_END", + "WUPS_LOADER_HOOK_CONFIRM_RELEASE_FOREGROUND", + "WUPS_LOADER_HOOK_SAVES_DONE_READY_TO_RELEASE", + "WUPS_LOADER_HOOK_VSYNC", + "WUPS_LOADER_HOOK_GET_CONFIG", + "WUPS_LOADER_HOOK_VID_DRC_DRAW", + "WUPS_LOADER_HOOK_VID_TV_DRAW", + "WUPS_LOADER_HOOK_APPLET_START"}; + +void CallHookEx(plugin_information_t * pluginInformation, wups_loader_hook_type_t hook_type, int32_t plugin_index_needed) { + for(int32_t plugin_index=0; plugin_indexnumber_used_plugins; plugin_index++) { + plugin_information_single_t * plugin_data = &pluginInformation->plugin_data[plugin_index]; + if(plugin_index_needed != -1 && plugin_index_needed != plugin_index) { + continue; + } + + //DEBUG_FUNCTION_LINE("Checking hook functions for %s.\n",plugin_data->plugin_name); + //DEBUG_FUNCTION_LINE("Found hooks: %d\n",plugin_data->number_used_hooks); + for(uint32_t j=0; jinfo.number_used_hooks; j++) { + replacement_data_hook_t * hook_data = &plugin_data->info.hooks[j]; + if(hook_data->type == hook_type) { + DEBUG_FUNCTION_LINE("Calling hook of type %s for plugin %s",hook_names[hook_data->type],plugin_data->meta.name); + void * func_ptr = hook_data->func_pointer; + if(func_ptr != NULL) { + //DEBUG_FUNCTION_LINE("function pointer is %08x\n",func_ptr); + if(hook_type == WUPS_LOADER_HOOK_INIT_PLUGIN) { + ((void (*)(void))((uint32_t*)func_ptr) )(); + } else if(hook_type == WUPS_LOADER_HOOK_DEINIT_PLUGIN) { + ((void (*)(void))((uint32_t*)func_ptr) )(); + } else if(hook_type == WUPS_LOADER_HOOK_APPLICATION_START) { + wups_loader_app_started_args_t args; + ((void (*)(wups_loader_app_started_args_t))((uint32_t*)func_ptr) )(args); + } else if(hook_type == WUPS_LOADER_HOOK_FUNCTIONS_PATCHED) { + ((void (*)(void))((uint32_t*)func_ptr))(); + } else if(hook_type == WUPS_LOADER_HOOK_APPLICATION_END) { + ((void (*)(void))((uint32_t*)func_ptr))(); + } if(hook_type == WUPS_LOADER_HOOK_INIT_WUT_MALLOC) { + ((void (*)(void))((uint32_t*)func_ptr))(); + } else if(hook_type == WUPS_LOADER_HOOK_FINI_WUT_MALLOC) { + ((void (*)(void))((uint32_t*)func_ptr))(); + } else if(hook_type == WUPS_LOADER_HOOK_INIT_WUT_DEVOPTAB) { + ((void (*)(void))((uint32_t*)func_ptr))(); + } else if(hook_type == WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB) { + ((void (*)(void))((uint32_t*)func_ptr))(); + } else if(hook_type == WUPS_LOADER_HOOK_INIT_WUT_NEWLIB) { + ((void (*)(void))((uint32_t*)func_ptr))(); + } else if(hook_type == WUPS_LOADER_HOOK_FINI_WUT_NEWLIB) { + ((void (*)(void))((uint32_t*)func_ptr))(); + } else if(hook_type == WUPS_LOADER_HOOK_INIT_WUT_STDCPP) { + ((void (*)(void))((uint32_t*)func_ptr))(); + } else if(hook_type == WUPS_LOADER_HOOK_FINI_WUT_STDCPP) { + ((void (*)(void))((uint32_t*)func_ptr))(); + }else{ + DEBUG_FUNCTION_LINE("IMPLEMENT ME"); + } + } else { + DEBUG_FUNCTION_LINE("Failed to call hook. It was not defined\n"); + } + } + } + } +} diff --git a/source/hooks.h b/source/hooks.h new file mode 100644 index 0000000..784b7a0 --- /dev/null +++ b/source/hooks.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include "common/plugin_defines.h" + +void CallHook(plugin_information_t * pluginInformation, wups_loader_hook_type_t hook_type); +void CallHookEx(plugin_information_t * pluginInformation, wups_loader_hook_type_t hook_type, int32_t plugin_index_needed); +bool HasHookCallHook(plugin_information_t * pluginInformation, wups_loader_hook_type_t hook_type); diff --git a/src/kernel/kernel.S b/source/kernel/kernel.s similarity index 92% rename from src/kernel/kernel.S rename to source/kernel/kernel.s index 92a5777..2e6eac7 100644 --- a/src/kernel/kernel.S +++ b/source/kernel/kernel.s @@ -6,7 +6,7 @@ SCKernelCopyData: li %r7, 0x10 andc %r6, %r6, %r7 mtmsr %r6 - + // Copy data addi %r3, %r3, -1 addi %r4, %r4, -1 @@ -15,7 +15,7 @@ SCKernelCopyData_loop: lbzu %r5, 1(%r4) stbu %r5, 1(%r3) bdnz SCKernelCopyData_loop - + // Enable data address translation ori %r6, %r6, 0x10 mtmsr %r6 @@ -29,12 +29,12 @@ KernelCopyData: .globl SC0x36_KernelReadSRs SC0x36_KernelReadSRs: - li r0, 0x3600 + li %r0, 0x3600 sc blr .globl SC0x0A_KernelWriteSRs SC0x0A_KernelWriteSRs: - li r0, 0x0A00 + li %r0, 0x0A00 sc - blr \ No newline at end of file + blr diff --git a/src/kernel/kernel_defs.h b/source/kernel/kernel_defs.h similarity index 62% rename from src/kernel/kernel_defs.h rename to source/kernel/kernel_defs.h index 3aecefa..9298b27 100644 --- a/src/kernel/kernel_defs.h +++ b/source/kernel/kernel_defs.h @@ -7,6 +7,13 @@ extern "C" { #endif + +#define KERN_SYSCALL_TBL1 0xFFE84C70 //Unknown +#define KERN_SYSCALL_TBL2 0xFFE85070 //Games +#define KERN_SYSCALL_TBL3 0xFFE85470 //Loader +#define KERN_SYSCALL_TBL4 0xFFEAAA60 //Home menu +#define KERN_SYSCALL_TBL5 0xFFEAAE60 //Browser + typedef struct _sr_table_t { uint32_t value[16]; uint32_t sdr1; diff --git a/source/kernel/kernel_utils.c b/source/kernel/kernel_utils.c new file mode 100644 index 0000000..68cf873 --- /dev/null +++ b/source/kernel/kernel_utils.c @@ -0,0 +1,91 @@ +#include "kernel_utils.h" +#include "kernel_defs.h" +#include + + +extern void SCKernelCopyData(uint32_t dst, uint32_t src, uint32_t len); + +void KernelWrite(uint32_t addr, const void *data, uint32_t length) { + uint32_t dst = (uint32_t) OSEffectiveToPhysical(addr); + uint32_t src = (uint32_t) OSEffectiveToPhysical((uint32_t)data); + KernelCopyData(dst, src, length); + DCFlushRange((void *)addr, length); + ICInvalidateRange((void *)addr, length); +} + +void KernelWriteU32(uint32_t addr, uint32_t value) { + uint32_t dst = (uint32_t) OSEffectiveToPhysical(addr); + uint32_t src = (uint32_t) OSEffectiveToPhysical((uint32_t)&value); + KernelCopyData(dst, src, 4); + DCFlushRange((void *)addr, 4); + ICInvalidateRange((void *)addr, 4); +} + +/* Write a 32-bit word with kernel permissions */ +void __attribute__ ((noinline)) kern_write(void * addr, uint32_t value) { + asm volatile ( + "li 3,1\n" + "li 4,0\n" + "mr 5,%1\n" + "li 6,0\n" + "li 7,0\n" + "lis 8,1\n" + "mr 9,%0\n" + "mr %1,1\n" + "li 0,0x3500\n" + "sc\n" + "nop\n" + "mr 1,%1\n" + : + : "r"(addr), "r"(value) + : "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10", + "11", "12" + ); +} + +/* Read a 32-bit word with kernel permissions */ +uint32_t __attribute__ ((noinline)) kern_read(const void *addr) { + uint32_t result; + asm volatile ( + "li 3,1\n" + "li 4,0\n" + "li 5,0\n" + "li 6,0\n" + "li 7,0\n" + "lis 8,1\n" + "mr 9,%1\n" + "li 0,0x3400\n" + "mr %0,1\n" + "sc\n" + "nop\n" + "mr 1,%0\n" + "mr %0,3\n" + : "=r"(result) + : "b"(addr) + : "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10", + "11", "12" + ); + + return result; +} + +void PatchSyscall(int index, uint32_t addr) { + //DEBUG_FUNCTION_LINE("Patching Syscall 0x%02X\n",index); + kern_write((void *) (KERN_SYSCALL_TBL1 + index * 4), addr); + kern_write((void *) (KERN_SYSCALL_TBL2 + index * 4), addr); + kern_write((void *) (KERN_SYSCALL_TBL3 + index * 4), addr); + kern_write((void *) (KERN_SYSCALL_TBL4 + index * 4), addr); + kern_write((void *) (KERN_SYSCALL_TBL5 + index * 4), addr); +} + +void kernelInitialize() { + static uint8_t ucSyscallsSetupRequired = 1; + if(!ucSyscallsSetupRequired) + return; + + ucSyscallsSetupRequired = 0; + + PatchSyscall(0x25, (uint32_t)SCKernelCopyData); + + +} diff --git a/src/kernel/kernel_utils.h b/source/kernel/kernel_utils.h similarity index 100% rename from src/kernel/kernel_utils.h rename to source/kernel/kernel_utils.h diff --git a/source/main.cpp b/source/main.cpp new file mode 100644 index 0000000..c235649 --- /dev/null +++ b/source/main.cpp @@ -0,0 +1,192 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "plugin/PluginDataFactory.h" +#include "plugin/PluginContainerPersistence.h" +#include "plugin/PluginInformationFactory.h" +#include "plugin/PluginMetaInformationFactory.h" +#include "plugin/FunctionData.h" +#include "plugin/PluginContainer.h" +#include "utils/logger.h" +#include "utils/utils.h" +#include "kernel/kernel_utils.h" +#include "patcher/hooks_patcher_static.h" +#include "patcher/hooks_patcher.h" +#include "utils/ElfUtils.h" +#include "common/relocation_defines.h" +#include "common/plugin_defines.h" +#include "common/plugin_defines.h" +#include "common/module_defines.h" +#include "hooks.h" +#include + +MEMHeapHandle pluginDataHeap __attribute__((section(".data"))) = 0; +plugin_information_t * gPluginInformation __attribute__((section(".data"))) = NULL; + +int test(); + +#define gModuleData ((module_information_t *) (0x00880000)) + +int main(int argc, char **argv) { + test(); +} + +bool doRelocation(const std::vector &relocData, relocation_trampolin_entry_t * tramp_data, uint32_t tramp_length, uint32_t trampolinID) { + std::map moduleHandleCache; + for (auto const& cur : relocData) { + std::string functionName = cur.getName(); + std::string rplName = cur.getImportRPLInformation().getName(); + int32_t isData = cur.getImportRPLInformation().isData(); + OSDynLoad_Module rplHandle = 0; + if(moduleHandleCache.count(rplName) > 0) { + rplHandle = moduleHandleCache[rplName]; + } else { + OSDynLoad_Acquire(rplName.c_str(), &rplHandle); + moduleHandleCache[rplName] = rplHandle; + } + + uint32_t functionAddress = 0; + OSDynLoad_FindExport(rplHandle, isData, functionName.c_str(), (void**) &functionAddress); + if(functionAddress == 0) { + DEBUG_FUNCTION_LINE("Failed to find export for %s", functionName.c_str()); + return false; + } else { + //DEBUG_FUNCTION_LINE("Found export for %s %s", rplName.c_str(), functionName.c_str()); + } + if(!ElfUtils::elfLinkOne(cur.getType(), cur.getOffset(), cur.getAddend(), (uint32_t) cur.getDestination(), functionAddress, tramp_data, tramp_length, RELOC_TYPE_IMPORT,trampolinID)) { + DEBUG_FUNCTION_LINE("Relocation failed\n"); + return false; + } + } + + DCFlushRange(tramp_data, tramp_length * sizeof(relocation_trampolin_entry_t)); + ICInvalidateRange(tramp_data, tramp_length * sizeof(relocation_trampolin_entry_t)); + return true; +} + +int test() { + WHBLogUdpInit(); + log_init(); + bool pluginFreshLoaded = false; + if(pluginDataHeap == NULL) { + kernelInitialize(); + DEBUG_FUNCTION_LINE("Kernel init done"); + DCFlushRange((void*)0x00880000, sizeof(module_information_t)); + uint32_t endAddress = 0; + DEBUG_FUNCTION_LINE("Using %d modules",gModuleData->number_used_modules); + for(int i = 0; i < gModuleData->number_used_modules; i++) { + DEBUG_FUNCTION_LINE("%08x",gModuleData->module_data[i].endAddress); + uint32_t curEndAddr = gModuleData->module_data[i].endAddress; + if(curEndAddr > endAddress) { + endAddress = curEndAddr; + } + } + // If this address is 0, make sure the header common match the one + // in the SetupPayload repo. (I know thats a bad idea) + endAddress = (endAddress + 0x100) & 0xFFFFFF00; + DEBUG_FUNCTION_LINE("endAddress: %08X", endAddress); + + DEBUG_FUNCTION_LINE("Create heap"); + pluginDataHeap = MEMCreateExpHeapEx((void*) (endAddress), 0x00FFF000 - endAddress, 0); + + if(pluginDataHeap != NULL) { + if(gPluginInformation == NULL) { + gPluginInformation = (plugin_information_t*) MEMAllocFromExpHeapEx(pluginDataHeap, sizeof(plugin_information_t), 4); + if(gPluginInformation == NULL) { + DEBUG_FUNCTION_LINE("Failed to allocate global plugin information"); + return 0; + } + } + DEBUG_FUNCTION_LINE("MEMGetAllocatableSizeForExpHeapEx %d kb", MEMGetAllocatableSizeForExpHeapEx(pluginDataHeap, 4)/1024); + std::vector pluginList = PluginDataFactory::loadDir("fs:/vol/external01/wiiu/plugins/", pluginDataHeap); + std::vector plugins; + DEBUG_FUNCTION_LINE("Loaded %d plugin data", pluginList.size()); + for(auto & pluginData : pluginList) { + DEBUG_FUNCTION_LINE("Load meta information"); + auto metaInfo = PluginMetaInformationFactory::loadPlugin(pluginData); + if(metaInfo) { + PluginContainer container; + container.setMetaInformation(metaInfo.value()); + container.setPluginData(pluginData); + plugins.push_back(container); + } + } + uint8_t trampolinID = 0; + for(auto & pluginContainer : plugins) { + std::optional data = PluginInformationFactory::load(pluginContainer.getPluginData(), pluginDataHeap, gPluginInformation->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH, trampolinID); + + if(!data) { + DEBUG_FUNCTION_LINE("Failed to load Plugin %s", pluginContainer.getMetaInformation().getName().c_str()); + break; + } + pluginContainer.setPluginInformation(data.value()); + + for (const auto& kv : data->getSectionInfoList()) { + DEBUG_FUNCTION_LINE("%s = %s %08X %d", kv.first.c_str(), kv.second.getName().c_str(), kv.second.getAddress(), kv.second.getSize()); + } + + trampolinID++; + + PluginContainerPersistence::savePlugin(gPluginInformation, pluginContainer); + } + pluginFreshLoaded = true; + } + } + + if(pluginDataHeap != NULL) { + std::vector plugins = PluginContainerPersistence::loadPlugins(gPluginInformation); + for(auto & pluginContainer : plugins) { + DEBUG_FUNCTION_LINE("Doing relocations for plugin: %s", pluginContainer.getMetaInformation().getName().c_str()); + + if(!doRelocation(pluginContainer.getPluginInformation().getRelocationDataList(), gPluginInformation->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH, pluginContainer.getPluginInformation().getTrampolinId())) { + DEBUG_FUNCTION_LINE("Relocation failed"); + } + + auto sbssSection = pluginContainer.getPluginInformation().getSectionInfo(".sbss"); + if(sbssSection){ + DEBUG_FUNCTION_LINE("memset .sbss %08X (%d)", sbssSection->getAddress(), sbssSection->getSize()); + memset((void*)sbssSection->getAddress(), 0, sbssSection->getSize()); + } + auto bssSection = pluginContainer.getPluginInformation().getSectionInfo(".bss"); + if(bssSection) { + DEBUG_FUNCTION_LINE("memset .bss %08X (%d)", bssSection->getAddress(), bssSection->getSize()); + memset((void*)bssSection->getAddress(), 0, bssSection->getSize()); + } + + } + + DCFlushRange((void*)0x00800000, 0x00800000); + ICInvalidateRange((void*)0x00800000, 0x00800000); + + if(pluginFreshLoaded) { + CallHook(gPluginInformation, WUPS_LOADER_HOOK_INIT_WUT_MALLOC); + CallHook(gPluginInformation, WUPS_LOADER_HOOK_INIT_WUT_NEWLIB); + CallHook(gPluginInformation, WUPS_LOADER_HOOK_INIT_WUT_STDCPP); + + CallHook(gPluginInformation, WUPS_LOADER_HOOK_INIT_VID_MEM); + CallHook(gPluginInformation, WUPS_LOADER_HOOK_INIT_KERNEL); + CallHook(gPluginInformation, WUPS_LOADER_HOOK_INIT_OVERLAY); + CallHook(gPluginInformation, WUPS_LOADER_HOOK_INIT_PLUGIN); + pluginFreshLoaded = false; + } + + PatchInvidualMethodHooks(method_hooks_hooks_static, method_hooks_size_hooks_static, method_calls_hooks_static); + PatchInvidualMethodHooks(method_hooks_hooks, method_hooks_size_hooks, method_calls_hooks); + + for(int32_t plugin_index=0; plugin_indexnumber_used_plugins; plugin_index++) { + CallHookEx(gPluginInformation, WUPS_LOADER_HOOK_INIT_WUT_DEVOPTAB,plugin_index); + CallHookEx(gPluginInformation, WUPS_LOADER_HOOK_APPLICATION_START,plugin_index); + //new_PatchInvidualMethodHooks(&gbl_replacement_data.plugin_data[plugin_index]); + CallHookEx(gPluginInformation, WUPS_LOADER_HOOK_FUNCTIONS_PATCHED,plugin_index); + } + } + + return 0; +} + + diff --git a/src/patcher/hooks_patcher.cpp b/source/patcher/hooks_patcher.cpp similarity index 100% rename from src/patcher/hooks_patcher.cpp rename to source/patcher/hooks_patcher.cpp diff --git a/src/patcher/hooks_patcher.h b/source/patcher/hooks_patcher.h similarity index 100% rename from src/patcher/hooks_patcher.h rename to source/patcher/hooks_patcher.h diff --git a/src/patcher/hooks_patcher_static.cpp b/source/patcher/hooks_patcher_static.cpp similarity index 66% rename from src/patcher/hooks_patcher_static.cpp rename to source/patcher/hooks_patcher_static.cpp index 0435c5f..0cf395d 100644 --- a/src/patcher/hooks_patcher_static.cpp +++ b/source/patcher/hooks_patcher_static.cpp @@ -1,80 +1,17 @@ #include "utils/logger.h" #include "utils/function_patcher.h" -#include "common/retain_vars.h" #include "hooks_patcher.h" -#include "utils/overlay_helper.h" -#include "utils/ConfigUtils.h" #include -#include "utils.h" -#include "memory/memory_mapping.h" -#include "utils/mem_utils.h" -#include "dynamic_libs/vpad_functions.h" -#include "dynamic_libs/coreinit.h" -#include "fs/sd_fat_devoptab.h" -//#include "utils/texture_utils.h" +#include +#include +#include +#include +#include "hooks.h" -DECL_FUNCTION(uint32_t, __OSPhysicalToEffectiveCached, uint32_t phyiscalAddress) { - uint32_t result = real___OSPhysicalToEffectiveCached(phyiscalAddress); - if(result == 0) { - result = MemoryMapping::PhysicalToEffective(phyiscalAddress); - //DEBUG_FUNCTION_LINE("__OSPhysicalToEffectiveCached in %08X out %08X\n",phyiscalAddress,result); - } - return result; -} - -DECL_FUNCTION(uint32_t, __OSPhysicalToEffectiveUncached, uint32_t phyiscalAddress) { - uint32_t result = real___OSPhysicalToEffectiveUncached(phyiscalAddress); - if(result == 0) { - result = MemoryMapping::PhysicalToEffective(phyiscalAddress); - //DEBUG_FUNCTION_LINE("__OSPhysicalToEffectiveUncached in %08X out %08X\n",phyiscalAddress,result); - return result; - } - return result; -} - - -DECL_FUNCTION(uint32_t, OSEffectiveToPhysical, uint32_t virtualAddress) { - uint32_t result = real_OSEffectiveToPhysical(virtualAddress); - if(result == 0) { - result = MemoryMapping::EffectiveToPhysical(virtualAddress); - //DEBUG_FUNCTION_LINE("OSEffectiveToPhysical in %08X out %08X\n",virtualAddress,result); - return result; - } - return result; -} - -DECL_FUNCTION(int32_t, OSIsAddressValid, uint32_t virtualAddress) { - int32_t result = real_OSIsAddressValid(virtualAddress); - if(result == 0) { - result = (MemoryMapping::EffectiveToPhysical(virtualAddress) > 0); - //DEBUG_FUNCTION_LINE("OSIsAddressValid in %08X out %d\n",virtualAddress,result); - return result; - } - return result; -} - -DECL(void, GX2SetTVBuffer, void *buffer, uint32_t buffer_size, int32_t tv_render_mode, int32_t format, int32_t buffering_mode) { - tv_store.buffer = buffer; - tv_store.buffer_size = buffer_size; - tv_store.mode = tv_render_mode; - tv_store.surface_format = format; - tv_store.buffering_mode = buffering_mode; - - return real_GX2SetTVBuffer(buffer,buffer_size,tv_render_mode,format,buffering_mode); -} - -DECL(void, GX2SetDRCBuffer, void *buffer, uint32_t buffer_size, int32_t drc_mode, int32_t surface_format, int32_t buffering_mode) { - drc_store.buffer = buffer; - drc_store.buffer_size = buffer_size; - drc_store.mode = drc_mode; - drc_store.surface_format = surface_format; - drc_store.buffering_mode = buffering_mode; - - return real_GX2SetDRCBuffer(buffer,buffer_size,drc_mode,surface_format,buffering_mode); -} +extern plugin_information_t * gPluginInformation; DECL(void, GX2WaitForVsync, void) { - CallHook(WUPS_LOADER_HOOK_VSYNC); + CallHook(gPluginInformation, WUPS_LOADER_HOOK_VSYNC); real_GX2WaitForVsync(); } @@ -85,7 +22,7 @@ float angleX_delta = 0.0f; float angleX_last = 0.0f; uint8_t angleX_frameCounter = 0; -void checkMagic(VPADData *buffer) { +void checkMagic(VPADStatus *buffer) { // buffer->angle stores the rotations per axis since the app started. // Each full rotation add/subtracts 1.0f (depending on the direction). @@ -103,7 +40,7 @@ void checkMagic(VPADData *buffer) { angleX_counter++; // When the gamepad rotated ~0.16% for 6 times in a row we made a full rotation! if(angleX_counter > 5) { - ConfigUtils::openConfigMenu(); + //ConfigUtils::openConfigMenu(); // reset stuff. angleX_counter = 0; angleX_delta = 0.0f; @@ -120,20 +57,20 @@ void checkMagic(VPADData *buffer) { } } -DECL(int32_t, VPADRead, int32_t chan, VPADData *buffer, uint32_t buffer_size, int32_t *error) { +DECL(int32_t, VPADRead, int32_t chan, VPADStatus *buffer, uint32_t buffer_size, int32_t *error) { int32_t result = real_VPADRead(chan, buffer, buffer_size, error); - if(result > 0 && (buffer[0].btns_h == (VPAD_BUTTON_PLUS | VPAD_BUTTON_R | VPAD_BUTTON_L)) && vpadPressCooldown == 0 && OSIsHomeButtonMenuEnabled()) { - if(MemoryMapping::isMemoryMapped()) { - MemoryMapping::readTestValuesFromMemory(); - } else { - DEBUG_FUNCTION_LINE("Memory was not mapped. To test the memory please exit the plugin loader by pressing MINUS\n"); - } + if(result > 0 && (buffer[0].hold == (VPAD_BUTTON_PLUS | VPAD_BUTTON_R | VPAD_BUTTON_L)) && vpadPressCooldown == 0 && OSIsHomeButtonMenuEnabled()) { + //if(MemoryMapping::isMemoryMapped()) { + //MemoryMapping::readTestValuesFromMemory(); + //} else { + // DEBUG_FUNCTION_LINE("Memory was not mapped. To test the memory please exit the plugin loader by pressing MINUS\n"); + //} vpadPressCooldown = 0x3C; } - if(result > 0 && (buffer[0].btns_h == (VPAD_BUTTON_L | VPAD_BUTTON_DOWN | VPAD_BUTTON_MINUS)) && vpadPressCooldown == 0 && OSIsHomeButtonMenuEnabled()) { - ConfigUtils::openConfigMenu(); + if(result > 0 && (buffer[0].hold == (VPAD_BUTTON_L | VPAD_BUTTON_DOWN | VPAD_BUTTON_MINUS)) && vpadPressCooldown == 0 && OSIsHomeButtonMenuEnabled()) { + //ConfigUtils::openConfigMenu(); vpadPressCooldown = 0x3C; } else if(result > 0 && OSIsHomeButtonMenuEnabled()) { checkMagic(buffer); @@ -312,28 +249,28 @@ static uint32_t lastData0 = 0; DECL(uint32_t, OSReceiveMessage, OSMessageQueue *queue, OSMessage *message, uint32_t flags) { if(flags == 0x15154848) { - CallHook(WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND); - CallHook(WUPS_LOADER_HOOK_APPLICATION_END); - CallHook(WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB); - gInBackground = false; - DCFlushRange(&gInBackground,4); + CallHook(gPluginInformation, WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND); + CallHook(gPluginInformation, WUPS_LOADER_HOOK_APPLICATION_END); + CallHook(gPluginInformation, WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB); + //gInBackground = false; + //DCFlushRange(&gInBackground,4); return false; } int32_t res = real_OSReceiveMessage(queue, message, flags); if(queue == OSGetSystemMessageQueue()) { if(message != NULL) { - if(lastData0 != message->data0) { - if(message->data0 == 0xFACEF000) { - CallHook(WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND); - } else if(message->data0 == 0xD1E0D1E0) { - CallHook(WUPS_LOADER_HOOK_APPLICATION_END); - CallHook(WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB); - gInBackground = false; - DCFlushRange(&gInBackground,4); - unmount_sd_fat("sd"); + if(lastData0 != message->args[0]) { + if(message->args[0] == 0xFACEF000) { + CallHook(gPluginInformation, WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND); + } else if(message->args[0] == 0xD1E0D1E0) { + CallHook(gPluginInformation, WUPS_LOADER_HOOK_APPLICATION_END); + CallHook(gPluginInformation, WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB); + //gInBackground = false; + //DCFlushRange(&gInBackground,4); + //unmount_sd_fat("sd"); } } - lastData0 = message->data0; + lastData0 = message->args[0]; } } return res; @@ -341,22 +278,22 @@ DECL(uint32_t, OSReceiveMessage, OSMessageQueue *queue, OSMessage *message, uint DECL(void, OSReleaseForeground) { if(OSGetCoreId() == 1) { - CallHook(WUPS_LOADER_HOOK_RELEASE_FOREGROUND); + CallHook(gPluginInformation, WUPS_LOADER_HOOK_RELEASE_FOREGROUND); } real_OSReleaseForeground(); } hooks_magic_t method_hooks_hooks_static[] __attribute__((section(".data"))) = { - MAKE_MAGIC(GX2SetTVBuffer, LIB_GX2, STATIC_FUNCTION), - MAKE_MAGIC(GX2SetDRCBuffer, LIB_GX2, STATIC_FUNCTION), - MAKE_MAGIC(GX2WaitForVsync, LIB_GX2, STATIC_FUNCTION), + //MAKE_MAGIC(GX2SetTVBuffer, LIB_GX2, STATIC_FUNCTION), + //MAKE_MAGIC(GX2SetDRCBuffer, LIB_GX2, STATIC_FUNCTION), + //MAKE_MAGIC(GX2WaitForVsync, LIB_GX2, STATIC_FUNCTION), //MAKE_MAGIC(GX2CopyColorBufferToScanBuffer, LIB_GX2, STATIC_FUNCTION), //MAKE_MAGIC(GX2SetContextState, LIB_GX2, STATIC_FUNCTION), MAKE_MAGIC(VPADRead, LIB_VPAD, STATIC_FUNCTION), - MAKE_MAGIC(OSIsAddressValid, LIB_CORE_INIT, STATIC_FUNCTION), - MAKE_MAGIC(__OSPhysicalToEffectiveUncached, LIB_CORE_INIT, STATIC_FUNCTION), - MAKE_MAGIC(__OSPhysicalToEffectiveCached, LIB_CORE_INIT, STATIC_FUNCTION), - MAKE_MAGIC(OSEffectiveToPhysical, LIB_CORE_INIT, STATIC_FUNCTION), + //MAKE_MAGIC(OSIsAddressValid, LIB_CORE_INIT, STATIC_FUNCTION), + //MAKE_MAGIC(__OSPhysicalToEffectiveUncached, LIB_CORE_INIT, STATIC_FUNCTION), + //MAKE_MAGIC(__OSPhysicalToEffectiveCached, LIB_CORE_INIT, STATIC_FUNCTION), + //MAKE_MAGIC(OSEffectiveToPhysical, LIB_CORE_INIT, STATIC_FUNCTION), MAKE_MAGIC(OSReceiveMessage, LIB_CORE_INIT, STATIC_FUNCTION), MAKE_MAGIC(OSReleaseForeground, LIB_CORE_INIT, STATIC_FUNCTION) }; diff --git a/src/patcher/hooks_patcher_static.h b/source/patcher/hooks_patcher_static.h similarity index 100% rename from src/patcher/hooks_patcher_static.h rename to source/patcher/hooks_patcher_static.h diff --git a/source/plugin/DynamicLinkingHelper.cpp b/source/plugin/DynamicLinkingHelper.cpp new file mode 100644 index 0000000..0f34873 --- /dev/null +++ b/source/plugin/DynamicLinkingHelper.cpp @@ -0,0 +1,104 @@ +#include "DynamicLinkingHelper.h" +#include +#include +#include +#include +#include "utils/logger.h" +#include "common/plugin_defines.h" + +dyn_linking_function_t * DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_linking_relocation_data_t * data, const char* functionName) { + if(data == NULL) { + return NULL; + } + if(functionName == NULL) { + return NULL; + } + dyn_linking_function_t * result = NULL; + for(int32_t i = 0; i < DYN_LINK_FUNCTION_LIST_LENGTH; i++) { + dyn_linking_function_t * curEntry = &(data->functions[i]); + if(strlen(curEntry->functionName) == 0) { + if(strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) { + DEBUG_FUNCTION_LINE("Failed to add function name, it's too long.\n"); + return NULL; + } + strncpy(curEntry->functionName,functionName,DYN_LINK_FUNCTION_NAME_LENGTH); + result = curEntry; + break; + } + if(strncmp(curEntry->functionName,functionName,DYN_LINK_FUNCTION_NAME_LENGTH) == 0) { + result = curEntry; + break; + } + } + return result; +} + +dyn_linking_import_t * DynamicLinkingHelper::getOrAddFunctionImportByName(dyn_linking_relocation_data_t * data, const char* importName) { + return getOrAddImport(data, importName, false); +} + +dyn_linking_import_t * DynamicLinkingHelper::getOrAddDataImportByName(dyn_linking_relocation_data_t * data, const char* importName) { + return getOrAddImport(data, importName, true); +} + +dyn_linking_import_t * DynamicLinkingHelper::getOrAddImport(dyn_linking_relocation_data_t * data, const char* importName, bool isData) { + if(importName == NULL || data == NULL) { + return NULL; + } + dyn_linking_import_t * result = NULL; + for(int32_t i = 0; i < DYN_LINK_IMPORT_LIST_LENGTH; i++) { + dyn_linking_import_t * curEntry = &(data->imports[i]); + if(strlen(curEntry->importName) == 0) { + if(strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) { + DEBUG_FUNCTION_LINE("Failed to add Import, it's too long.\n"); + return NULL; + } + strncpy(curEntry->importName,importName,DYN_LINK_IMPORT_NAME_LENGTH); + curEntry->isData = isData; + result = curEntry; + break; + } + if(strncmp(curEntry->importName,importName,DYN_LINK_IMPORT_NAME_LENGTH) == 0 && (curEntry->isData == isData)) { + return curEntry; + } + } + return result; +} + +bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, const RelocationData& relocationData) { + return addReloationEntry(linking_data, linking_entries, linking_entry_length, relocationData.getType(), relocationData.getOffset(), relocationData.getAddend(), relocationData.getDestination(), relocationData.getName(), relocationData.getImportRPLInformation()); +} + +bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, const void *destination, const std::string& name, const ImportRPLInformation& rplInfo) { + dyn_linking_import_t * importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, rplInfo.getName().c_str(),rplInfo.isData()); + if(importInfoGbl == NULL) { + DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d rpl files to import reached.\n",DYN_LINK_IMPORT_LIST_LENGTH); + return false; + } + + dyn_linking_function_t * functionInfo = DynamicLinkingHelper::getOrAddFunctionEntryByName(linking_data, name.c_str()); + if(functionInfo == NULL) { + DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d function to be relocated reached.\n",DYN_LINK_FUNCTION_LIST_LENGTH); + return false; + } + + return addReloationEntry(linking_entries, linking_entry_length, type, offset, addend, destination, functionInfo, importInfoGbl); +} + +bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, const void *destination, dyn_linking_function_t * functionName, dyn_linking_import_t * importInfo) { + for(uint32_t i = 0; i < linking_entry_length; i++) { + dyn_linking_relocation_entry_t * curEntry = &(linking_entries[i]); + if(curEntry->functionEntry != NULL) { + continue; + } + curEntry->type = type; + curEntry->offset = offset; + curEntry->addend = addend; + curEntry->destination = (void*) destination; + curEntry->functionEntry = functionName; + curEntry->importEntry = importInfo; + + return true; + } + return false; +} diff --git a/src/plugin/DynamicLinkingHelper.h b/source/plugin/DynamicLinkingHelper.h similarity index 55% rename from src/plugin/DynamicLinkingHelper.h rename to source/plugin/DynamicLinkingHelper.h index 7a5bef8..22e283f 100644 --- a/src/plugin/DynamicLinkingHelper.h +++ b/source/plugin/DynamicLinkingHelper.h @@ -1,8 +1,5 @@ -#ifndef DYNAMICLINKINGHELPER_H -#define DYNAMICLINKINGHELPER_H - -#include "common/retain_vars.h" -#include "dynamic_linking_defines.h" +#pragma once +#include "common/dynamic_linking_defines.h" #include "utils/logger.h" #include #include @@ -10,28 +7,13 @@ class DynamicLinkingHelper { public: - static DynamicLinkingHelper *getInstance() { - if(!instance) { - instance = new DynamicLinkingHelper(); - } - return instance; - } - - static void destroyInstance() { - if(instance) { - delete instance; - instance = NULL; - } - } - - /** Gets the function entry for a given function name. If the function name is not present in the list, it will be added. \param functionName Name of the function \return Returns a pointer to the entry which contains the functionName. Null on error or if the list full. **/ - dyn_linking_function_t * getOrAddFunctionEntryByName(const char * functionName); + static dyn_linking_function_t * getOrAddFunctionEntryByName(dyn_linking_relocation_data_t * data, const char * functionName); /** Gets the function import entry for a given function name. If the import is not present in the list, it will be added. @@ -40,7 +22,7 @@ public: \param importName Name of the function \return Returns a pointer to the function import entry which contains the importName. Null on error or if the list full. **/ - dyn_linking_import_t * getOrAddFunctionImportByName(const char * importName); + static dyn_linking_import_t * getOrAddFunctionImportByName(dyn_linking_relocation_data_t * data, const char * importName); /** @@ -50,7 +32,7 @@ public: \param importName Name of the data \return Returns a pointer to the data import entry which contains the importName. Null on error or if the list full. **/ - dyn_linking_import_t * getOrAddDataImportByName(const char * importName); + static dyn_linking_import_t * getOrAddDataImportByName(dyn_linking_relocation_data_t * data, const char * importName); /** @@ -62,33 +44,17 @@ public: \return Returns a pointer to the data import entry which contains the importName. Null on error or if the list full. **/ - dyn_linking_import_t * getOrAddImport(const char * importName, bool isData); + static dyn_linking_import_t * getOrAddImport(dyn_linking_relocation_data_t * data, const char * importName, bool isData); + static bool addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, const RelocationData& relocationData); - bool addReloationEntry(RelocationData * relocationData); + static bool addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, const void *destination, const std::string& name, const ImportRPLInformation& rplInfo); - bool addReloationEntry(char type, size_t offset, int32_t addend, void *destination, std::string name, ImportRPLInformation * rplInfo); - - bool addReloationEntry(char type, size_t offset, int32_t addend, void *destination, dyn_linking_function_t * functionName, dyn_linking_import_t * importInfo); - - std::vector getAllValidDynamicLinkingRelocations(); - - bool fillRelocations(std::vector entries ); - - void clearAll(); - - -protected: + static bool addReloationEntry(dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, const void *destination, dyn_linking_function_t * functionName, dyn_linking_import_t * importInfo); private: - DynamicLinkingHelper() { } ~DynamicLinkingHelper() { - } - - static DynamicLinkingHelper *instance; }; - -#endif // DYNAMICLINKINGHELPER_H diff --git a/src/plugin/FunctionData.h b/source/plugin/FunctionData.h similarity index 72% rename from src/plugin/FunctionData.h rename to source/plugin/FunctionData.h index d2a3721..4f351ef 100644 --- a/src/plugin/FunctionData.h +++ b/source/plugin/FunctionData.h @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (C) 2018 Maschell + * Copyright (C) 2018-2020 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 @@ -14,9 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . ****************************************************************************/ - -#ifndef _FUNCTION_DATA_H_ -#define _FUNCTION_DATA_H_ +#pragma once #include #include @@ -24,39 +22,39 @@ class FunctionData { public: - FunctionData(void * paddress, void * vaddress, const char * name, wups_loader_library_type_t library, void * target, void * call_addr) { + FunctionData(void * paddress, void * vaddress, const std::string& name, wups_loader_library_type_t library, void * replaceAddr, void * replaceCall) { this->paddress = paddress; this->vaddress = vaddress; this->name = name; this->library = library; - this->replaceAddr = target; - this->replaceCall = call_addr; + this->replaceAddr = replaceAddr; + this->replaceCall = replaceCall; } ~FunctionData() { } - std::string getName() { + const std::string& getName() const{ return this->name; } - wups_loader_library_type_t getLibrary() { + wups_loader_library_type_t getLibrary() const{ return this->library; } - void * getPhysicalAddress() { + const void * getPhysicalAddress() const{ return paddress; } - void * getVirtualAddress() { + const void * getVirtualAddress() const{ return vaddress; } - void * getReplaceAddress() { + const void * getReplaceAddress() const{ return replaceAddr; } - void * getReplaceCall() { + const void * getReplaceCall() const{ return replaceCall; } @@ -69,5 +67,3 @@ private: void * replaceCall = NULL; }; - -#endif diff --git a/src/plugin/HookData.h b/source/plugin/HookData.h similarity index 88% rename from src/plugin/HookData.h rename to source/plugin/HookData.h index 1884002..9c094d2 100644 --- a/src/plugin/HookData.h +++ b/source/plugin/HookData.h @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (C) 2018 Maschell + * Copyright (C) 2018-2020 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 @@ -15,8 +15,7 @@ * along with this program. If not, see . ****************************************************************************/ -#ifndef _HOOK_DATA_H_ -#define _HOOK_DATA_H_ +#pragma once #include #include @@ -33,17 +32,14 @@ public: } - void * getFunctionPointer() { + void * getFunctionPointer() const{ return function_pointer; } - wups_loader_hook_type_t getType() { + wups_loader_hook_type_t getType() const{ return this->type; } private: void * function_pointer; wups_loader_hook_type_t type; }; - - -#endif diff --git a/src/memory/memory.h b/source/plugin/ImportRPLInformation.h similarity index 63% rename from src/memory/memory.h rename to source/plugin/ImportRPLInformation.h index 4c8ea9b..01e1658 100644 --- a/src/memory/memory.h +++ b/source/plugin/ImportRPLInformation.h @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (C) 2015 Dimok + * 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 @@ -14,19 +14,32 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . ****************************************************************************/ -#ifndef __MEMORY_H_ -#define __MEMORY_H_ -#ifdef __cplusplus -extern "C" { -#endif +#pragma once -#include +#include +#include "utils/logger.h" -void initMemory(); +class ImportRPLInformation { -#ifdef __cplusplus -} -#endif +public: + ImportRPLInformation(std::string name, bool isData = false) { + this->name = name; + this->_isData = isData; + } -#endif // __MEMORY_H_ + ~ImportRPLInformation() { + } + + std::string getName() const { + return name; + } + + bool isData() const{ + return _isData; + } + +private: + std::string name; + bool _isData = false; +}; diff --git a/source/plugin/PluginContainer.h b/source/plugin/PluginContainer.h new file mode 100644 index 0000000..453f146 --- /dev/null +++ b/source/plugin/PluginContainer.h @@ -0,0 +1,56 @@ +/**************************************************************************** + * Copyright (C) 2020 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 . + ****************************************************************************/ + +#pragma once + +#include "PluginData.h" +#include "PluginMetaInformation.h" +#include "PluginInformation.h" + +class PluginContainer { +public: + PluginContainer(){ + + } + const PluginMetaInformation& getMetaInformation() const{ + return this->metaInformation; + } + + void setMetaInformation(PluginMetaInformation& metaInfo){ + this->metaInformation = metaInfo; + } + + const PluginInformation& getPluginInformation() const{ + return pluginInformation; + } + + void setPluginInformation(PluginInformation& pluginInformation){ + this->pluginInformation = pluginInformation; + } + + const PluginData& getPluginData() const{ + return pluginData; + } + + void setPluginData(PluginData& pluginData){ + this->pluginData = pluginData; + } + + PluginData pluginData; + PluginMetaInformation metaInformation; + PluginInformation pluginInformation; +}; diff --git a/source/plugin/PluginContainerPersistence.cpp b/source/plugin/PluginContainerPersistence.cpp new file mode 100644 index 0000000..cd034f0 --- /dev/null +++ b/source/plugin/PluginContainerPersistence.cpp @@ -0,0 +1,296 @@ +#include + +#include "PluginContainer.h" +#include "PluginInformationFactory.h" +#include "PluginMetaInformationFactory.h" +#include "PluginContainerPersistence.h" +#include "DynamicLinkingHelper.h" +#include "common/plugin_defines.h" +#include "PluginInformation.h" +#include "RelocationData.h" + +bool PluginContainerPersistence::savePlugin(plugin_information_t * pluginInformation, PluginContainer& plugin) { + + int32_t plugin_count = pluginInformation->number_used_plugins; + + auto pluginName = plugin.getMetaInformation().getName(); + //auto pluginPath = plugin.getMetaInformation().getPath(); + + + if(plugin_count >= MAXIMUM_PLUGINS - 1) { + DEBUG_FUNCTION_LINE("Maximum of %d plugins reached. %s won't be loaded!\n", MAXIMUM_PLUGINS, pluginName.c_str()); + return false; + } + // Copy data to global struct. + plugin_information_single_t * plugin_data = &(pluginInformation->plugin_data[plugin_count]); + + DEBUG_FUNCTION_LINE("%08X", plugin_data); + // Make sure everything is reset. + //plugin_data = {}; + memset((void*)plugin_data, 0, sizeof(plugin_information_single_t)); + + auto pluginMetaInfo = plugin.getMetaInformation(); + auto plugin_meta_data = &plugin_data->meta; + + if(pluginMetaInfo.getName().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) { + DEBUG_FUNCTION_LINE("Warning: name will be truncated."); + } + strncpy(plugin_meta_data->name, pluginMetaInfo.getName().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH-1); + if(pluginMetaInfo.getAuthor().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) { + DEBUG_FUNCTION_LINE("Warning: author will be truncated."); + } + strncpy(plugin_meta_data->author, pluginMetaInfo.getAuthor().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH-1); + + if(pluginMetaInfo.getVersion().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) { + DEBUG_FUNCTION_LINE("Warning: version will be truncated."); + } + strncpy(plugin_meta_data->version, pluginMetaInfo.getVersion().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH-1); + + if(pluginMetaInfo.getLicense().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) { + DEBUG_FUNCTION_LINE("Warning: license will be truncated."); + } + strncpy(plugin_meta_data->license, pluginMetaInfo.getLicense().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH-1); + + if(pluginMetaInfo.getBuildTimestamp().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) { + DEBUG_FUNCTION_LINE("Warning: build timestampt will be truncated."); + } + strncpy(plugin_meta_data->buildTimestamp, pluginMetaInfo.getBuildTimestamp().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH-1); + + if(pluginMetaInfo.getDescription().size() >= MAXIMUM_PLUGIN_DESCRIPTION_LENGTH) { + DEBUG_FUNCTION_LINE("Warning: description will be truncated."); + DEBUG_FUNCTION_LINE("%s", pluginMetaInfo.getDescription().c_str()); + } + strncpy(plugin_meta_data->descripion, pluginMetaInfo.getDescription().c_str(), MAXIMUM_PLUGIN_DESCRIPTION_LENGTH-1); + + plugin_meta_data->size = pluginMetaInfo.getSize(); + + auto pluginInfo = plugin.getPluginInformation(); + + + // Relocation + std::vector relocationData = pluginInfo.getRelocationDataList(); + for (auto & reloc : relocationData) { + if(!DynamicLinkingHelper::addReloationEntry(&(pluginInformation->linking_data), plugin_data->info.linking_entries, DYN_LINK_RELOCATION_LIST_LENGTH, reloc)) { + return false; + } + } + + + std::vector function_data_list = pluginInfo.getFunctionDataList(); + std::vector hook_data_list = pluginInfo.getHookDataList(); + + + if(function_data_list.size() > MAXIMUM_FUNCTION_PER_PLUGIN) { + DEBUG_FUNCTION_LINE("Plugin %s would replace to many function (%d, maximum is %d). It won't be loaded.",pluginName.c_str(), function_data_list.size(), MAXIMUM_FUNCTION_PER_PLUGIN); + return false; + } + if(hook_data_list.size() > MAXIMUM_HOOKS_PER_PLUGIN) { + DEBUG_FUNCTION_LINE("Plugin %s would set too many hooks (%d, maximum is %d). It won't be loaded.", pluginName.c_str(), hook_data_list.size(), MAXIMUM_HOOKS_PER_PLUGIN); + return false; + } + + if(pluginName.length() > MAXIMUM_PLUGIN_NAME_LENGTH-1) { + DEBUG_FUNCTION_LINE("Name for plugin %s was too long to be stored.", pluginName.c_str()); + return false; + } + + /* Store function replacement information */ + uint32_t i = 0; + for(auto & curFunction : pluginInfo.getFunctionDataList()) { + replacement_data_function_t * function_data = &plugin_data->info.functions[i]; + if(strlen(curFunction.getName().c_str()) > MAXIMUM_FUNCTION_NAME_LENGTH-1) { + DEBUG_FUNCTION_LINE("Could not add function \"%s\" for plugin \"%s\" function name is too long.", curFunction.getName().c_str(), pluginName.c_str()); + continue; + } + + DEBUG_FUNCTION_LINE("Adding function \"%s\" for plugin \"%s\"",curFunction.getName().c_str(), pluginName.c_str()); + + strncpy(function_data->function_name, curFunction.getName().c_str(),MAXIMUM_FUNCTION_NAME_LENGTH-1); + + function_data->library = curFunction.getLibrary(); + function_data->replaceAddr = (uint32_t) curFunction.getReplaceAddress(); + function_data->replaceCall = (uint32_t) curFunction.getReplaceCall(); + function_data->physicalAddr = (uint32_t) curFunction.getPhysicalAddress(); + function_data->virtualAddr = (uint32_t) curFunction.getVirtualAddress(); + + plugin_data->info.number_used_functions++; + i++; + } + + i = 0; + for(auto & curHook : pluginInfo.getHookDataList()) { + replacement_data_hook_t * hook_data = &plugin_data->info.hooks[i]; + + DEBUG_FUNCTION_LINE("Set hook for plugin \"%s\" of type %08X to target %08X",plugin_data->meta.name, curHook.getType(),(void*) curHook.getFunctionPointer()); + + hook_data->func_pointer = (void*) curHook.getFunctionPointer(); + hook_data->type = curHook.getType(); + + plugin_data->info.number_used_hooks++; + i++; + } + + /* Saving SectionInfos */ + for(auto & curSection : pluginInfo.getSectionInfoList()) { + bool foundFreeSlot = false; + uint32_t slot = 0; + for(uint32_t i = 0; i < MAXIMUM_PLUGIN_SECTION_LENGTH; i++) { + plugin_section_info_t * sectionInfo = &(plugin_data->info.sectionInfos[i]); + if(sectionInfo->addr == 0 && sectionInfo->size == 0) { + foundFreeSlot = true; + slot = i; + break; + } + } + if(foundFreeSlot) { + plugin_section_info_t * sectionInfo = &(plugin_data->info.sectionInfos[slot]); + if(strlen(curSection.first.c_str()) > MAXIMUM_PLUGIN_SECTION_NAME_LENGTH-1) { + DEBUG_FUNCTION_LINE("Could not add section info \"%s\" for plugin \"%s\" section name is too long.",curSection.first.c_str(), pluginName.c_str()); + break; + } + strncpy(sectionInfo->name, curSection.first.c_str(), MAXIMUM_PLUGIN_SECTION_NAME_LENGTH-1); + sectionInfo->addr = curSection.second.getAddress(); + sectionInfo->size = curSection.second.getSize(); + + } else { + DEBUG_FUNCTION_LINE("Failed to store SectionInfos"); + return false; + } + } + plugin_data->info.trampolinId = pluginInfo.getTrampolinId(); + + /* Copy plugin data */ + auto pluginData = plugin.getPluginData(); + auto plugin_data_data = &plugin_data->data; + + plugin_data_data->buffer = (char*)pluginData.buffer; + plugin_data_data->bufferLength = pluginData.length; + plugin_data_data->memoryType = pluginData.memoryType; + plugin_data_data->heapHandle = (int)pluginData.heapHandle; + + pluginInformation->number_used_plugins++; + + DCFlushRange((void*)pluginInformation,sizeof(plugin_information_t)); + ICInvalidateRange((void*)pluginInformation,sizeof(plugin_information_t)); + + return true; +} + +std::vector PluginContainerPersistence::loadPlugins(plugin_information_t * pluginInformation) { + std::vector result; + if(pluginInformation == NULL) { + DEBUG_FUNCTION_LINE("pluginInformation == NULL"); + return result; + } + DCFlushRange((void*)pluginInformation,sizeof(plugin_information_t)); + ICInvalidateRange((void*)pluginInformation,sizeof(plugin_information_t)); + + int32_t plugin_count = pluginInformation->number_used_plugins; + if(plugin_count > MAXIMUM_PLUGINS) { + DEBUG_FUNCTION_LINE("pluginInformation->plugin_count was bigger then allowed. %d > %d. Limiting to %d",plugin_count, MAXIMUM_PLUGINS, MAXIMUM_PLUGINS); + plugin_count = MAXIMUM_PLUGINS; + } + for(int32_t i = 0; i < plugin_count; i++) { + // Copy data from struct. + plugin_information_single_t * plugin_data = &(pluginInformation->plugin_data[i]); + + PluginMetaInformation metaInformation; + + plugin_meta_info_t * meta = &(plugin_data->meta); + metaInformation.setAuthor(meta->author); + metaInformation.setVersion(meta->version); + metaInformation.setBuildTimestamp(meta->buildTimestamp); + metaInformation.setLicense(meta->license); + metaInformation.setDescription(meta->descripion); + metaInformation.setSize(meta->size); + metaInformation.setName(meta->name); + + PluginData pluginData; + + plugin_data_t * data = &(plugin_data->data); + + pluginData.buffer = data->buffer; + pluginData.length = data->bufferLength; + pluginData.memoryType = (eMemoryTypes) data->memoryType; + pluginData.heapHandle = (MEMHeapHandle) data->heapHandle; + pluginData.loadReader(); + + PluginInformation pluginInformation; + + pluginInformation.setTrampolinId(plugin_data->info.trampolinId); + + for(uint32_t i = 0; i < MAXIMUM_PLUGIN_SECTION_LENGTH; i++) { + plugin_section_info_t * sectionInfo = &(plugin_data->info.sectionInfos[i]); + if(sectionInfo->addr == 0 && sectionInfo->size == 0) { + continue; + } + DEBUG_FUNCTION_LINE("Add SectionInfo %s", sectionInfo->name); + pluginInformation.addSectionInfo(SectionInfo(sectionInfo->name, sectionInfo->addr, sectionInfo->size)); + } + + /* load hook data */ + uint32_t hookCount = plugin_data->info.number_used_hooks; + + if(hookCount > MAXIMUM_HOOKS_PER_PLUGIN) { + DEBUG_FUNCTION_LINE("number_used_hooks was bigger then allowed. %d > %d. Limiting to %d",hookCount, MAXIMUM_HOOKS_PER_PLUGIN, MAXIMUM_HOOKS_PER_PLUGIN); + hookCount = MAXIMUM_HOOKS_PER_PLUGIN; + } + + for(uint32_t j = 0; j < hookCount; j++) { + replacement_data_hook_t * hook_entry = &(plugin_data->info.hooks[j]); + HookData curHook(hook_entry->func_pointer, hook_entry->type); + pluginInformation.addHookData(curHook); + } + + /* load function replacement data */ + uint32_t functionReplaceCount = plugin_data->info.number_used_functions; + + if(functionReplaceCount > MAXIMUM_FUNCTION_PER_PLUGIN) { + DEBUG_FUNCTION_LINE("number_used_functions was bigger then allowed. %d > %d. Limiting to %d",functionReplaceCount, MAXIMUM_FUNCTION_PER_PLUGIN, MAXIMUM_FUNCTION_PER_PLUGIN); + functionReplaceCount = MAXIMUM_FUNCTION_PER_PLUGIN; + } + + for(uint32_t j = 0; j < functionReplaceCount; j++) { + replacement_data_function_t * entry = &(plugin_data->info.functions[j]); + FunctionData func((void *) entry->physicalAddr, (void *) entry->virtualAddr, entry->function_name, entry->library, (void *) entry->replaceAddr, (void *) entry->replaceCall); + pluginInformation.addFunctionData(func); + } + + /* load relocation data */ + for(uint32_t j = 0; j < DYN_LINK_RELOCATION_LIST_LENGTH; j++) { + dyn_linking_relocation_entry_t * linking_entry = &(plugin_data->info.linking_entries[j]); + if(linking_entry->destination == NULL) { + break; + } + dyn_linking_import_t* importEntry = linking_entry->importEntry; + if(importEntry == NULL) { + DEBUG_FUNCTION_LINE("importEntry was NULL, skipping relocation entry"); + continue; + } + if(importEntry->importName == NULL) { + DEBUG_FUNCTION_LINE("importEntry->importName was NULL, skipping relocation entry"); + continue; + } + dyn_linking_function_t* functionEntry = linking_entry->functionEntry; + + if(functionEntry == NULL) { + DEBUG_FUNCTION_LINE("functionEntry was NULL, skipping relocation entry"); + continue; + } + if(functionEntry->functionName == NULL) { + DEBUG_FUNCTION_LINE("functionEntry->functionName was NULL, skipping relocation entry"); + continue; + } + ImportRPLInformation rplInfo(importEntry->importName, importEntry->isData); + RelocationData reloc(linking_entry->type, linking_entry->offset, linking_entry->addend, linking_entry->destination, functionEntry->functionName, rplInfo); + pluginInformation.addRelocationData(reloc); + } + + PluginContainer container; + container.setMetaInformation(metaInformation); + container.setPluginData(pluginData); + container.setPluginInformation(pluginInformation); + result.push_back(container); + } + return result; +} diff --git a/source/plugin/PluginContainerPersistence.h b/source/plugin/PluginContainerPersistence.h new file mode 100644 index 0000000..0a66a4a --- /dev/null +++ b/source/plugin/PluginContainerPersistence.h @@ -0,0 +1,10 @@ +#pragma once + +#include "common/plugin_defines.h" +#include "PluginContainer.h" + +class PluginContainerPersistence { +public: + static bool savePlugin(plugin_information_t * pluginInformation, PluginContainer& plugin); + static std::vector loadPlugins(plugin_information_t * pluginInformation); +}; diff --git a/source/plugin/PluginData.cpp b/source/plugin/PluginData.cpp new file mode 100644 index 0000000..26ffec2 --- /dev/null +++ b/source/plugin/PluginData.cpp @@ -0,0 +1,76 @@ +#include "PluginData.h" + +void PluginData::freeMemory() { + if(buffer == NULL) { + return; + } + + switch(memoryType) { + default: + case eMemTypeExpHeap: + MEMFreeToExpHeap(this->heapHandle, buffer); + this->buffer = NULL; + break; + case eMemTypeMEM2: + free(this->buffer); + this->buffer = NULL; + break; + } +} + +PluginData::PluginData(std::vector buffer) : PluginData(buffer, 0, eMemTypeMEM2) { +} + +void PluginData::loadReader() { + if(this->buffer == NULL) { + this->reader = std::nullopt; + } else { + elfio * nReader = new elfio; + if(nReader != NULL && nReader->load((char*)this->buffer, length)) { + DEBUG_FUNCTION_LINE("Loading was okay"); + this->reader = nReader; + } else { + if(nReader){ + delete nReader; + nReader = NULL; + } + DEBUG_FUNCTION_LINE("Loading failed"); + this->reader = std::nullopt; + } + } +} + + +PluginData::PluginData(std::vector input, MEMHeapHandle heapHandle, eMemoryTypes memoryType): + heapHandle(heapHandle), + memoryType(memoryType), + length(input.size()) { + void * data_copy = NULL; + switch(memoryType) { + default: + case eMemTypeExpHeap: + data_copy = MEMAllocFromExpHeapEx(heapHandle, length, 4); + if(data_copy == NULL) { + DEBUG_FUNCTION_LINE("Failed to allocate space on exp heap"); + } else { + memcpy(data_copy, &input[0], length); + } + this->buffer = data_copy; + DEBUG_FUNCTION_LINE("copied data to exp heap"); + break; + case eMemTypeMEM2: + data_copy = memalign(length, 4); + if(data_copy == NULL) { + DEBUG_FUNCTION_LINE("Failed to allocate space on default heap"); + } else { + memcpy(data_copy, &input[0], length); + } + this->buffer = data_copy; + break; + } + loadReader(); +} + +std::optional PluginData::createFromExistingData(const void* buffer, MEMHeapHandle heapHandle, eMemoryTypes memoryType, const size_t length) { + return std::nullopt; +} diff --git a/source/plugin/PluginData.h b/source/plugin/PluginData.h new file mode 100644 index 0000000..987946f --- /dev/null +++ b/source/plugin/PluginData.h @@ -0,0 +1,68 @@ +/**************************************************************************** + * Copyright (C) 2020 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 . + ****************************************************************************/ + +#pragma once +#include +#include +#include +#include + +#include "elfio/elfio.hpp" + +using namespace ELFIO; + +enum eMemoryTypes { + eMemTypeMEM2, + eMemTypeExpHeap +}; + +class PluginData { +public: + const std::optional& getReader() const { + return reader; + } + ~PluginData() { + if(nReader != NULL) { + delete nReader; + nReader = NULL; + } + } + + + void freeMemory(); +private: + PluginData() { + } + + PluginData(std::vector buffer); + PluginData(std::vector input, MEMHeapHandle heapHandle, eMemoryTypes memoryType); + + + void loadReader(); + + static std::optional createFromExistingData(const void* buffer, MEMHeapHandle heapHandle, eMemoryTypes memoryType, const size_t length); + + std::optional reader; + elfio* nReader = NULL; + void* buffer; + MEMHeapHandle heapHandle; + eMemoryTypes memoryType; + size_t length; + friend class PluginDataFactory; + friend class PluginContainer; + friend class PluginContainerPersistence; +}; diff --git a/source/plugin/PluginDataFactory.cpp b/source/plugin/PluginDataFactory.cpp new file mode 100644 index 0000000..f8addaa --- /dev/null +++ b/source/plugin/PluginDataFactory.cpp @@ -0,0 +1,112 @@ +/**************************************************************************** + * 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 . + ****************************************************************************/ +#include +#include +#include +#include +#include +#include "PluginDataFactory.h" +#include "utils/logger.h" +#include "utils/StringTools.h" + + +std::vector PluginDataFactory::loadDir(const std::string & path, MEMHeapHandle heapHandle) { + std::vector result; + struct dirent *dp; + DIR *dfd = NULL; + + if(path.empty()) { + DEBUG_FUNCTION_LINE("Path was empty\n"); + return result; + } + + if ((dfd = opendir(path.c_str())) == NULL) { + DEBUG_FUNCTION_LINE("Couldn't open dir %s\n",path.c_str()); + return result; + } + + while ((dp = readdir(dfd)) != NULL) { + struct stat stbuf ; + std::string full_file_path = StringTools::strfmt("%s/%s",path.c_str(),dp->d_name); + StringTools::RemoveDoubleSlashs(full_file_path); + if( stat(full_file_path.c_str(),&stbuf ) == -1 ) { + DEBUG_FUNCTION_LINE("Unable to stat file: %s\n",full_file_path.c_str()) ; + continue; + } + + if ( ( stbuf.st_mode & S_IFMT ) == S_IFDIR ) { // Skip directories + continue; + } else { + DEBUG_FUNCTION_LINE("Found file: %s\n",full_file_path.c_str()) ; + auto pluginData = load(full_file_path, heapHandle); + if(pluginData) { + result.push_back(pluginData.value()); + } + } + } + if(dfd != NULL) { + closedir(dfd); + } + + return result; +} + +std::optional PluginDataFactory::load(const std::string & filename, MEMHeapHandle heapHandle) { + // open the file: + DEBUG_FUNCTION_LINE(); + std::ifstream file(filename, std::ios::binary); + DEBUG_FUNCTION_LINE(); + if(!file.is_open()){ + DEBUG_FUNCTION_LINE("Failed to open %s", filename.c_str()); + return std::nullopt; + } + // Stop eating new lines in binary mode!!! + file.unsetf(std::ios::skipws); + DEBUG_FUNCTION_LINE(); + // get its size: + std::streampos fileSize; + DEBUG_FUNCTION_LINE(); + + file.seekg(0, std::ios::end); + fileSize = file.tellg(); + file.seekg(0, std::ios::beg); + + DEBUG_FUNCTION_LINE(); + + std::vector vBuffer; + vBuffer.reserve(fileSize); + + + DEBUG_FUNCTION_LINE(); + // read the data: + vBuffer.insert(vBuffer.begin(), + std::istream_iterator(file), + std::istream_iterator()); + + DEBUG_FUNCTION_LINE("Loaded file"); + + return load(vBuffer, heapHandle); +} + +std::optional PluginDataFactory::load(std::vector& buffer, MEMHeapHandle heapHandle) { + if(buffer.empty()){ + return std::nullopt; + } + + PluginData pluginData(buffer, heapHandle, eMemoryTypes::eMemTypeExpHeap); + return pluginData; +} diff --git a/src/utils/mem_utils.cpp b/source/plugin/PluginDataFactory.h similarity index 56% rename from src/utils/mem_utils.cpp rename to source/plugin/PluginDataFactory.h index 6f6c883..622cfd9 100644 --- a/src/utils/mem_utils.cpp +++ b/source/plugin/PluginDataFactory.h @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (C) 2018 Maschell + * Copyright (C) 2020 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 @@ -14,24 +14,18 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . ****************************************************************************/ -#include -#include -#include -#include "dynamic_libs/coreinit.h" -#include "mem_utils.h" -#include "memory/memory_mapping.h" +#pragma once -int32_t memHandleVideo __attribute__((section(".data"))) = -1; +#include +#include +#include +#include +#include "PluginData.h" -void MemoryUtils::init() { - memHandleVideo = MEMCreateExpHeapEx((void*)MemoryMapping::getVideoMemoryAddress(), MemoryMapping::getVideoMemorySize(), 0); -} - -void* MemoryUtils::alloc(uint32_t size, int32_t align) { - return MEMAllocFromExpHeapEx(memHandleVideo,size, align); -} - -void MemoryUtils::free(void * ptr) { - MEMFreeToExpHeap(memHandleVideo,ptr); -} +class PluginDataFactory { +public: + static std::vector loadDir(const std::string & path, MEMHeapHandle heapHandle); + static std::optional load(const std::string & path, MEMHeapHandle heapHandle); + static std::optional load(std::vector& buffer, MEMHeapHandle heapHandle); +}; diff --git a/source/plugin/PluginInformation.h b/source/plugin/PluginInformation.h new file mode 100644 index 0000000..1bda3d8 --- /dev/null +++ b/source/plugin/PluginInformation.h @@ -0,0 +1,95 @@ +/**************************************************************************** + * 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 . + ****************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include "PluginMetaInformation.h" +#include "RelocationData.h" +#include "HookData.h" +#include "FunctionData.h" +#include "SectionInfo.h" + +class PluginInformation { +public: + PluginInformation(){ + } + + virtual ~PluginInformation() { + } + + void addHookData(const HookData& hook_data) { + hook_data_list.push_back(hook_data); + } + + const std::vector& getHookDataList() const { + return hook_data_list; + } + + void addFunctionData(const FunctionData &function_data) { + function_data_list.push_back(function_data); + } + + const std::vector& getFunctionDataList() const { + return function_data_list; + } + + void addRelocationData(const RelocationData &relocation_data) { + relocation_data_list.push_back(relocation_data); + } + + const std::vector& getRelocationDataList() const { + return relocation_data_list; + } + + void addSectionInfo(const SectionInfo& sectionInfo) { + section_info_list[sectionInfo.getName()] = sectionInfo; + } + + const std::map& getSectionInfoList() const { + return section_info_list; + } + + std::optional getSectionInfo(const std::string& sectionName) const { + if(getSectionInfoList().count(sectionName) > 0) { + return section_info_list.at(sectionName); + } + return std::nullopt; + } + + void setTrampolinId(uint8_t trampolinId) { + this->trampolinId = trampolinId; + } + + uint8_t getTrampolinId() const { + return trampolinId; + } +private: + + std::vector hook_data_list; + std::vector function_data_list; + std::vector relocation_data_list; + std::map section_info_list; + + uint8_t trampolinId = 0; + + friend class PluginInformationFactory; + friend class PluginInformationPersistence; +}; diff --git a/source/plugin/PluginInformationFactory.cpp b/source/plugin/PluginInformationFactory.cpp new file mode 100644 index 0000000..e542293 --- /dev/null +++ b/source/plugin/PluginInformationFactory.cpp @@ -0,0 +1,349 @@ +/**************************************************************************** + * 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 . + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include "PluginData.h" +#include "PluginInformationFactory.h" +#include "HookData.h" +#include "SectionInfo.h" +#include "elfio/elfio.hpp" +#include "utils/utils.h" +#include "utils/ElfUtils.h" +#include "utils/StringTools.h" + +using namespace ELFIO; + +std::optional PluginInformationFactory::load(const PluginData & pluginData, MEMHeapHandle heapHandle, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, uint8_t trampolinId) { + auto readerOpt = pluginData.getReader(); + if(!readerOpt) { + DEBUG_FUNCTION_LINE("Can't find or process ELF file"); + return std::nullopt; + } + auto reader = readerOpt.value(); + PluginInformation pluginInfo; + + uint32_t sec_num = reader->sections.size(); + uint8_t **destinations = (uint8_t **) malloc(sizeof(uint8_t *) * sec_num); + + uint32_t totalSize = 0; + + uint32_t text_size = 0; + uint32_t data_size = 0; + + for(uint32_t i = 0; i < sec_num; ++i ) { + section* psec = reader->sections[i]; + if (psec->get_type() == 0x80000002) { + continue; + } + + if ((psec->get_type() == SHT_PROGBITS || psec->get_type() == SHT_NOBITS) && (psec->get_flags() & SHF_ALLOC)) { + uint32_t sectionSize = psec->get_size(); + uint32_t address = (uint32_t) psec->get_address(); + if((address >= 0x02000000) && address < 0x10000000) { + text_size += sectionSize; + } else if((address >= 0x10000000) && address < 0xC0000000) { + data_size += sectionSize; + } + } + } + + void * text_data = MEMAllocFromExpHeapEx(heapHandle, text_size, 0x1000); + + if(text_data == NULL) { + DEBUG_FUNCTION_LINE("Failed to alloc memory for the .text section (%d bytes)\n", text_size); + + return std::nullopt; + } + DEBUG_FUNCTION_LINE("Allocated %d kb from ExpHeap", text_size/1024); + void * data_data = MEMAllocFromExpHeapEx(heapHandle, data_size, 0x1000); + if(data_data == NULL) { + DEBUG_FUNCTION_LINE("Failed to alloc memory for the .data section (%d bytes)\n", data_size); + + MEMFreeToExpHeap(heapHandle, text_data); + return std::nullopt; + } + DEBUG_FUNCTION_LINE("Allocated %d kb from ExpHeap", data_size/1024); + + uint32_t entrypoint = (uint32_t)text_data + (uint32_t) reader->get_entry() - 0x02000000; + + for(uint32_t i = 0; i < sec_num; ++i ) { + section* psec = reader->sections[i]; + if (psec->get_type() == 0x80000002) { + continue; + } + + if ((psec->get_type() == SHT_PROGBITS || psec->get_type() == SHT_NOBITS) && (psec->get_flags() & SHF_ALLOC)) { + uint32_t sectionSize = psec->get_size(); + uint32_t address = (uint32_t) psec->get_address(); + + uint32_t destination = address; + if((address >= 0x02000000) && address < 0x10000000) { + destination += (uint32_t) text_data; + destination -= 0x02000000; + destinations[psec->get_index()] = (uint8_t *) text_data; + } else if((address >= 0x10000000) && address < 0xC0000000) { + destination += (uint32_t) data_data; + destination -= 0x10000000; + destinations[psec->get_index()] = (uint8_t *) data_data; + } else if(address >= 0xC0000000) { + destination += (uint32_t) data_data; + destination -= 0xC0000000; + //destinations[psec->get_index()] = (uint8_t *) data_data; + //destinations[psec->get_index()] -= 0xC0000000; + } else { + DEBUG_FUNCTION_LINE("Unhandled case"); + free(destinations); + MEMFreeToExpHeap(heapHandle, text_data); + MEMFreeToExpHeap(heapHandle, data_data); + return std::nullopt; + } + + const char* p = psec->get_data(); + + if(psec->get_type() == SHT_NOBITS) { + DEBUG_FUNCTION_LINE("memset section %s %08X to 0 (%d bytes)", psec->get_name().c_str(), destination, sectionSize); + memset((void*) destination, 0, sectionSize); + } else if(psec->get_type() == SHT_PROGBITS) { + DEBUG_FUNCTION_LINE("Copy section %s %08X -> %08X (%d bytes)", psec->get_name().c_str(), p, destination, sectionSize); + memcpy((void*) destination, p, sectionSize); + } + + pluginInfo.addSectionInfo(SectionInfo(psec->get_name(), destination, sectionSize)); + DEBUG_FUNCTION_LINE("Saved %s section info. Location: %08X size: %08X", psec->get_name().c_str(), destination, sectionSize); + + totalSize += sectionSize; + + DCFlushRange((void*)destination, sectionSize); + ICInvalidateRange((void*)destination, sectionSize); + } + } + + for(uint32_t i = 0; i < sec_num; ++i ) { + section* psec = reader->sections[i]; + if ((psec->get_type() == SHT_PROGBITS || psec->get_type() == SHT_NOBITS) && (psec->get_flags() & SHF_ALLOC)) { + DEBUG_FUNCTION_LINE("Linking (%d)... %s at %08X",i,psec->get_name().c_str(), destinations[psec->get_index()]); + + if (!linkSection(pluginData, psec->get_index(), (uint32_t) destinations[psec->get_index()], (uint32_t) text_data, (uint32_t) data_data, trampolin_data, trampolin_data_length, trampolinId)) { + DEBUG_FUNCTION_LINE("elfLink failed"); + free(destinations); + MEMFreeToExpHeap(heapHandle, text_data); + MEMFreeToExpHeap(heapHandle, data_data); + return std::nullopt; + } + } + } + std::vector relocationData = getImportRelocationData(pluginData, destinations); + + for (auto const& reloc : relocationData) { + pluginInfo.addRelocationData(reloc); + } + + DCFlushRange((void*)text_data, text_size); + ICInvalidateRange((void*)text_data, text_size); + DCFlushRange((void*)data_data, data_size); + ICInvalidateRange((void*)data_data, data_size); + + free(destinations); + + pluginInfo.setTrampolinId(trampolinId); + + DEBUG_FUNCTION_LINE("Saved entrypoint as %08X", entrypoint); + + std::optional secInfo = pluginInfo.getSectionInfo(".wups.hooks"); + if(secInfo && secInfo->getSize() > 0) { + size_t entries_count = secInfo->getSize() / sizeof(wups_loader_hook_t); + wups_loader_hook_t * entries = (wups_loader_hook_t *) secInfo->getAddress(); + if(entries != NULL) { + for(size_t j=0; jgetName().c_str()*/,hook->type,(void*) hook->target); + HookData hook_data((void *) hook->target,hook->type); + pluginInfo.addHookData(hook_data); + } + } + } + + secInfo = pluginInfo.getSectionInfo(".wups.load"); + if(secInfo && secInfo->getSize() > 0) { + size_t entries_count = secInfo->getSize() / sizeof(wups_loader_entry_t); + wups_loader_entry_t * entries = (wups_loader_entry_t *) secInfo->getAddress(); + if(entries != NULL) { + for(size_t j=0; j_function.name/*,pluginData.getPluginInformation()->getName().c_str()*/,cur_function->_function.physical_address,cur_function->_function.virtual_address, cur_function->_function.library,cur_function->_function.target, (void *) cur_function->_function.call_addr); + FunctionData function_data((void *) cur_function->_function.physical_address,(void *) cur_function->_function.virtual_address, cur_function->_function.name, cur_function->_function.library, (void *) cur_function->_function.target, (void *) cur_function->_function.call_addr); + pluginInfo.addFunctionData(function_data); + } + } + } + + return pluginInfo; +} + +std::vector PluginInformationFactory::getImportRelocationData(const PluginData &pluginData, uint8_t ** destinations) { + auto readerOpt = pluginData.getReader(); + + std::vector result; + if(!readerOpt) { + return result; + } + auto reader = readerOpt.value(); + std::map infoMap; + + uint32_t sec_num = reader->sections.size(); + + for ( uint32_t i = 0; i < sec_num; ++i ) { + section* psec = reader->sections[i]; + if (psec->get_type() == 0x80000002) { + infoMap[i] = psec->get_name(); + } + } + + for (uint32_t i = 0; i < sec_num; ++i ) { + section* psec = reader->sections[i]; + if(psec->get_type() == SHT_RELA || psec->get_type() == SHT_REL) { + DEBUG_FUNCTION_LINE("Found relocation section %s",psec->get_name().c_str()); + relocation_section_accessor rel(*reader, psec); + for ( uint32_t j = 0; j < (uint32_t) rel.get_entries_num(); ++j ) { + Elf64_Addr offset; + Elf_Word type; + Elf_Sxword addend; + std::string sym_name; + Elf64_Addr sym_value; + Elf_Half sym_section_index; + + if(!rel.get_entry(j, offset, sym_value, sym_name, type, addend, sym_section_index)) { + DEBUG_FUNCTION_LINE("Failed to get relocation"); + break; + } + + uint32_t adjusted_sym_value = (uint32_t) sym_value; + if(adjusted_sym_value < 0xC0000000) { + continue; + } + + std::string fimport = ".fimport_"; + std::string dimport = ".dimport_"; + + bool isData = false; + + std::string rplName = ""; + std::string rawSectionName = infoMap[sym_section_index]; + + if(rawSectionName.size() < fimport.size()) { + DEBUG_FUNCTION_LINE("Section name was shorter than expected, skipping this relocation"); + continue; + } else if (std::equal(fimport.begin(), fimport.end(), rawSectionName.begin())) { + rplName = rawSectionName.substr(fimport.size()); + } else if (std::equal(dimport.begin(), dimport.end(), rawSectionName.begin())) { + rplName = rawSectionName.substr(dimport.size()); + isData = true; + } else { + DEBUG_FUNCTION_LINE("invalid section name\n"); + continue; + } + + ImportRPLInformation rplInfo(rplName, isData); + + uint32_t section_index = psec->get_info(); + + result.push_back(RelocationData(type, offset - 0x02000000, addend, (void*)(destinations[section_index]), sym_name, rplInfo)); + } + } + } + return result; +} +bool PluginInformationFactory::linkSection(const PluginData& pluginData, uint32_t section_index, uint32_t destination, uint32_t base_text, uint32_t base_data, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, uint8_t trampolinId) { + auto readerOpt = pluginData.getReader(); + if(!readerOpt) { + return false; + } + auto reader = readerOpt.value(); + uint32_t sec_num = reader->sections.size(); + + for (uint32_t i = 0; i < sec_num; ++i ) { + section* psec = reader->sections[i]; + if(psec->get_info() == section_index) { + DEBUG_FUNCTION_LINE("Found relocation section %s",psec->get_name().c_str()); + relocation_section_accessor rel(*reader, psec); + for ( uint32_t j = 0; j < (uint32_t) rel.get_entries_num(); ++j ) { + Elf64_Addr offset; + Elf_Word type; + Elf_Sxword addend; + std::string sym_name; + Elf64_Addr sym_value; + Elf_Half sym_section_index; + + if(!rel.get_entry(j, offset, sym_value, sym_name, type, addend, sym_section_index)) { + DEBUG_FUNCTION_LINE("Failed to get relocation"); + break; + } + + uint32_t adjusted_sym_value = (uint32_t) sym_value; + if((adjusted_sym_value >= 0x02000000) && adjusted_sym_value < 0x10000000) { + adjusted_sym_value -= 0x02000000; + adjusted_sym_value += base_text; + } else if((adjusted_sym_value >= 0x10000000) && adjusted_sym_value < 0xC0000000) { + adjusted_sym_value -= 0x10000000; + adjusted_sym_value += base_data; + } else if(adjusted_sym_value >= 0xC0000000) { + //DEBUG_FUNCTION_LINE("Skip imports"); + // Skip imports + continue; + } else if(adjusted_sym_value == 0x0) { + // + } else { + DEBUG_FUNCTION_LINE("Unhandled case %08X",adjusted_sym_value); + return false; + } + + uint32_t adjusted_offset = (uint32_t) offset; + if((offset >= 0x02000000) && offset < 0x10000000) { + adjusted_offset -= 0x02000000; + } else if((adjusted_offset >= 0x10000000) && adjusted_offset < 0xC0000000) { + adjusted_offset -= 0x10000000; + } else if(adjusted_offset >= 0xC0000000) { + adjusted_offset -= 0xC0000000; + } + + if(sym_section_index == SHN_ABS) { + // + } else if(sym_section_index > SHN_LORESERVE) { + DEBUG_FUNCTION_LINE("NOT IMPLEMENTED: %04X", sym_section_index); + return false; + } + if(false) { + DEBUG_FUNCTION_LINE("sym_value %08X adjusted_sym_value %08X offset %08X adjusted_offset %08X", (uint32_t) sym_value, adjusted_sym_value, (uint32_t) offset, adjusted_offset); + } + if(!ElfUtils::elfLinkOne(type, adjusted_offset, addend, destination, adjusted_sym_value, trampolin_data, trampolin_data_length, RELOC_TYPE_FIXED, trampolinId)) { + DEBUG_FUNCTION_LINE("Link failed"); + return false; + } + } + DEBUG_FUNCTION_LINE("done"); + return true; + } + } + DEBUG_FUNCTION_LINE("Failed to find relocation section"); + return true; +} diff --git a/source/plugin/PluginInformationFactory.h b/source/plugin/PluginInformationFactory.h new file mode 100644 index 0000000..766c301 --- /dev/null +++ b/source/plugin/PluginInformationFactory.h @@ -0,0 +1,35 @@ +/**************************************************************************** + * Copyright (C) 2019 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 . + ****************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include +#include "common/relocation_defines.h" +#include "PluginInformation.h" +#include "PluginContainer.h" +#include "elfio/elfio.hpp" + +class PluginInformationFactory { +public: + static std::optional load(const PluginData & pluginData, MEMHeapHandle heaphandle, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, uint8_t trampolinId); + static bool linkSection(const PluginData & pluginData, uint32_t section_index, uint32_t destination, uint32_t base_text, uint32_t base_data, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, uint8_t trampolinId); + static std::vector getImportRelocationData(const PluginData & pluginData, uint8_t ** destinations); +}; diff --git a/source/plugin/PluginMetaInformation.h b/source/plugin/PluginMetaInformation.h new file mode 100644 index 0000000..cec70e4 --- /dev/null +++ b/source/plugin/PluginMetaInformation.h @@ -0,0 +1,96 @@ +/**************************************************************************** + * Copyright (C) 2019,2020 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 . + ****************************************************************************/ + +#pragma once + +#include +#include + +class PluginMetaInformation { +public: + const std::string getName() const { + return name; + } + + const std::string getAuthor() const { + return this->author; + } + + const std::string getVersion() const { + return this->version; + } + + const std::string getLicense() const { + return this->license; + } + + const std::string getBuildTimestamp() const { + return this->buildtimestamp; + } + + const std::string getDescription() const { + return this->description; + } + + const size_t getSize() const { + return this->size; + } + +private: + PluginMetaInformation() { + } + + void setName(const std::string& name) { + this->name = name; + } + + void setAuthor(const std::string& author) { + this->author = author; + } + + void setVersion(const std::string& version) { + this->version = version; + } + + void setLicense(const std::string& license) { + this->license = license; + } + + void setBuildTimestamp(const std::string& buildtimestamp) { + this->buildtimestamp = buildtimestamp; + } + + void setDescription(const std::string& description) { + this->description = description; + } + + void setSize(size_t size) { + this->size = size; + } + + std::string name; + std::string author; + std::string version; + std::string license; + std::string buildtimestamp; + std::string description; + size_t size; + + friend class PluginMetaInformationFactory; + friend class PluginContainerPersistence; + friend class PluginContainer; +}; diff --git a/source/plugin/PluginMetaInformationFactory.cpp b/source/plugin/PluginMetaInformationFactory.cpp new file mode 100644 index 0000000..bb99376 --- /dev/null +++ b/source/plugin/PluginMetaInformationFactory.cpp @@ -0,0 +1,108 @@ +/**************************************************************************** + * Copyright (C) 2018-2020 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 . + ****************************************************************************/ + +#include +#include +#include +#include +#include "utils/StringTools.h" +#include "PluginMetaInformationFactory.h" +#include "PluginMetaInformation.h" +#include "elfio/elfio.hpp" + +using namespace ELFIO; + +std::optional PluginMetaInformationFactory::loadPlugin(const PluginData& pluginData) { + auto readerOpt = pluginData.getReader(); + + // Load ELF data + if (!readerOpt) { + DEBUG_FUNCTION_LINE("Can't find or process ELF file"); + return std::nullopt; + } + auto reader = readerOpt.value(); + + DEBUG_FUNCTION_LINE("Found elfio reader"); + + size_t pluginSize = 0; + + PluginMetaInformation pluginInfo; + uint32_t sec_num = reader->sections.size(); + + DEBUG_FUNCTION_LINE("%d number of sections", sec_num); + + for(uint32_t i = 0; i < sec_num; ++i ) { + section* psec = reader->sections[i]; + + // Calculate total size: + if ((psec->get_type() == SHT_PROGBITS || psec->get_type() == SHT_NOBITS) && (psec->get_flags() & SHF_ALLOC)) { + uint32_t sectionSize = psec->get_size(); + uint32_t address = (uint32_t) psec->get_address(); + if((address >= 0x02000000) && address < 0x10000000) { + pluginSize += sectionSize; + } else if((address >= 0x10000000) && address < 0xC0000000) { + pluginSize += sectionSize; + } + } + + // Get meta information and check WUPS version: + if (psec->get_name().compare(".wups.meta") == 0) { + const void * sectionData = psec->get_data(); + uint32_t sectionSize = psec->get_size(); + + char * curEntry = (char *) sectionData; + while((uint32_t) curEntry < (uint32_t) sectionData + sectionSize) { + if (*curEntry == '\0') { + curEntry++; + continue; + } + + auto firstFound = std::string(curEntry).find_first_of("="); + if(firstFound != std::string::npos) { + curEntry[firstFound] = '\0'; + std::string key(curEntry); + std::string value(curEntry + firstFound + 1); + + if(key.compare("name") == 0) { + DEBUG_FUNCTION_LINE("Name = %s", value.c_str()); + pluginInfo.setName(value); + } else if(key.compare("author") == 0) { + pluginInfo.setAuthor(value); + } else if(key.compare("version") == 0) { + pluginInfo.setVersion(value); + } else if(key.compare("license") == 0) { + pluginInfo.setLicense(value); + } else if(key.compare("buildtimestamp") == 0) { + pluginInfo.setBuildTimestamp(value); + } else if(key.compare("description") == 0) { + pluginInfo.setDescription(value); + } else if(key.compare("wups") == 0) { + if(value.compare("0.2") != 0) { + DEBUG_FUNCTION_LINE("Warning: Ignoring plugin - Unsupported WUPS version: %s.\n", value); + return std::nullopt; + } + } + } + curEntry += strlen(curEntry) + 1; + } + } + } + + pluginInfo.setSize(pluginSize); + + return pluginInfo; +} diff --git a/src/utils/mem_utils.h b/source/plugin/PluginMetaInformationFactory.h similarity index 73% rename from src/utils/mem_utils.h rename to source/plugin/PluginMetaInformationFactory.h index bf7d7b9..925b775 100644 --- a/src/utils/mem_utils.h +++ b/source/plugin/PluginMetaInformationFactory.h @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (C) 2018 Maschell + * Copyright (C) 2019,2020 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 @@ -14,19 +14,16 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . ****************************************************************************/ -#ifndef __MEMORY_UTILS_UTILS_H_ -#define __MEMORY_UTILS_UTILS_H_ -class MemoryUtils { +#pragma once + +#include +#include +#include +#include "PluginMetaInformation.h" +#include "PluginData.h" + +class PluginMetaInformationFactory { public: - static void init(); - - static void* alloc(uint32_t size, int32_t align); - - static void free(void * ptr); -private: - MemoryUtils() {} - ~MemoryUtils() {} - + static std::optional loadPlugin(const PluginData& pluginData); }; -#endif diff --git a/src/plugin/RelocationData.h b/source/plugin/RelocationData.h similarity index 58% rename from src/plugin/RelocationData.h rename to source/plugin/RelocationData.h index f16c527..eecf766 100644 --- a/src/plugin/RelocationData.h +++ b/source/plugin/RelocationData.h @@ -15,65 +15,64 @@ * along with this program. If not, see . ****************************************************************************/ -#ifndef _RELOCATION_DATA_H_ -#define _RELOCATION_DATA_H_ +#pragma once -#include #include #include "ImportRPLInformation.h" class RelocationData { public: - RelocationData(char type, size_t offset, int32_t addend, void *destination, std::string name, ImportRPLInformation * rplInfo) { - this->type = type; - this->offset = offset; - this->addend = addend; - this->destination = destination; - this->name = name; - this->rplInfo = rplInfo; + RelocationData(const char type, size_t offset, int32_t addend, void *destination, std::string name, ImportRPLInformation rplInfo): + type(type), + offset(offset), + addend(addend), + destination(destination), + name(name), + rplInfo(rplInfo) { } - ~RelocationData() { - + RelocationData(const RelocationData &o2): + type(o2.type), + offset(o2.offset), + addend(o2.addend), + destination(o2.destination), + name(o2.name), + rplInfo(o2.rplInfo) { } - char getType() { + virtual ~RelocationData() { + } + + const char getType() const{ return type; } - size_t getOffset() { + const size_t getOffset() const{ return offset; } - int32_t getAddend() { + const int32_t getAddend() const{ return addend; } - void * getDestination() { + const void * getDestination() const{ return destination; } - std::string getName() { + const std::string& getName() const{ return name; } - ImportRPLInformation * getImportRPLInformation() { + const ImportRPLInformation& getImportRPLInformation() const{ return rplInfo; } - void printInformation() { - DEBUG_FUNCTION_LINE("%s destination: %08X offset: %08X type: %02X addend: %d rplName: %s isData: %d \n",name.c_str(), destination, offset, type, addend, rplInfo->getName().c_str(), rplInfo->isData() ); - } - private: char type; size_t offset; int32_t addend; void *destination; std::string name; - ImportRPLInformation * rplInfo; + ImportRPLInformation rplInfo; }; - - -#endif diff --git a/src/system/CMutex.h b/source/plugin/SectionInfo.h similarity index 52% rename from src/system/CMutex.h rename to source/plugin/SectionInfo.h index 410aa1d..2b4b4ac 100644 --- a/src/system/CMutex.h +++ b/source/plugin/SectionInfo.h @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (C) 2015 Dimok + * Copyright (C) 2019 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 @@ -14,54 +14,48 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . ****************************************************************************/ -#ifndef _CMUTEX_H_ -#define _CMUTEX_H_ -#include -#include +#pragma once + +#include + +class SectionInfo { -class CMutex { public: - CMutex() { - pMutex = malloc(OS_MUTEX_SIZE); - if(!pMutex) - return; - - OSInitMutex(pMutex); - } - virtual ~CMutex() { - if(pMutex) - free(pMutex); + SectionInfo(std::string name, uint32_t address, uint32_t sectionSize): + name(name), + address(address), + sectionSize(sectionSize) { } - void lock(void) { - if(pMutex) - OSLockMutex(pMutex); + SectionInfo(){ } - void unlock(void) { - if(pMutex) - OSUnlockMutex(pMutex); - } - bool tryLock(void) { - if(!pMutex) - return false; - return (OSTryLockMutex(pMutex) != 0); + SectionInfo(const SectionInfo &o2): + name(o2.name), + address(o2.address), + sectionSize(o2.sectionSize) { } + + + virtual ~SectionInfo() { + + } + + const std::string& getName() const { + return name; + } + + const uint32_t getAddress() const { + return address; + } + + const uint32_t getSize() const { + return sectionSize; + } + private: - void *pMutex; + std::string name; + uint32_t address; + uint32_t sectionSize; }; - -class CMutexLock { -public: - CMutexLock() { - mutex.lock(); - } - virtual ~CMutexLock() { - mutex.unlock(); - } -private: - CMutex mutex; -}; - -#endif // _CMUTEX_H_ diff --git a/source/utils/ElfUtils.cpp b/source/utils/ElfUtils.cpp new file mode 100644 index 0000000..50e8267 --- /dev/null +++ b/source/utils/ElfUtils.cpp @@ -0,0 +1,159 @@ +#include +#include +#include + +#include "utils/logger.h" + +#include "elfio/elfio.hpp" +#include "ElfUtils.h" + +// See https://github.com/decaf-emu/decaf-emu/blob/43366a34e7b55ab9d19b2444aeb0ccd46ac77dea/src/libdecaf/src/cafe/loader/cafe_loader_reloc.cpp#L144 +bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type, uint8_t trampolinId) { + if(type == R_PPC_NONE) { + return true; + } + + auto target = destination + offset; + auto value = symbol_addr + addend; + + auto relValue = value - static_cast(target); + + switch (type) { + case R_PPC_NONE: + break; + case R_PPC_ADDR32: + *((uint32_t *)(target)) = value; + break; + case R_PPC_ADDR16_LO: + *((uint16_t *)(target)) = static_cast(value & 0xFFFF); + break; + case R_PPC_ADDR16_HI: + *((uint16_t *)(target)) = static_cast(value >> 16); + break; + case R_PPC_ADDR16_HA: + *((uint16_t *)(target)) = static_cast((value + 0x8000) >> 16); + break; + case R_PPC_DTPMOD32: + DEBUG_FUNCTION_LINE("################IMPLEMENT ME\n"); + //*((int32_t *)(target)) = tlsModuleIndex; + break; + case R_PPC_DTPREL32: + *((uint32_t *)(target)) = value; + break; + case R_PPC_GHS_REL16_HA: + *((uint16_t *)(target)) = static_cast((relValue + 0x8000) >> 16); + break; + case R_PPC_GHS_REL16_HI: + *((uint16_t *)(target)) = static_cast(relValue >> 16); + break; + case R_PPC_GHS_REL16_LO: + *((uint16_t *)(target)) = static_cast(relValue & 0xFFFF); + break; + case R_PPC_REL14: { + auto distance = static_cast(value) - static_cast(target); + if (distance > 0x7FFC || distance < -0x7FFC) { + DEBUG_FUNCTION_LINE("***14-bit relative branch cannot hit target."); + return false; + } + + if (distance & 3) { + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470040); + return false; + } + + if ((distance >= 0 && (distance & 0xFFFF8000)) || + (distance < 0 && ((distance & 0xFFFF8000) != 0xFFFF8000))) { + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 17 bits before shift must all be the same.", -470040); + return false; + } + + *(int32_t *)target = (*(int32_t *)target & 0xFFBF0003) | (distance & 0x0000fffc); + break; + } + case R_PPC_REL24: { + // if (isWeakSymbol && !symbolValue) { + // symbolValue = static_cast(target); + // value = symbolValue + addend; + // } + auto distance = static_cast(value) - static_cast(target); + if (distance > 0x1FFFFFC || distance < -0x1FFFFFC) { + if(trampolin_data == NULL) { + DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin isn't provided\n"); + DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance); + return false; + } else { + relocation_trampolin_entry_t * freeSlot = NULL; + for(uint32_t i = 0; i < trampolin_data_length; i++) { + // We want to override "old" relocations of imports + // Pending relocations have the status RELOC_TRAMP_IMPORT_IN_PROGRESS. + // When all relocations are done successfully, they will be turned into RELOC_TRAMP_IMPORT_DONE + // so they can be overridden/updated/reused on the next application launch. + // + // Relocations that won't change will have the status RELOC_TRAMP_FIXED and are set to free when the module is unloaded. + if(trampolin_data[i].status == RELOC_TRAMP_FREE || + trampolin_data[i].status == RELOC_TRAMP_IMPORT_DONE) { + freeSlot = &(trampolin_data[i]); + break; + } + } + if(freeSlot != NULL) { + DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin data list is full\n"); + DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance); + return false; + } + if(target - (uint32_t)&(freeSlot->trampolin[0]) > 0x1FFFFFC) { + DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer)."); + DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance); + return false; + } + + DEBUG_FUNCTION_LINE("freeSlot = %08X", freeSlot); + + freeSlot->trampolin[0] = 0x3D600000 | ((((uint32_t) value) >> 16) & 0x0000FFFF); // lis r11, real_addr@h + freeSlot->trampolin[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l + freeSlot->trampolin[2] = 0x7D6903A6; // mtctr r11 + freeSlot->trampolin[3] = 0x4E800420; // bctr + DCFlushRange((void*)freeSlot->trampolin, sizeof(freeSlot->trampolin)); + ICInvalidateRange((unsigned char*)freeSlot->trampolin, sizeof(freeSlot->trampolin)); + + freeSlot->id = trampolinId; + DCFlushRange((void*)&freeSlot->id, sizeof(freeSlot->id)); + ICInvalidateRange((unsigned char*)&freeSlot->id, sizeof(freeSlot->id)); + + if(reloc_type == RELOC_TYPE_FIXED) { + freeSlot->status = RELOC_TRAMP_FIXED; + } else { + // Relocations for the imports may be overridden + freeSlot->status = RELOC_TRAMP_IMPORT_IN_PROGRESS; + } + uint32_t symbolValue = (uint32_t)&(freeSlot->trampolin[0]); + value = symbolValue + addend; + distance = static_cast(value) - static_cast(target); + DEBUG_FUNCTION_LINE("Created tramp\n"); + } + } + + if (distance & 3) { + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470022); + return false; + } + + if (distance < 0 && (distance & 0xFE000000) != 0xFE000000) { + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (1).", -470040); + return false; + } + + if (distance >= 0 && (distance & 0xFE000000)) { + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (0).", -470040); + return false; + } + + *(int32_t *)target = (*(int32_t *)target & 0xfc000003) | (distance & 0x03fffffc); + break; + } + default: + DEBUG_FUNCTION_LINE("***ERROR: Unsupported Relocation_Add Type (%08X):", type); + return false; + } + return true; +} diff --git a/source/utils/ElfUtils.h b/source/utils/ElfUtils.h new file mode 100644 index 0000000..6aa24b6 --- /dev/null +++ b/source/utils/ElfUtils.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include "common/relocation_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t * sizeOut); +uint32_t load_loader_elf_from_sd(unsigned char* baseAddress, const char* relativePath); +uint32_t load_loader_elf(unsigned char* baseAddress, char * elf_data, uint32_t fileSize); + +#define R_PPC_NONE 0 +#define R_PPC_ADDR32 1 +#define R_PPC_ADDR16_LO 4 +#define R_PPC_ADDR16_HI 5 +#define R_PPC_ADDR16_HA 6 +#define R_PPC_REL24 10 +#define R_PPC_REL14 11 +#define R_PPC_DTPMOD32 68 +#define R_PPC_DTPREL32 78 +#define R_PPC_EMB_SDA21 109 +#define R_PPC_EMB_RELSDA 116 +#define R_PPC_DIAB_SDA21_LO 180 +#define R_PPC_DIAB_SDA21_HI 181 +#define R_PPC_DIAB_SDA21_HA 182 +#define R_PPC_DIAB_RELSDA_LO 183 +#define R_PPC_DIAB_RELSDA_HI 184 +#define R_PPC_DIAB_RELSDA_HA 185 +#define R_PPC_GHS_REL16_HA 251 +#define R_PPC_GHS_REL16_HI 252 +#define R_PPC_GHS_REL16_LO 253 + +// Masks for manipulating Power PC relocation targets +#define PPC_WORD32 0xFFFFFFFF +#define PPC_WORD30 0xFFFFFFFC +#define PPC_LOW24 0x03FFFFFC +#define PPC_LOW14 0x0020FFFC +#define PPC_HALF16 0xFFFF + +#ifdef __cplusplus +} +#endif + +class ElfUtils { + +public: + static bool elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type, uint8_t trampolinId); +}; diff --git a/src/utils/StringTools.cpp b/source/utils/StringTools.cpp similarity index 86% rename from src/utils/StringTools.cpp rename to source/utils/StringTools.cpp index 5c66ed4..7144cfa 100644 --- a/src/utils/StringTools.cpp +++ b/source/utils/StringTools.cpp @@ -30,10 +30,15 @@ #include #include #include -#include "StringTools.h" +#include +#include +#include +#include -bool StringTools::EndsWith(const std::string& a, const std::string& b) { - if (b.size() > a.size()) return false; + +BOOL StringTools::EndsWith(const std::string& a, const std::string& b) { + if (b.size() > a.size()) + return false; return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin()); } @@ -64,27 +69,23 @@ std::string StringTools::removeCharFromString(std::string& input,char toBeRemove const char * StringTools::fmt(const char * format, ...) { static char strChar[512]; strChar[0] = 0; - char * tmp = NULL; va_list va; va_start(va, format); - if((vasprintf(&tmp, format, va) >= 0) && tmp) { - snprintf(strChar, sizeof(strChar), tmp); - free(tmp); + if((vsprintf(strChar, format, va) >= 0)) { va_end(va); return (const char *) strChar; } va_end(va); - if(tmp) - free(tmp); - return NULL; } const wchar_t * StringTools::wfmt(const char * format, ...) { + static char tmp[512]; static wchar_t strWChar[512]; strWChar[0] = 0; + tmp[0] = 0; if(!format) return (const wchar_t *) strWChar; @@ -92,16 +93,12 @@ const wchar_t * StringTools::wfmt(const char * format, ...) { if(strcmp(format, "") == 0) return (const wchar_t *) strWChar; - char * tmp = NULL; - va_list va; va_start(va, format); - if((vasprintf(&tmp, format, va) >= 0) && tmp) { + if((vsprintf(tmp, format, va) >= 0)) { int bt; int32_t strlength = strlen(tmp); bt = mbstowcs(strWChar, tmp, (strlength < 512) ? strlength : 512 ); - free(tmp); - tmp = 0; if(bt > 0) { strWChar[bt] = 0; @@ -110,48 +107,41 @@ const wchar_t * StringTools::wfmt(const char * format, ...) { } va_end(va); - if(tmp) - free(tmp); - return NULL; } int32_t StringTools::strprintf(std::string &str, const char * format, ...) { + static char tmp[512]; + tmp[0] = 0; int32_t result = 0; - char * tmp = NULL; va_list va; va_start(va, format); - if((vasprintf(&tmp, format, va) >= 0) && tmp) { + if((vsprintf(tmp, format, va) >= 0)) { str = tmp; result = str.size(); } va_end(va); - if(tmp) - free(tmp); - return result; } std::string StringTools::strfmt(const char * format, ...) { std::string str; - char * tmp = NULL; + static char tmp[512]; + tmp[0] = 0; va_list va; va_start(va, format); - if((vasprintf(&tmp, format, va) >= 0) && tmp) { + if((vsprintf(tmp, format, va) >= 0)) { str = tmp; } va_end(va); - if(tmp) - free(tmp); - return str; } -bool StringTools::char2wchar_t(const char * strChar, wchar_t * dest) { +BOOL StringTools::char2wchar_t(const char * strChar, wchar_t * dest) { if(!strChar || !dest) return false; diff --git a/source/utils/StringTools.h b/source/utils/StringTools.h new file mode 100644 index 0000000..1f0e336 --- /dev/null +++ b/source/utils/StringTools.h @@ -0,0 +1,80 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any + * damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any + * purpose, including commercial applications, and to alter it and + * redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you use + * this software in a product, an acknowledgment in the product + * documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and + * must not be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#ifndef __STRING_TOOLS_H +#define __STRING_TOOLS_H + +#include +#include +#include + +class StringTools { +public: + static BOOL EndsWith(const std::string& a, const std::string& b); + static const char * byte_to_binary(int32_t x); + static std::string removeCharFromString(std::string& input,char toBeRemoved); + static const char * fmt(const char * format, ...); + static const wchar_t * wfmt(const char * format, ...); + static int32_t strprintf(std::string &str, const char * format, ...); + static std::string strfmt(const char * format, ...); + static BOOL char2wchar_t(const char * src, wchar_t * dest); + static int32_t strtokcmp(const char * string, const char * compare, const char * separator); + static int32_t strextcmp(const char * string, const char * extension, char seperator); + + static const char * FullpathToFilename(const char *path) { + if(!path) + return path; + + const char * ptr = path; + const char * Filename = ptr; + + while(*ptr != '\0') { + if(ptr[0] == '/' && ptr[1] != '\0') + Filename = ptr+1; + + ++ptr; + } + + return Filename; + } + + static void RemoveDoubleSlashs(std::string &str) { + uint32_t length = str.size(); + + //! clear path of double slashes + for(uint32_t i = 1; i < length; ++i) { + if(str[i-1] == '/' && str[i] == '/') { + str.erase(i, 1); + i--; + length--; + } + } + } + + static std::vector stringSplit(const std::string & value, const std::string & splitter); +}; + +#endif /* __STRING_TOOLS_H */ + diff --git a/src/utils/function_patcher.h b/source/utils/function_patcher.h similarity index 97% rename from src/utils/function_patcher.h rename to source/utils/function_patcher.h index b2a1532..6b54246 100644 --- a/src/utils/function_patcher.h +++ b/source/utils/function_patcher.h @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (C) 2016 Maschell + * Copyright (C) 2016-2020 Maschell * With code from chadderz and dimok * * This program is free software: you can redistribute it and/or modify @@ -23,7 +23,7 @@ extern "C" { #endif -#include "dynamic_libs/coreinit.h" +#include /* Macros for libs */ #define LIB_CORE_INIT 0 diff --git a/src/utils/function_patcher_.cpp b/source/utils/function_patcher_.cpp similarity index 78% rename from src/utils/function_patcher_.cpp rename to source/utils/function_patcher_.cpp index 24724a8..cc39756 100644 --- a/src/utils/function_patcher_.cpp +++ b/source/utils/function_patcher_.cpp @@ -21,45 +21,46 @@ #include #include #include +#include +#include +#include +#include "kernel/kernel_utils.h" #include "function_patcher.h" #include "logger.h" -#include "kernel/kernel_defs.h" -#include "kernel/kernel_utils.h" #define LIB_CODE_RW_BASE_OFFSET 0xC1000000 #define CODE_RW_BASE_OFFSET 0x00000000 #define DEBUG_LOG_DYN 0 -uint32_t acp_handle_internal = 0; -uint32_t aoc_handle_internal = 0; -uint32_t sound_handle_internal = 0; -uint32_t sound_handle_internal_old = 0; -uint32_t libcurl_handle_internal = 0; -uint32_t gx2_handle_internal = 0; -uint32_t nfp_handle_internal = 0; -uint32_t nn_act_handle_internal = 0; -uint32_t nn_nim_handle_internal = 0; -uint32_t nn_save_handle_internal = 0; -uint32_t ntag_handle_internal = 0; -uint32_t coreinit_handle_internal = 0; -uint32_t padscore_handle_internal = 0; -uint32_t proc_ui_handle_internal = 0; -uint32_t nsysnet_handle_internal = 0; -uint32_t sysapp_handle_internal = 0; -uint32_t syshid_handle_internal = 0; -uint32_t vpad_handle_internal = 0; -uint32_t vpadbase_handle_internal = 0; +OSDynLoad_Module acp_handle_internal = 0; +OSDynLoad_Module aoc_handle_internal = 0; +OSDynLoad_Module sound_handle_internal = 0; +OSDynLoad_Module sound_handle_internal_old = 0; +OSDynLoad_Module libcurl_handle_internal = 0; +OSDynLoad_Module gx2_handle_internal = 0; +OSDynLoad_Module nfp_handle_internal = 0; +OSDynLoad_Module nn_act_handle_internal = 0; +OSDynLoad_Module nn_nim_handle_internal = 0; +OSDynLoad_Module nn_save_handle_internal = 0; +OSDynLoad_Module ntag_handle_internal = 0; +OSDynLoad_Module coreinit_handle_internal = 0; +OSDynLoad_Module padscore_handle_internal = 0; +OSDynLoad_Module proc_ui_handle_internal = 0; +OSDynLoad_Module nsysnet_handle_internal = 0; +OSDynLoad_Module sysapp_handle_internal = 0; +OSDynLoad_Module syshid_handle_internal = 0; +OSDynLoad_Module vpad_handle_internal = 0; +OSDynLoad_Module vpadbase_handle_internal = 0; /* * Patches a function that is loaded at the start of each application. Its not required to restore, at least when they are really dynamic. * "normal" functions should be patch with the normal patcher. Current Code by Maschell with the help of dimok. Orignal code by Chadderz. */ void PatchInvidualMethodHooks(hooks_magic_t method_hooks[],int32_t hook_information_size, volatile uint32_t dynamic_method_calls[]) { - InitAcquireOS(); resetLibs(); - DEBUG_FUNCTION_LINE("Patching %d given functions\n",hook_information_size); + DEBUG_FUNCTION_LINE("Patching %d given functions",hook_information_size); /* Patch branches to it. */ volatile uint32_t *space = &dynamic_method_calls[0]; @@ -70,13 +71,13 @@ void PatchInvidualMethodHooks(hooks_magic_t method_hooks[],int32_t hook_informat uint32_t instr_len = my_instr_len + skip_instr; uint32_t flush_len = 4*instr_len; for(int32_t i = 0; i < method_hooks_count; i++) { - DEBUG_FUNCTION_LINE("Patching %s ...",method_hooks[i].functionName); + log_printf("Patching %s ...",method_hooks[i].functionName); if(method_hooks[i].functionType == STATIC_FUNCTION && method_hooks[i].alreadyPatched == 1) { if(isDynamicFunction((uint32_t)OSEffectiveToPhysical(method_hooks[i].realAddr))) { - log_printf("The function %s is a dynamic function. Please fix that <3\n", method_hooks[i].functionName); + log_printf("The function %s is a dynamic function. Please fix that <3", method_hooks[i].functionName); method_hooks[i].functionType = DYNAMIC_FUNCTION; } else { - log_printf("Skipping %s, its already patched\n", method_hooks[i].functionName); + log_printf("Skipping %s, its already patched", method_hooks[i].functionName); space += instr_len; continue; } @@ -89,25 +90,25 @@ void PatchInvidualMethodHooks(hooks_magic_t method_hooks[],int32_t hook_informat uint32_t real_addr = GetAddressOfFunction(method_hooks[i].functionName,method_hooks[i].library); if(!real_addr) { - log_printf("\n"); - DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s\n", method_hooks[i].functionName); + log_printf(""); + DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s", method_hooks[i].functionName); space += instr_len; continue; } if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("%s is located at %08X!\n", method_hooks[i].functionName,real_addr); + DEBUG_FUNCTION_LINE("%s is located at %08X!", method_hooks[i].functionName,real_addr); } physical = (uint32_t)OSEffectiveToPhysical(real_addr); if(!physical) { - log_printf("Error. Something is wrong with the physical address\n"); + log_printf("Error. Something is wrong with the physical address"); space += instr_len; continue; } if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("%s physical is located at %08X!\n", method_hooks[i].functionName,physical); + DEBUG_FUNCTION_LINE("%s physical is located at %08X!", method_hooks[i].functionName,physical); } *(volatile uint32_t *)(call_addr) = (uint32_t)(space) - CODE_RW_BASE_OFFSET; @@ -132,13 +133,13 @@ void PatchInvidualMethodHooks(hooks_magic_t method_hooks[],int32_t hook_informat method_hooks[i].realAddr = real_addr; method_hooks[i].restoreInstruction = *(space-1); if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("method_hooks[i].realAddr = %08X!\n", method_hooks[i].realAddr); + DEBUG_FUNCTION_LINE("method_hooks[i].realAddr = %08X!", method_hooks[i].realAddr); } if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("method_hooks[i].restoreInstruction = %08X!\n",method_hooks[i].restoreInstruction) ; + DEBUG_FUNCTION_LINE("method_hooks[i].restoreInstruction = %08X!",method_hooks[i].restoreInstruction) ; } } else { - log_printf("Error. Can't save %s for restoring!\n", method_hooks[i].functionName); + log_printf("Error. Can't save %s for restoring!", method_hooks[i].functionName); } //adding jump to real function thx @ dimok for the assembler code @@ -175,43 +176,42 @@ void PatchInvidualMethodHooks(hooks_magic_t method_hooks[],int32_t hook_informat log_printf("done!\n"); } - DEBUG_FUNCTION_LINE("Done with patching given functions!\n"); + DEBUG_FUNCTION_LINE("Done with patching given functions!"); } /* ****************************************************************** */ /* RESTORE ORIGINAL INSTRUCTIONS */ /* ****************************************************************** */ void RestoreInvidualInstructions(hooks_magic_t method_hooks[],int32_t hook_information_size) { - InitAcquireOS(); resetLibs(); - DEBUG_FUNCTION_LINE("Restoring given functions!\n"); + DEBUG_FUNCTION_LINE("Restoring given functions!"); int32_t method_hooks_count = hook_information_size; for(int32_t i = 0; i < method_hooks_count; i++) { DEBUG_FUNCTION_LINE("Restoring %s... ",method_hooks[i].functionName); if(method_hooks[i].restoreInstruction == 0 || method_hooks[i].realAddr == 0) { - log_printf("I dont have the information for the restore =( skip\n"); + log_printf("I dont have the information for the restore =( skip"); continue; } uint32_t real_addr = GetAddressOfFunction(method_hooks[i].functionName,method_hooks[i].library); if(!real_addr) { - log_printf("OSDynLoad_FindExport failed for %s\n", method_hooks[i].functionName); + log_printf("OSDynLoad_FindExport failed for %s", method_hooks[i].functionName); continue; } uint32_t physical = (uint32_t)OSEffectiveToPhysical(real_addr); if(!physical) { - log_printf("Something is wrong with the physical address\n"); + log_printf("Something is wrong with the physical address"); continue; } if(isDynamicFunction(physical)) { - log_printf("Its a dynamic function. We don't need to restore it!\n",method_hooks[i].functionName); + log_printf("Its a dynamic function. We don't need to restore it!",method_hooks[i].functionName); } else { physical = (uint32_t)OSEffectiveToPhysical(method_hooks[i].realAddr); //When its an static function, we need to use the old location if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("Restoring %08X to %08X\n",(uint32_t)method_hooks[i].restoreInstruction,physical); + DEBUG_FUNCTION_LINE("Restoring %08X to %08X",(uint32_t)method_hooks[i].restoreInstruction,physical); } uint32_t targetAddr = (uint32_t)&method_hooks[i].restoreInstruction; if(targetAddr < 0x00800000 || targetAddr >= 0x01000000) { @@ -222,15 +222,15 @@ void RestoreInvidualInstructions(hooks_magic_t method_hooks[],int32_t hook_infor KernelCopyData(physical,targetAddr, 4); if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("ICInvalidateRange %08X\n",(void*)method_hooks[i].realAddr); + DEBUG_FUNCTION_LINE("ICInvalidateRange %08X",(void*)method_hooks[i].realAddr); } ICInvalidateRange((void*)method_hooks[i].realAddr, 4); - log_printf("done\n"); + log_printf("done"); } method_hooks[i].alreadyPatched = 0; // In case a } - DEBUG_FUNCTION_LINE("Done with restoring given functions!\n"); + DEBUG_FUNCTION_LINE("Done with restoring given functions!"); } int32_t isDynamicFunction(uint32_t physicalAddress) { @@ -261,272 +261,272 @@ uint32_t GetAddressOfFunction(const char * functionName,uint32_t library) { } */ - uint32_t rpl_handle = 0; + OSDynLoad_Module rpl_handle = 0; if(library == LIB_CORE_INIT) { if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_CORE_INIT\n", functionName); + DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_CORE_INIT", functionName); } if(coreinit_handle_internal == 0) { OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle_internal); } if(coreinit_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_CORE_INIT failed to acquire\n"); + DEBUG_FUNCTION_LINE("LIB_CORE_INIT failed to acquire"); return 0; } rpl_handle = coreinit_handle_internal; } else if(library == LIB_NSYSNET) { if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_NSYSNET\n", functionName); + DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_NSYSNET", functionName); } if(nsysnet_handle_internal == 0) { OSDynLoad_Acquire("nsysnet.rpl", &nsysnet_handle_internal); } if(nsysnet_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_NSYSNET failed to acquire\n"); + DEBUG_FUNCTION_LINE("LIB_NSYSNET failed to acquire"); return 0; } rpl_handle = nsysnet_handle_internal; } else if(library == LIB_GX2) { if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_GX2\n", functionName); + DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_GX2", functionName); } if(gx2_handle_internal == 0) { OSDynLoad_Acquire("gx2.rpl", &gx2_handle_internal); } if(gx2_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_GX2 failed to acquire\n"); + DEBUG_FUNCTION_LINE("LIB_GX2 failed to acquire"); return 0; } rpl_handle = gx2_handle_internal; } else if(library == LIB_AOC) { if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_AOC\n", functionName); + DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_AOC", functionName); } if(aoc_handle_internal == 0) { OSDynLoad_Acquire("nn_aoc.rpl", &aoc_handle_internal); } if(aoc_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_AOC failed to acquire\n"); + DEBUG_FUNCTION_LINE("LIB_AOC failed to acquire"); return 0; } rpl_handle = aoc_handle_internal; } else if(library == LIB_AX) { if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_AX\n", functionName); + DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_AX", functionName); } if(sound_handle_internal == 0) { OSDynLoad_Acquire("sndcore2.rpl", &sound_handle_internal); } if(sound_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_AX failed to acquire\n"); + DEBUG_FUNCTION_LINE("LIB_AX failed to acquire"); return 0; } rpl_handle = sound_handle_internal; } else if(library == LIB_AX_OLD) { if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_AX_OLD\n", functionName); + DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_AX_OLD", functionName); } if(sound_handle_internal_old == 0) { OSDynLoad_Acquire("snd_core.rpl", &sound_handle_internal_old); } if(sound_handle_internal_old == 0) { - DEBUG_FUNCTION_LINE("LIB_AX_OLD failed to acquire\n"); + DEBUG_FUNCTION_LINE("LIB_AX_OLD failed to acquire"); return 0; } rpl_handle = sound_handle_internal_old; } else if(library == LIB_FS) { if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_FS\n", functionName); + DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_FS", functionName); } if(coreinit_handle_internal == 0) { OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle_internal); } if(coreinit_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_FS failed to acquire\n"); + DEBUG_FUNCTION_LINE("LIB_FS failed to acquire"); return 0; } rpl_handle = coreinit_handle_internal; } else if(library == LIB_OS) { if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_OS\n", functionName); + DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_OS", functionName); } if(coreinit_handle_internal == 0) { OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle_internal); } if(coreinit_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_OS failed to acquire\n"); + DEBUG_FUNCTION_LINE("LIB_OS failed to acquire"); return 0; } rpl_handle = coreinit_handle_internal; } else if(library == LIB_PADSCORE) { if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_PADSCORE\n", functionName); + DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_PADSCORE", functionName); } if(padscore_handle_internal == 0) { OSDynLoad_Acquire("padscore.rpl", &padscore_handle_internal); } if(padscore_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_PADSCORE failed to acquire\n"); + DEBUG_FUNCTION_LINE("LIB_PADSCORE failed to acquire"); return 0; } rpl_handle = padscore_handle_internal; } else if(library == LIB_SOCKET) { if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_SOCKET\n", functionName); + DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_SOCKET", functionName); } if(nsysnet_handle_internal == 0) { OSDynLoad_Acquire("nsysnet.rpl", &nsysnet_handle_internal); } if(nsysnet_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_SOCKET failed to acquire\n"); + DEBUG_FUNCTION_LINE("LIB_SOCKET failed to acquire"); return 0; } rpl_handle = nsysnet_handle_internal; } else if(library == LIB_SYS) { if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_SYS\n", functionName); + DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_SYS", functionName); } if(sysapp_handle_internal == 0) { OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle_internal); } if(sysapp_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_SYS failed to acquire\n"); + DEBUG_FUNCTION_LINE("LIB_SYS failed to acquire"); return 0; } rpl_handle = sysapp_handle_internal; } else if(library == LIB_VPAD) { if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_VPAD\n", functionName); + DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_VPAD", functionName); } if(vpad_handle_internal == 0) { OSDynLoad_Acquire("vpad.rpl", &vpad_handle_internal); } if(vpad_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_VPAD failed to acquire\n"); + DEBUG_FUNCTION_LINE("LIB_VPAD failed to acquire"); return 0; } rpl_handle = vpad_handle_internal; } else if(library == LIB_NN_ACP) { if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_NN_ACP\n", functionName); + DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_NN_ACP", functionName); } if(acp_handle_internal == 0) { OSDynLoad_Acquire("nn_acp.rpl", &acp_handle_internal); } if(acp_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_NN_ACP failed to acquire\n"); + DEBUG_FUNCTION_LINE("LIB_NN_ACP failed to acquire"); return 0; } rpl_handle = acp_handle_internal; } else if(library == LIB_SYSHID) { if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_SYSHID\n", functionName); + DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_SYSHID", functionName); } if(syshid_handle_internal == 0) { OSDynLoad_Acquire("nsyshid.rpl", &syshid_handle_internal); } if(syshid_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_SYSHID failed to acquire\n"); + DEBUG_FUNCTION_LINE("LIB_SYSHID failed to acquire"); return 0; } rpl_handle = syshid_handle_internal; } else if(library == LIB_VPADBASE) { if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_VPADBASE\n", functionName); + DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_VPADBASE", functionName); } if(vpadbase_handle_internal == 0) { OSDynLoad_Acquire("vpadbase.rpl", &vpadbase_handle_internal); } if(vpadbase_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_VPADBASE failed to acquire\n"); + DEBUG_FUNCTION_LINE("LIB_VPADBASE failed to acquire"); return 0; } rpl_handle = vpadbase_handle_internal; } else if(library == LIB_PROC_UI) { if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_PROC_UI\n", functionName); + DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_PROC_UI", functionName); } if(proc_ui_handle_internal == 0) { OSDynLoad_Acquire("proc_ui.rpl", &proc_ui_handle_internal); } if(proc_ui_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_PROC_UI failed to acquire\n"); + DEBUG_FUNCTION_LINE("LIB_PROC_UI failed to acquire"); return 0; } rpl_handle = proc_ui_handle_internal; } else if(library == LIB_NTAG) { if(DEBUG_LOG_DYN) { - log_printf("FindExport of %s! From LIB_NTAG\n", functionName); + log_printf("FindExport of %s! From LIB_NTAG", functionName); } if(ntag_handle_internal == 0) { OSDynLoad_Acquire("ntag.rpl", &ntag_handle_internal); } if(ntag_handle_internal == 0) { - log_print("LIB_NTAG failed to acquire\n"); + log_print("LIB_NTAG failed to acquire"); return 0; } rpl_handle = ntag_handle_internal; } else if(library == LIB_NFP) { if(DEBUG_LOG_DYN) { - log_printf("FindExport of %s! From LIB_NFP\n", functionName); + log_printf("FindExport of %s! From LIB_NFP", functionName); } if(nfp_handle_internal == 0) { OSDynLoad_Acquire("nn_nfp.rpl", &nfp_handle_internal); } if(nfp_handle_internal == 0) { - log_print("LIB_NFP failed to acquire\n"); + log_print("LIB_NFP failed to acquire"); return 0; } rpl_handle = nfp_handle_internal; } else if(library == LIB_SAVE) { if(DEBUG_LOG_DYN) { - log_printf("FindExport of %s! From LIB_SAVE\n", functionName); + log_printf("FindExport of %s! From LIB_SAVE", functionName); } if(nn_save_handle_internal == 0) { OSDynLoad_Acquire("nn_save.rpl", &nn_save_handle_internal); } if(nn_save_handle_internal == 0) { - log_print("LIB_SAVE failed to acquire\n"); + log_print("LIB_SAVE failed to acquire"); return 0; } rpl_handle = nn_save_handle_internal; } else if(library == LIB_ACT) { if(DEBUG_LOG_DYN) { - log_printf("FindExport of %s! From LIB_ACT\n", functionName); + log_printf("FindExport of %s! From LIB_ACT", functionName); } if(nn_act_handle_internal == 0) { OSDynLoad_Acquire("nn_act.rpl", &nn_act_handle_internal); } if(nn_act_handle_internal == 0) { - log_print("LIB_ACT failed to acquire\n"); + log_print("LIB_ACT failed to acquire"); return 0; } rpl_handle = nn_act_handle_internal; } else if(library == LIB_NIM) { if(DEBUG_LOG_DYN) { - log_printf("FindExport of %s! From LIB_NIM\n", functionName); + log_printf("FindExport of %s! From LIB_NIM", functionName); } if(nn_nim_handle_internal == 0) { OSDynLoad_Acquire("nn_nim.rpl", &nn_nim_handle_internal); } if(nn_nim_handle_internal == 0) { - log_print("LIB_NIM failed to acquire\n"); + log_print("LIB_NIM failed to acquire"); return 0; } rpl_handle = nn_nim_handle_internal; } if(!rpl_handle) { - DEBUG_FUNCTION_LINE("Failed to find the RPL handle for %s\n", functionName); + DEBUG_FUNCTION_LINE("Failed to find the RPL handle for %s", functionName); return 0; } - OSDynLoad_FindExport(rpl_handle, 0, functionName, &real_addr); + OSDynLoad_FindExport(rpl_handle, 0, functionName, (void**) &real_addr); if(!real_addr) { - OSDynLoad_FindExport(rpl_handle, 1, functionName, &real_addr); + OSDynLoad_FindExport(rpl_handle, 1, functionName, (void**) &real_addr); if(!real_addr) { - DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s\n", functionName); + DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s", functionName); return 0; } } diff --git a/src/utils/logger.c b/source/utils/logger.c similarity index 73% rename from src/utils/logger.c rename to source/utils/logger.c index 17d22b3..0922230 100644 --- a/src/utils/logger.c +++ b/source/utils/logger.c @@ -3,23 +3,22 @@ #include #include #include -#include "logger.h" -#include "dynamic_libs/coreinit.h" -#include "dynamic_libs/socket_functions.h" +#include +#include +#include + +#include +#include static int log_socket __attribute__((section(".data")))= -1; static struct sockaddr_in connect_addr __attribute__((section(".data"))); static volatile int log_lock __attribute__((section(".data"))) = 0; -void log_init() { - InitOSFunctionPointers(); - InitSocketFunctionPointers(); - +void log_init_() { int broadcastEnable = 1; log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (log_socket < 0){ + if (log_socket < 0) return; - } setsockopt(log_socket, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable)); @@ -29,14 +28,14 @@ void log_init() { connect_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST); } -void log_print(const char *str) { +void log_print_(const char *str) { // socket is always 0 initially as it is in the BSS if(log_socket < 0) { return; } while(log_lock) - os_usleep(1000); + OSSleepTicks(OSMicrosecondsToTicks(1000)); log_lock = 1; int len = strlen(str); @@ -55,31 +54,29 @@ void log_print(const char *str) { } void OSFatal_printf(const char *format, ...) { - char * tmp = NULL; + char tmp[512]; + tmp[0] = 0; va_list va; va_start(va, format); - if((vasprintf(&tmp, format, va) >= 0) && tmp) { + if((vsprintf(tmp, format, va) >= 0)) { OSFatal(tmp); } va_end(va); } -void log_printf(const char *format, ...) { +void log_printf_(const char *format, ...) { if(log_socket < 0) { return; } - - char * tmp = NULL; + char tmp[512]; + tmp[0] = 0; va_list va; va_start(va, format); - if((vasprintf(&tmp, format, va) >= 0) && tmp) { - log_print(tmp); + if((vsprintf(tmp, format, va) >= 0)) { + log_print_(tmp); } va_end(va); - - if(tmp) - free(tmp); } diff --git a/src/utils/logger.h b/source/utils/logger.h similarity index 63% rename from src/utils/logger.h rename to source/utils/logger.h index 35b579f..72a8be6 100644 --- a/src/utils/logger.h +++ b/source/utils/logger.h @@ -7,10 +7,10 @@ extern "C" { #include -void log_init(); +void log_init_(); //void log_deinit_(void); -void log_print(const char *str); -void log_printf(const char *format, ...); +void log_print_(const char *str); +void log_printf_(const char *format, ...); void OSFatal_printf(const char *format, ...); #define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__) @@ -20,11 +20,17 @@ void OSFatal_printf(const char *format, ...); OSFatal_printf("[%s]%s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ } while (0) -#define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \ - log_printf("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ - } while (0) +#define log_init() log_init_() +//#define log_deinit() log_deinit_() +#define log_print(str) log_print_(str) +#define log_printf(FMT, ARGS...) log_printf_(FMT, ## ARGS); + +#define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \ + log_printf("[%23s]%30s@L%04d: " FMT "\n",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ + } while (0) + #ifdef __cplusplus } #endif diff --git a/src/utils/_utils.c b/source/utils/utils.c similarity index 96% rename from src/utils/_utils.c rename to source/utils/utils.c index ca64f72..9f0a7f5 100644 --- a/src/utils/_utils.c +++ b/source/utils/utils.c @@ -4,8 +4,7 @@ #include #include #include -#include "utils.h" -#include "logger.h" +#include "utils/logger.h" // https://gist.github.com/ccbrown/9722406 void dumpHex(const void* data, size_t size) { diff --git a/source/utils/utils.h b/source/utils/utils.h new file mode 100644 index 0000000..155015b --- /dev/null +++ b/source/utils/utils.h @@ -0,0 +1,40 @@ +#ifndef __UTILS_H_ +#define __UTILS_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define LIMIT(x, min, max) \ + ({ \ + typeof( x ) _x = x; \ + typeof( min ) _min = min; \ + typeof( max ) _max = max; \ + ( ( ( _x ) < ( _min ) ) ? ( _min ) : ( ( _x ) > ( _max ) ) ? ( _max) : ( _x ) ); \ +}) + +#define DegToRad(a) ( (a) * 0.01745329252f ) +#define RadToDeg(a) ( (a) * 57.29577951f ) + +#define ALIGN4(x) (((x) + 3) & ~3) +#define ALIGN32(x) (((x) + 31) & ~31) + +// those work only in powers of 2 +#define ROUNDDOWN(val, align) ((val) & ~(align-1)) +#define ROUNDUP(val, align) ROUNDDOWN(((val) + (align-1)), align) + + +#define le16(i) ((((uint16_t) ((i) & 0xFF)) << 8) | ((uint16_t) (((i) & 0xFF00) >> 8))) +#define le32(i) ((((uint32_t)le16((i) & 0xFFFF)) << 16) | ((uint32_t)le16(((i) & 0xFFFF0000) >> 16))) +#define le64(i) ((((uint64_t)le32((i) & 0xFFFFFFFFLL)) << 32) | ((uint64_t)le32(((i) & 0xFFFFFFFF00000000LL) >> 32))) + +//Needs to have log_init() called beforehand. +void dumpHex(const void* data, size_t size); + +#ifdef __cplusplus +} +#endif + +#endif // __UTILS_H_ diff --git a/src/common/retain_vars.cpp b/src/common/retain_vars.cpp deleted file mode 100644 index 8a8a11c..0000000 --- a/src/common/retain_vars.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "retain_vars.h" -#include "utils/overlay_helper.h" -replacement_data_t gbl_replacement_data __attribute__((section(".data"))); -to_link_and_load_data_t gbl_to_link_and_load_data[MAXIMUM_PLUGINS] __attribute__((section(".data"))); -dyn_linking_relocation_data_t gbl_dyn_linking_data __attribute__((section(".data"))); - -bool gInBackground __attribute__((section(".data"))) = false; -bool g_NotInLoader __attribute__((section(".data"))) = true; -uint64_t gGameTitleID __attribute__((section(".data"))) = 0; -volatile uint8_t gSDInitDone __attribute__((section(".data"))) = 0; - -struct buffer_store drc_store __attribute__((section(".data"))); -struct buffer_store tv_store __attribute__((section(".data"))); - -char gbl_common_data[0x20000] __attribute__((section(".data"))); -char * gbl_common_data_ptr __attribute__((section(".data"))) = gbl_common_data; - -/* -GX2ColorBuffer g_vid_main_cbuf __attribute__((section(".data"))); -GX2Texture g_vid_drcTex __attribute__((section(".data"))); -GX2Sampler g_vid_sampler __attribute__((section(".data"))); -GX2Texture g_vid_tvTex __attribute__((section(".data"))); -GX2ContextState* g_vid_ownContextState __attribute__((section(".data"))); -GX2ContextState* g_vid_originalContextSave __attribute__((section(".data")))= NULL;*/ diff --git a/src/common/retain_vars.h b/src/common/retain_vars.h deleted file mode 100644 index f6e6893..0000000 --- a/src/common/retain_vars.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef RETAINS_VARS_H_ -#define RETAINS_VARS_H_ -#include "patcher/function_patcher.h" -#include "plugin/dynamic_linking_defines.h" -#include "utils/overlay_helper.h" -//#include - -extern replacement_data_t gbl_replacement_data; -extern to_link_and_load_data_t gbl_to_link_and_load_data[MAXIMUM_PLUGINS]; -extern dyn_linking_relocation_data_t gbl_dyn_linking_data; - -extern bool g_NotInLoader; - -extern bool gInBackground; -extern uint64_t gGameTitleID; -extern volatile uint8_t gSDInitDone; - -extern void * ntfs_mounts; -extern int32_t ntfs_mount_count; - -extern struct buffer_store drc_store; -extern struct buffer_store tv_store; - -/* -extern GX2ColorBuffer g_vid_main_cbuf; -extern GX2Texture g_vid_drcTex; -extern GX2Texture g_vid_tvTex; -extern GX2ContextState* g_vid_ownContextState; -extern GX2ContextState* g_vid_originalContextSave; -extern GX2Sampler g_vid_sampler;*/ - -#endif // RETAINS_VARS_H_ diff --git a/src/dynamic_libs/coreinit.c b/src/dynamic_libs/coreinit.c deleted file mode 100644 index 9c98aa2..0000000 --- a/src/dynamic_libs/coreinit.c +++ /dev/null @@ -1,166 +0,0 @@ -#include "coreinit.h" - -uint32_t coreinit_handle __attribute__((section(".data"))) = 0; - -EXPORT_DECL(void, DCInvalidateRange, void *buffer, uint32_t length); -EXPORT_DECL(void, DCFlushRange, const void *addr, uint32_t length); -EXPORT_DECL(void, DCStoreRange, const void *addr, uint32_t length); -EXPORT_DECL(void, ICInvalidateRange, const void *addr, uint32_t length); -EXPORT_DECL(void*, OSEffectiveToPhysical, uint32_t); -EXPORT_DECL(void*, OSSleepTicks, uint64_t); - -EXPORT_DECL(int32_t, OSCreateThread, OSThread *thread, int32_t (*callback)(int32_t, void*), int32_t argc, void *args, uint32_t stack, uint32_t stack_size, int32_t priority, uint32_t attr); -EXPORT_DECL(int32_t, OSResumeThread, OSThread *thread); -EXPORT_DECL(int32_t, OSSuspendThread, OSThread *thread); -EXPORT_DECL(int32_t, OSIsThreadTerminated, OSThread *thread); -EXPORT_DECL(int32_t, OSIsThreadSuspended, OSThread *thread); -EXPORT_DECL(int32_t, OSSetThreadPriority, OSThread * thread, int32_t priority); -EXPORT_DECL(int32_t, OSJoinThread, OSThread * thread, int32_t * ret_val); -EXPORT_DECL(void, OSDetachThread, OSThread * thread); -EXPORT_DECL(OSThread *,OSGetCurrentThread,void); -EXPORT_DECL(const char *,OSGetThreadName,OSThread * thread); -EXPORT_DECL(void,OSGetActiveThreadLink,OSThread * thread, void* link); -EXPORT_DECL(uint32_t,OSGetThreadAffinity,OSThread * thread); -EXPORT_DECL(int32_t,OSGetThreadPriority,OSThread * thread); -EXPORT_DECL(void,OSSetThreadName,OSThread * thread, const char *name); -EXPORT_DECL(int32_t, OSGetCoreId, void); - -EXPORT_DECL(int32_t, OSEnableInterrupts, void); -EXPORT_DECL(void, OSRestoreInterrupts, int32_t); - -EXPORT_DECL(int32_t, MEMCreateExpHeapEx, void *heap, uint32_t size, uint16_t flags); -EXPORT_DECL(void*, MEMAllocFromExpHeapEx, int32_t heap, uint32_t size, int alignment); -EXPORT_DECL(void, MEMFreeToExpHeap, int32_t heap, void * block); - -EXPORT_DECL(OSMessageQueue *, OSGetSystemMessageQueue, void); -EXPORT_DECL(void, OSEnableHomeButtonMenu, int32_t); - -EXPORT_VAR(uint32_t *, pMEMAllocFromDefaultHeapEx); -EXPORT_VAR(uint32_t *, pMEMAllocFromDefaultHeap); -EXPORT_VAR(uint32_t *, pMEMFreeToDefaultHeap); - -EXPORT_DECL(int32_t, OSIsHomeButtonMenuEnabled, void); -EXPORT_DECL(uint64_t, OSGetTitleID, void); - -EXPORT_DECL(void,OSScreenInit,void); -EXPORT_DECL(unsigned int, OSScreenGetBufferSizeEx,unsigned int bufferNum); -EXPORT_DECL(unsigned int, OSScreenSetBufferEx,unsigned int bufferNum, void * addr); -EXPORT_DECL(unsigned int, OSScreenFlipBuffersEx,unsigned int x); -EXPORT_DECL(int32_t, OSScreenEnableEx,uint32_t bufferNum, int32_t enable); -EXPORT_DECL(int32_t, OSScreenPutFontEx,uint32_t bufferNum, uint32_t posX, uint32_t posY, const char * buffer); -EXPORT_DECL(unsigned int, OSScreenClearBufferEx,unsigned int bufferNum, unsigned int temp); - -EXPORT_DECL(void, OSInitMutex, void* mutex); -EXPORT_DECL(void, OSLockMutex, void* mutex); -EXPORT_DECL(void, OSUnlockMutex, void* mutex); -EXPORT_DECL(int32_t, OSTryLockMutex, void* mutex); - -EXPORT_DECL(void, OSInitEvent, OSEvent *event, int32_t value, OSEventMode mode); -EXPORT_DECL(void, OSSignalEvent, OSEvent *event); -EXPORT_DECL(void, OSWaitEvent, OSEvent *event); -EXPORT_DECL(void, OSResetEvent, OSEvent *event); - -EXPORT_DECL(int32_t, OSReceiveMessage, OSMessageQueue *, OSMessage * , int32_t); -EXPORT_DECL(int32_t, OSSendMessage, OSMessageQueue *, OSMessage * , int32_t); - -void _os_find_export(uint32_t handle, const char *funcName, void *funcPointer) { - OSDynLoad_FindExport(handle, 0, funcName, funcPointer); - - if(!*(uint32_t *)funcPointer) { - /* - * This is effectively OSFatal("Function %s is NULL", funcName), - * but we can't rely on any library functions like snprintf or - * strcpy at this point. - * - * Buffer bounds are not checked. Beware! - */ - char buf[256], *bufp = buf; - const char a[] = "Function ", b[] = " is NULL", *p; - unsigned int i; - - for (i = 0; i < sizeof(a) - 1; i++) - *bufp++ = a[i]; - - for (p = funcName; *p; p++) - *bufp++ = *p; - - for (i = 0; i < sizeof(b) - 1; i++) - *bufp++ = b[i]; - - *bufp++ = '\0'; - - OSFatal(buf); - } -} - - -void InitAcquireOS() { - OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); -} -void InitOSFunctionPointers(void) { - - if(coreinit_handle != 0){ - return; - } - - uint32_t funcPointer = 0; - - InitAcquireOS(); - - OS_FIND_EXPORT(coreinit_handle, OSInitMutex); - OS_FIND_EXPORT(coreinit_handle, OSLockMutex); - OS_FIND_EXPORT(coreinit_handle, OSUnlockMutex); - OS_FIND_EXPORT(coreinit_handle, OSTryLockMutex); - - OS_FIND_EXPORT(coreinit_handle, OSScreenInit); - OS_FIND_EXPORT(coreinit_handle, OSScreenGetBufferSizeEx); - OS_FIND_EXPORT(coreinit_handle, OSScreenSetBufferEx); - OS_FIND_EXPORT(coreinit_handle, OSScreenFlipBuffersEx); - OS_FIND_EXPORT(coreinit_handle, OSScreenEnableEx); - OS_FIND_EXPORT(coreinit_handle, OSScreenPutFontEx); - OS_FIND_EXPORT(coreinit_handle, OSScreenClearBufferEx); - OS_FIND_EXPORT(coreinit_handle, OSEnableHomeButtonMenu); - - OS_FIND_EXPORT(coreinit_handle, OSGetSystemMessageQueue); - OS_FIND_EXPORT(coreinit_handle, OSIsHomeButtonMenuEnabled); - OS_FIND_EXPORT(coreinit_handle, DCInvalidateRange); - OS_FIND_EXPORT(coreinit_handle, DCFlushRange); - OS_FIND_EXPORT(coreinit_handle, DCStoreRange); - OS_FIND_EXPORT(coreinit_handle, ICInvalidateRange); - OS_FIND_EXPORT(coreinit_handle, OSEffectiveToPhysical); - OS_FIND_EXPORT(coreinit_handle, OSSleepTicks); - OS_FIND_EXPORT(coreinit_handle, MEMCreateExpHeapEx); - OS_FIND_EXPORT(coreinit_handle, MEMAllocFromExpHeapEx); - OS_FIND_EXPORT(coreinit_handle, MEMFreeToExpHeap); - OS_FIND_EXPORT(coreinit_handle, OSGetTitleID); - - OS_FIND_EXPORT(coreinit_handle, OSCreateThread); - OS_FIND_EXPORT(coreinit_handle, OSResumeThread); - OS_FIND_EXPORT(coreinit_handle, OSSuspendThread); - OS_FIND_EXPORT(coreinit_handle, OSIsThreadTerminated); - OS_FIND_EXPORT(coreinit_handle, OSIsThreadSuspended); - OS_FIND_EXPORT(coreinit_handle, OSJoinThread); - OS_FIND_EXPORT(coreinit_handle, OSSetThreadPriority); - OS_FIND_EXPORT(coreinit_handle, OSDetachThread); - OS_FIND_EXPORT(coreinit_handle, OSGetCurrentThread); - OS_FIND_EXPORT(coreinit_handle, OSGetThreadName); - OS_FIND_EXPORT(coreinit_handle, OSGetActiveThreadLink); - OS_FIND_EXPORT(coreinit_handle, OSGetThreadAffinity); - OS_FIND_EXPORT(coreinit_handle, OSGetThreadPriority); - OS_FIND_EXPORT(coreinit_handle, OSSetThreadName); - OS_FIND_EXPORT(coreinit_handle, OSGetCoreId); - - OS_FIND_EXPORT(coreinit_handle, OSEnableInterrupts); - OS_FIND_EXPORT(coreinit_handle, OSRestoreInterrupts); - - OS_FIND_EXPORT(coreinit_handle, OSInitEvent); - OS_FIND_EXPORT(coreinit_handle, OSSignalEvent); - OS_FIND_EXPORT(coreinit_handle, OSWaitEvent); - OS_FIND_EXPORT(coreinit_handle, OSResetEvent); - OS_FIND_EXPORT(coreinit_handle, OSSendMessage); - OS_FIND_EXPORT(coreinit_handle, OSReceiveMessage); - - OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &pMEMAllocFromDefaultHeapEx); - OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeap", &pMEMAllocFromDefaultHeap); - OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &pMEMFreeToDefaultHeap); -} diff --git a/src/dynamic_libs/coreinit.h b/src/dynamic_libs/coreinit.h deleted file mode 100644 index 99ec473..0000000 --- a/src/dynamic_libs/coreinit.h +++ /dev/null @@ -1,253 +0,0 @@ -#ifndef __COREINIT_H_ -#define __COREINIT_H_ - - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -#define OSTimerClockSpeed ((248625000) / 4) - -#define OSSecondsToTicks(val) ((uint64_t)(val) * (uint64_t)OSTimerClockSpeed) -#define OSMillisecondsToTicks(val) (((uint64_t)(val) * (uint64_t)OSTimerClockSpeed) / 1000ull) -#define OSMicrosecondsToTicks(val) (((uint64_t)(val) * (uint64_t)OSTimerClockSpeed) / 1000000ull) - -#define os_usleep(usecs) OSSleepTicks(OSMicrosecondsToTicks(usecs)) -#define os_sleep(secs) OSSleepTicks(OSSecondsToTicks(secs)) - -#define OSDynLoad_Acquire ((void (*)(const char* rpl, unsigned int *handle))0x0102A3B4) -#define OSDynLoad_FindExport ((void (*)(unsigned int handle, int isdata, const char *symbol, void *address))0x0102B828) -#define OSFatal ((void (*)(char* msg))0x01031618) - -#define EXPORT_DECL(res, func, ...) res (* func)(__VA_ARGS__) __attribute__((section(".data"))) = 0; -#define EXPORT_VAR(type, var) type var __attribute__((section(".data"))); - - -#define EXPORT_FUNC_WRITE(func, val) *(uint32_t*)(((uint32_t)&func) + 0) = (uint32_t)val - -#define OS_FIND_EXPORT(handle, func) _os_find_export(handle, # func, &funcPointer); \ - EXPORT_FUNC_WRITE(func, funcPointer); - -#define OS_FIND_EXPORT_EX(handle, func, func_p) \ - _os_find_export(handle, # func, &funcPointer); \ - EXPORT_FUNC_WRITE(func_p, funcPointer); - -#define OS_MUTEX_SIZE 44 - -extern void _os_find_export(uint32_t handle, const char *funcName, void *funcPointer); - - -typedef struct OSThread_ OSThread; - -typedef struct OSContext_ { - char tag[8]; - - uint32_t gpr[32]; - - uint32_t cr; - uint32_t lr; - uint32_t ctr; - uint32_t xer; - - uint32_t srr0; - uint32_t srr1; - - uint32_t ex0; - uint32_t ex1; - - uint32_t exception_type; - uint32_t reserved; - - double fpscr; - double fpr[32]; - - uint16_t spinLockCount; - uint16_t state; - - uint32_t gqr[8]; - uint32_t pir; - double psf[32]; - - uint64_t coretime[3]; - uint64_t starttime; - - uint32_t error; - uint32_t attributes; - - uint32_t pmc1; - uint32_t pmc2; - uint32_t pmc3; - uint32_t pmc4; - uint32_t mmcr0; - uint32_t mmcr1; -} OSContext; - -typedef int (*ThreadFunc)(int argc, void *argv); - -typedef struct OSThreadLink_ { - OSThread *next; - OSThread *prev; -} OSThreadLink; - -struct OSThread_ { - OSContext context; - - uint32_t txtTag; - uint8_t state; - uint8_t attr; - - short threadId; - int suspend; - int priority; - - char _[0x394 - 0x330 - sizeof(OSThreadLink)]; - OSThreadLink linkActive; - - void *stackBase; - void *stackEnd; - - ThreadFunc entryPoint; - - char _3A0[0x6A0 - 0x3A0]; -}; - -typedef struct OSThreadQueue_ { - OSThread *head; - OSThread *tail; - void *parentStruct; - uint32_t reserved; -} OSThreadQueue; - -typedef struct OSMessage_ { - uint32_t message; - uint32_t data0; - uint32_t data1; - uint32_t data2; -} OSMessage; - -typedef struct OSMessageQueue_ { - uint32_t tag; - char *name; - uint32_t reserved; - - OSThreadQueue sendQueue; - OSThreadQueue recvQueue; - OSMessage *messages; - int msgCount; - int firstIndex; - int usedCount; -} OSMessageQueue; - - -typedef struct OSEvent OSEvent; - -typedef enum OSEventMode -{ - //! A manual event will only reset when OSResetEvent is called. - OS_EVENT_MODE_MANUAL = 0, - - //! An auto event will reset everytime a thread is woken. - OS_EVENT_MODE_AUTO = 1, -} OSEventMode; - -#define OS_EVENT_TAG 0x65566E54u - -struct OSEvent -{ - //! Should always be set to the value OS_EVENT_TAG. - uint32_t tag; - - //! Name set by OSInitEventEx. - const char *name; - - char unknwn[4]; - - //! The current value of the event object. - int32_t value; - - //! The threads currently waiting on this event object with OSWaitEvent. - OSThreadQueue queue; - - //! The mode of the event object, set by OSInitEvent. - OSEventMode mode; -}; - -extern OSMessageQueue * (*OSGetSystemMessageQueue)(void); -extern int32_t (*OSReceiveMessage)(OSMessageQueue *, OSMessage * , int32_t); -extern int32_t (*OSSendMessage)(OSMessageQueue *, OSMessage * , int32_t); -extern void (*DCInvalidateRange)(void *buffer, uint32_t length); -extern void (* DCFlushRange)(const void *addr, uint32_t length); -extern void (* DCStoreRange)(const void *addr, uint32_t length); -extern void (* ICInvalidateRange)(const void *addr, uint32_t length); -extern void* (* OSEffectiveToPhysical)(uint32_t); -extern void* (* OSSleepTicks)(uint64_t ticks); -extern void (* OSEnableHomeButtonMenu)(int32_t); - -extern void (* OSInitEvent)(OSEvent *event, int32_t value, OSEventMode mode); -extern void (* OSSignalEvent)(OSEvent *event); -extern void (* OSWaitEvent)(OSEvent *event); -extern void (* OSResetEvent)(OSEvent *event); - - -extern int32_t (* OSCreateThread)(OSThread *thread, int32_t (*callback)(int32_t, void*), int32_t argc, void *args, uint32_t stack, uint32_t stack_size, int32_t priority, uint32_t attr); -extern int32_t (* OSResumeThread)(OSThread *thread); -extern int32_t (* OSSuspendThread)(OSThread *thread); -extern int32_t (* OSIsThreadTerminated)(OSThread *thread); -extern int32_t (* OSIsThreadSuspended)(OSThread *thread); -extern int32_t (* OSJoinThread)(OSThread * thread, int32_t * ret_val); -extern int32_t (* OSSetThreadPriority)(OSThread * thread, int32_t priority); -extern void (* OSDetachThread)(OSThread * thread); -extern OSThread * (* OSGetCurrentThread)(void); -extern const char * (* OSGetThreadName)(OSThread * thread); - -extern void (* OSGetActiveThreadLink)(OSThread * thread, void* link); -extern uint32_t (* OSGetThreadAffinity)(OSThread * thread); -extern int32_t (* OSGetThreadPriority)(OSThread * thread); -extern void (* OSSetThreadName)(OSThread * thread, const char *name); - -extern int32_t (* OSEnableInterrupts)(void); -extern void (* OSRestoreInterrupts)(int32_t); - -extern int32_t (* OSGetCoreId)(void); -extern uint64_t (* OSGetTitleID)(void); - -extern int32_t (* OSIsHomeButtonMenuEnabled)(void); - -extern int32_t (* MEMCreateExpHeapEx)(void* heap, uint32_t size, uint16_t flags); -extern void* (* MEMAllocFromExpHeapEx)( int32_t heap, uint32_t size, int alignment); -extern void (* MEMFreeToExpHeap)( int32_t heap, void * block); - - -extern void(*OSScreenInit)(); -extern unsigned int(*OSScreenGetBufferSizeEx)(unsigned int bufferNum); -extern unsigned int(*OSScreenSetBufferEx)(unsigned int bufferNum, void * addr); -extern unsigned int(*OSScreenFlipBuffersEx)(unsigned int x); -extern int32_t (*OSScreenEnableEx)(uint32_t bufferNum, int32_t enable); -extern int32_t (*OSScreenPutFontEx)(uint32_t bufferNum, uint32_t posX, uint32_t posY, const char * buffer); -extern unsigned int(*OSScreenClearBufferEx)(unsigned int bufferNum, unsigned int temp); - -extern void (* OSInitMutex)(void* mutex); -extern void (* OSLockMutex)(void* mutex); -extern void (* OSUnlockMutex)(void* mutex); -extern int32_t (* OSTryLockMutex)(void* mutex); - - -extern uint32_t coreinit_handle; - -extern uint32_t *pMEMAllocFromDefaultHeapEx; -extern uint32_t *pMEMAllocFromDefaultHeap; -extern uint32_t *pMEMFreeToDefaultHeap; - - - -void InitAcquireOS(); -void InitOSFunctionPointers(void); - -#ifdef __cplusplus -} -#endif - -#endif // __COREINIT_H_ diff --git a/src/dynamic_libs/fs_defs.h b/src/dynamic_libs/fs_defs.h deleted file mode 100644 index 359433d..0000000 --- a/src/dynamic_libs/fs_defs.h +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef FS_DEFS_H -#define FS_DEFS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "dynamic_libs/coreinit.h" - -/* FS defines and types */ -#define FS_MAX_LOCALPATH_SIZE 511 -#define FS_MAX_MOUNTPATH_SIZE 128 -#define FS_MAX_FULLPATH_SIZE (FS_MAX_LOCALPATH_SIZE + FS_MAX_MOUNTPATH_SIZE) -#define FS_MAX_ARGPATH_SIZE FS_MAX_FULLPATH_SIZE - -#define FS_STATUS_OK 0 -#define FS_STATUS_EOF -2 -#define FS_STATUS_FATAL_ERROR -0x400 -#define FS_RET_UNSUPPORTED_CMD 0x0400 -#define FS_RET_NO_ERROR 0x0000 -#define FS_RET_ALL_ERROR (uint32_t)(-1) - -#define FS_IO_BUFFER_ALIGN 64 - -#define FS_STAT_FLAG_IS_DIRECTORY 0x80000000 - -/* max length of file/dir name */ -#define FS_MAX_ENTNAME_SIZE 256 - -#define FS_SOURCETYPE_EXTERNAL 0 -#define FS_SOURCETYPE_HFIO 1 - -#define FS_MOUNT_SOURCE_SIZE 0x300 -#define FS_CLIENT_SIZE 0x1700 -#define FS_CMD_BLOCK_SIZE 0xA80 - -typedef struct FSClient_ { - uint8_t buffer[FS_CLIENT_SIZE]; -} FSClient; - -typedef struct FSCmdBlock_ { - uint8_t buffer[FS_CMD_BLOCK_SIZE]; -} FSCmdBlock; - -typedef struct { - uint32_t flag; - uint32_t permission; - uint32_t owner_id; - uint32_t group_id; - uint32_t size; - uint32_t alloc_size; - uint64_t quota_size; - uint32_t ent_id; - uint64_t ctime; - uint64_t mtime; - uint8_t attributes[48]; -} __attribute__((packed)) FSStat; - -typedef struct { - FSStat stat; - char name[FS_MAX_ENTNAME_SIZE]; -} FSDirEntry; - -typedef void (*FSAsyncCallback)(FSClient * pClient, FSCmdBlock * pCmd, int32_t result, void *context); -typedef struct { - FSAsyncCallback userCallback; - void *userContext; - OSMessageQueue *ioMsgQueue; -} FSAsyncParams; - -typedef struct { - void* data; // pointer to a FSAsyncResult; - uint32_t unkwn1; - uint32_t unkwn2; - uint32_t unkwn3; // always 0x08 -} __attribute__((packed)) FSMessage; - -typedef struct FSAsyncResult_ { - FSAsyncParams userParams; - FSMessage ioMsg; - - FSClient * client; - FSCmdBlock * block; - uint32_t result; -} FSAsyncResult; - -#ifdef __cplusplus -} -#endif - -#endif /* FS_DEFS_H */ - diff --git a/src/dynamic_libs/fs_functions.c b/src/dynamic_libs/fs_functions.c deleted file mode 100644 index 73288bc..0000000 --- a/src/dynamic_libs/fs_functions.c +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#include "fs_functions.h" -#include "coreinit.h" - -EXPORT_DECL(int32_t, FSInit, void); -EXPORT_DECL(int32_t, FSShutdown, void); -EXPORT_DECL(int32_t, FSAddClient, void *pClient, int32_t errHandling); -EXPORT_DECL(int32_t, FSAddClientEx, void *pClient, int32_t unk_zero_param, int32_t errHandling); -EXPORT_DECL(int32_t, FSDelClient, void *pClient); -EXPORT_DECL(void, FSInitCmdBlock, void *pCmd); -EXPORT_DECL(void *, FSGetCurrentCmdBlock, void *pClient); -EXPORT_DECL(int32_t, FSGetMountSource, void *pClient, void *pCmd, int32_t type, void *source, int32_t errHandling); - -EXPORT_DECL(int32_t, FSMount, void *pClient, void *pCmd, void *source, char *target, uint32_t bytes, int32_t errHandling); -EXPORT_DECL(int32_t, FSUnmount, void *pClient, void *pCmd, const char *target, int32_t errHandling); - -EXPORT_DECL(int32_t, FSGetStat, void *pClient, void *pCmd, const char *path, FSStat *stats, int32_t errHandling); -EXPORT_DECL(int32_t, FSGetStatAsync, void *pClient, void *pCmd, const char *path, void *stats, int32_t error, void *asyncParams); -EXPORT_DECL(int32_t, FSRename, void *pClient, void *pCmd, const char *oldPath, const char *newPath, int32_t error); -EXPORT_DECL(int32_t, FSRenameAsync, void *pClient, void *pCmd, const char *oldPath, const char *newPath, int32_t error, void *asyncParams); -EXPORT_DECL(int32_t, FSRemove, void *pClient, void *pCmd, const char *path, int32_t error); -EXPORT_DECL(int32_t, FSRemoveAsync, void *pClient, void *pCmd, const char *path, int32_t error, void *asyncParams); -EXPORT_DECL(int32_t, FSFlushQuota, void *pClient, void *pCmd, const char* path, int32_t error); -EXPORT_DECL(int32_t, FSFlushQuotaAsync, void *pClient, void *pCmd, const char *path, int32_t error, void *asyncParams); -EXPORT_DECL(int32_t, FSGetFreeSpaceSize, void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, int32_t error); -EXPORT_DECL(int32_t, FSGetFreeSpaceSizeAsync, void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, int32_t error, void *asyncParams); -EXPORT_DECL(int32_t, FSRollbackQuota, void *pClient, void *pCmd, const char *path, int32_t error); -EXPORT_DECL(int32_t, FSRollbackQuotaAsync, void *pClient, void *pCmd, const char *path, int32_t error, void *asyncParams); - -EXPORT_DECL(int32_t, FSOpenDir, void *pClient, void *pCmd, const char *path, int32_t *dh, int32_t errHandling); -EXPORT_DECL(int32_t, FSOpenDirAsync, void *pClient, void* pCmd, const char *path, int32_t *handle, int32_t error, void *asyncParams); -EXPORT_DECL(int32_t, FSReadDir, void *pClient, void *pCmd, int32_t dh, FSDirEntry *dir_entry, int32_t errHandling); -EXPORT_DECL(int32_t, FSRewindDir, void *pClient, void *pCmd, int32_t dh, int32_t errHandling); -EXPORT_DECL(int32_t, FSCloseDir, void *pClient, void *pCmd, int32_t dh, int32_t errHandling); -EXPORT_DECL(int32_t, FSChangeDir, void *pClient, void *pCmd, const char *path, int32_t errHandling); -EXPORT_DECL(int32_t, FSChangeDirAsync, void *pClient, void *pCmd, const char *path, int32_t error, void *asyncParams); -EXPORT_DECL(int32_t, FSMakeDir, void *pClient, void *pCmd, const char *path, int32_t errHandling); -EXPORT_DECL(int32_t, FSMakeDirAsync, void *pClient, void *pCmd, const char *path, int32_t error, void *asyncParams); - -EXPORT_DECL(int32_t, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int32_t *fd, int32_t errHandling); -EXPORT_DECL(int32_t, FSOpenFileAsync, void *pClient, void *pCmd, const char *path, const char *mode, int32_t *handle, int32_t error, const void *asyncParams); -EXPORT_DECL(int32_t, FSReadFile, void *pClient, void *pCmd, void *buffer, int32_t size, int32_t count, int32_t fd, int32_t flag, int32_t errHandling); -EXPORT_DECL(int32_t, FSCloseFile, void *pClient, void *pCmd, int32_t fd, int32_t errHandling); - -EXPORT_DECL(int32_t, FSFlushFile, void *pClient, void *pCmd, int32_t fd, int32_t error); -EXPORT_DECL(int32_t, FSTruncateFile, void *pClient, void *pCmd, int32_t fd, int32_t error); -EXPORT_DECL(int32_t, FSGetStatFile, void *pClient, void *pCmd, int32_t fd, void *buffer, int32_t error); -EXPORT_DECL(int32_t, FSSetPosFile, void *pClient, void *pCmd, int32_t fd, uint32_t pos, int32_t error); -EXPORT_DECL(int32_t, FSWriteFile, void *pClient, void *pCmd, const void *source, int32_t block_size, int32_t block_count, int32_t fd, int32_t flag, int32_t error); - -EXPORT_DECL(int32_t, FSBindMount, void *pClient, void *pCmd, char *source, char *target, int32_t error); -EXPORT_DECL(int32_t, FSBindUnmount, void *pClient, void *pCmd, char *target, int32_t error); - -EXPORT_DECL(int32_t, FSMakeQuota, void *pClient, void *pCmd, const char *path,uint32_t mode, uint64_t size, int32_t errHandling); -EXPORT_DECL(int32_t, FSMakeQuotaAsync ,void *pClient, void *pCmd, const char *path,uint32_t mode, uint64_t size, int32_t errHandling,const void *asyncParams); - -EXPORT_DECL(int32_t, FSGetCwd,void * client,void * block,char * buffer,uint32_t bufferSize,uint32_t flags); - -void InitFSFunctionPointers(void) { - if(coreinit_handle == 0) { - InitAcquireOS(); - }; - uint32_t *funcPointer = 0; - - OS_FIND_EXPORT(coreinit_handle, FSInit); - OS_FIND_EXPORT(coreinit_handle, FSShutdown); - OS_FIND_EXPORT(coreinit_handle, FSAddClient); - OS_FIND_EXPORT(coreinit_handle, FSAddClientEx); - OS_FIND_EXPORT(coreinit_handle, FSDelClient); - OS_FIND_EXPORT(coreinit_handle, FSInitCmdBlock); - OS_FIND_EXPORT(coreinit_handle, FSGetCurrentCmdBlock); - OS_FIND_EXPORT(coreinit_handle, FSGetMountSource); - - OS_FIND_EXPORT(coreinit_handle, FSMount); - OS_FIND_EXPORT(coreinit_handle, FSUnmount); - - OS_FIND_EXPORT(coreinit_handle, FSGetStat); - OS_FIND_EXPORT(coreinit_handle, FSGetStatAsync); - OS_FIND_EXPORT(coreinit_handle, FSRename); - OS_FIND_EXPORT(coreinit_handle, FSRenameAsync); - OS_FIND_EXPORT(coreinit_handle, FSRemove); - OS_FIND_EXPORT(coreinit_handle, FSRemoveAsync); - OS_FIND_EXPORT(coreinit_handle, FSFlushQuota); - OS_FIND_EXPORT(coreinit_handle, FSFlushQuotaAsync); - OS_FIND_EXPORT(coreinit_handle, FSGetFreeSpaceSize); - OS_FIND_EXPORT(coreinit_handle, FSGetFreeSpaceSizeAsync); - OS_FIND_EXPORT(coreinit_handle, FSRollbackQuota); - OS_FIND_EXPORT(coreinit_handle, FSRollbackQuotaAsync); - - OS_FIND_EXPORT(coreinit_handle, FSOpenDir); - OS_FIND_EXPORT(coreinit_handle, FSOpenDirAsync); - OS_FIND_EXPORT(coreinit_handle, FSReadDir); - OS_FIND_EXPORT(coreinit_handle, FSRewindDir); - OS_FIND_EXPORT(coreinit_handle, FSCloseDir); - OS_FIND_EXPORT(coreinit_handle, FSChangeDir); - OS_FIND_EXPORT(coreinit_handle, FSChangeDirAsync); - OS_FIND_EXPORT(coreinit_handle, FSMakeDir); - OS_FIND_EXPORT(coreinit_handle, FSMakeDirAsync); - - - OS_FIND_EXPORT(coreinit_handle, FSOpenFile); - OS_FIND_EXPORT(coreinit_handle, FSOpenFileAsync); - OS_FIND_EXPORT(coreinit_handle, FSReadFile); - OS_FIND_EXPORT(coreinit_handle, FSCloseFile); - - OS_FIND_EXPORT(coreinit_handle, FSFlushFile); - OS_FIND_EXPORT(coreinit_handle, FSTruncateFile); - OS_FIND_EXPORT(coreinit_handle, FSGetStatFile); - OS_FIND_EXPORT(coreinit_handle, FSSetPosFile); - OS_FIND_EXPORT(coreinit_handle, FSWriteFile); - - OS_FIND_EXPORT(coreinit_handle, FSBindMount); - OS_FIND_EXPORT(coreinit_handle, FSBindUnmount); - - OS_FIND_EXPORT(coreinit_handle, FSMakeQuota); - OS_FIND_EXPORT(coreinit_handle, FSMakeQuotaAsync); - - OS_FIND_EXPORT(coreinit_handle, FSGetCwd); -} diff --git a/src/dynamic_libs/fs_functions.h b/src/dynamic_libs/fs_functions.h deleted file mode 100644 index 25f6571..0000000 --- a/src/dynamic_libs/fs_functions.h +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#ifndef __FS_FUNCTIONS_H_ -#define __FS_FUNCTIONS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "fs_defs.h" - -void InitFSFunctionPointers(void); - -extern int32_t (* FSInit)(void); -extern int32_t (* FSShutdown)(void); -extern int32_t (* FSAddClient)(void *pClient, int32_t errHandling); -extern int32_t (* FSAddClientEx)(void *pClient, int32_t unk_zero_param, int32_t errHandling); -extern int32_t (* FSDelClient)(void *pClient); -extern void (* FSInitCmdBlock)(void *pCmd); -extern void *(* FSGetCurrentCmdBlock)(void *pClient); -extern int32_t (* FSGetMountSource)(void *pClient, void *pCmd, int32_t type, void *source, int32_t errHandling); - -extern int32_t (* FSMount)(void *pClient, void *pCmd, void *source, char *target, uint32_t bytes, int32_t errHandling); -extern int32_t (* FSUnmount)(void *pClient, void *pCmd, const char *target, int32_t errHandling); -extern int32_t (* FSRename)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int32_t error); -extern int32_t (* FSRenameAsync)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int32_t error, void *asyncParams); -extern int32_t (* FSRemove)(void *pClient, void *pCmd, const char *path, int32_t error); -extern int32_t (* FSRemoveAsync)(void *pClient, void *pCmd, const char *path, int32_t error, void *asyncParams); - -extern int32_t (* FSGetStat)(void *pClient, void *pCmd, const char *path, FSStat *stats, int32_t errHandling); -extern int32_t (* FSGetStatAsync)(void *pClient, void *pCmd, const char *path, void *stats, int32_t error, void *asyncParams); -extern int32_t (* FSRename)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int32_t error); -extern int32_t (* FSRenameAsync)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int32_t error, void *asyncParams); -extern int32_t (* FSRemove)(void *pClient, void *pCmd, const char *path, int32_t error); -extern int32_t (* FSRemoveAsync)(void *pClient, void *pCmd, const char *path, int32_t error, void *asyncParams); -extern int32_t (* FSFlushQuota)(void *pClient, void *pCmd, const char* path, int32_t error); -extern int32_t (* FSFlushQuotaAsync)(void *pClient, void *pCmd, const char *path, int32_t error, void *asyncParams); -extern int32_t (* FSGetFreeSpaceSize)(void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, int32_t error); -extern int32_t (* FSGetFreeSpaceSizeAsync)(void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, int32_t error, void *asyncParams); -extern int32_t (* FSRollbackQuota)(void *pClient, void *pCmd, const char *path, int32_t error); -extern int32_t (* FSRollbackQuotaAsync)(void *pClient, void *pCmd, const char *path, int32_t error, void *asyncParams); - -extern int32_t (* FSOpenDir)(void *pClient, void *pCmd, const char *path, int32_t *dh, int32_t errHandling); -extern int32_t (* FSOpenDirAsync)(void *pClient, void* pCmd, const char *path, int32_t *handle, int32_t error, void *asyncParams); -extern int32_t (* FSReadDir)(void *pClient, void *pCmd, int32_t dh, FSDirEntry *dir_entry, int32_t errHandling); -extern int32_t (* FSRewindDir)(void *pClient, void *pCmd, int32_t dh, int32_t errHandling); -extern int32_t (* FSCloseDir)(void *pClient, void *pCmd, int32_t dh, int32_t errHandling); -extern int32_t (* FSChangeDir)(void *pClient, void *pCmd, const char *path, int32_t errHandling); -extern int32_t (* FSChangeDirAsync)(void *pClient, void *pCmd, const char *path, int32_t error, void *asyncParams); -extern int32_t (* FSMakeDir)(void *pClient, void *pCmd, const char *path, int32_t errHandling); -extern int32_t (* FSMakeDirAsync)(void *pClient, void *pCmd, const char *path, int32_t error, void *asyncParams); - -extern int32_t (* FSOpenFile)(void *pClient, void *pCmd, const char *path, const char *mode, int32_t *fd, int32_t errHandling); -extern int32_t (* FSOpenFileAsync)(void *pClient, void *pCmd, const char *path, const char *mode, int32_t *handle, int32_t error, const void *asyncParams); -extern int32_t (* FSReadFile)(void *pClient, void *pCmd, void *buffer, int32_t size, int32_t count, int32_t fd, int32_t flag, int32_t errHandling); -extern int32_t (* FSCloseFile)(void *pClient, void *pCmd, int32_t fd, int32_t errHandling); - -extern int32_t (* FSFlushFile)(void *pClient, void *pCmd, int32_t fd, int32_t error); -extern int32_t (* FSTruncateFile)(void *pClient, void *pCmd, int32_t fd, int32_t error); -extern int32_t (* FSGetStatFile)(void *pClient, void *pCmd, int32_t fd, void *buffer, int32_t error); -extern int32_t (* FSSetPosFile)(void *pClient, void *pCmd, int32_t fd, uint32_t pos, int32_t error); -extern int32_t (* FSWriteFile)(void *pClient, void *pCmd, const void *source, int32_t block_size, int32_t block_count, int32_t fd, int32_t flag, int32_t error); - -extern int32_t (* FSBindMount)(void *pClient, void *pCmd, char *source, char *target, int32_t error); -extern int32_t (* FSBindUnmount)(void *pClient, void *pCmd, char *target, int32_t error); - -extern int32_t (* FSMakeQuota)( void *pClient, void *pCmd, const char *path,uint32_t mode, uint64_t size, int32_t errHandling); -extern int32_t (* FSMakeQuotaAsync)(void *pClient, void *pCmd, const char *path,uint32_t mode, uint64_t size, int32_t errHandling,const void *asyncParams); - -extern int32_t (* FSGetCwd)(void * client,void * block,char * buffer,uint32_t bufferSize,uint32_t flags); - - -#ifdef __cplusplus -} -#endif - -#endif // __FS_FUNCTIONS_H_ diff --git a/src/dynamic_libs/gx2_functions.c b/src/dynamic_libs/gx2_functions.c deleted file mode 100644 index a329e09..0000000 --- a/src/dynamic_libs/gx2_functions.c +++ /dev/null @@ -1,187 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#include "coreinit.h" -#include "gx2_types.h" - -uint32_t gx2_handle __attribute__((section(".data"))) = 0; - -EXPORT_DECL(void, GX2Init, uint32_t * init_attribs); -EXPORT_DECL(void, GX2Shutdown, void); -EXPORT_DECL(void, GX2Flush, void); -EXPORT_DECL(int32_t, GX2GetMainCoreId, void) ; -EXPORT_DECL(int32_t, GX2DrawDone, void); -EXPORT_DECL(void, GX2ClearColor, GX2ColorBuffer *colorBuffer, float r, float g, float b, float a); -EXPORT_DECL(void, GX2SetViewport, float x, float y, float w, float h, float nearZ, float farZ); -EXPORT_DECL(void, GX2SetScissor, uint32_t x_orig, uint32_t y_orig, uint32_t wd, uint32_t ht); -EXPORT_DECL(void, GX2SetContextState, const GX2ContextState* state); -EXPORT_DECL(void, GX2DrawEx, int32_t primitive_type, uint32_t count, uint32_t first_vertex, uint32_t instances_count); -EXPORT_DECL(void, GX2DrawIndexedEx, int32_t primitive_type, uint32_t count, int32_t index_format, const void* idx, uint32_t first_vertex, uint32_t instances_count); -EXPORT_DECL(void, GX2ClearDepthStencilEx, GX2DepthBuffer *depthBuffer, float depth_value, uint8_t stencil_value, int32_t clear_mode); -EXPORT_DECL(void, GX2SetClearDepthStencil, GX2DepthBuffer *depthBuffer, float depth_value, uint8_t stencil_value); -EXPORT_DECL(void, GX2CopyColorBufferToScanBuffer, const GX2ColorBuffer *colorBuffer, int32_t scan_target); -EXPORT_DECL(void, GX2SwapScanBuffers, void); -EXPORT_DECL(void, GX2SetTVEnable, int32_t enable); -EXPORT_DECL(void, GX2SetSwapInterval, uint32_t swap_interval); -EXPORT_DECL(uint32_t, GX2GetSwapInterval, void); -EXPORT_DECL(void, GX2WaitForVsync, void); -EXPORT_DECL(void, GX2CalcTVSize, int32_t tv_render_mode, int32_t format, int32_t buffering_mode, uint32_t * size, int32_t * scale_needed); -EXPORT_DECL(void, GX2Invalidate, int32_t invalidate_type, void * ptr, uint32_t buffer_size); -EXPORT_DECL(void, GX2SetTVBuffer, void *buffer, uint32_t buffer_size, int32_t tv_render_mode, int32_t format, int32_t buffering_mode); -EXPORT_DECL(void, GX2CalcSurfaceSizeAndAlignment, GX2Surface *surface); -EXPORT_DECL(void, GX2InitDepthBufferRegs, GX2DepthBuffer *depthBuffer); -EXPORT_DECL(void, GX2InitColorBufferRegs, GX2ColorBuffer *colorBuffer); -EXPORT_DECL(void, GX2CalcColorBufferAuxInfo, GX2ColorBuffer *colorBuffer, uint32_t *size, uint32_t *align); -EXPORT_DECL(void, GX2CalcDepthBufferHiZInfo, GX2DepthBuffer *depthBuffer, uint32_t *size, uint32_t *align); -EXPORT_DECL(void, GX2InitDepthBufferHiZEnable, GX2DepthBuffer *depthBuffer, int32_t hiZ_enable); -EXPORT_DECL(void, GX2SetupContextStateEx, GX2ContextState* state, int32_t enable_profiling); -EXPORT_DECL(void, GX2SetColorBuffer, const GX2ColorBuffer *colorBuffer, int32_t target); -EXPORT_DECL(void, GX2SetDepthBuffer, const GX2DepthBuffer *depthBuffer); -EXPORT_DECL(void, GX2SetAttribBuffer, uint32_t attr_index, uint32_t attr_size, uint32_t stride, const void* attr); -EXPORT_DECL(void, GX2InitTextureRegs, GX2Texture *texture); -EXPORT_DECL(void, GX2InitSampler, GX2Sampler *sampler, int32_t tex_clamp, int32_t min_mag_filter); -EXPORT_DECL(uint32_t, GX2CalcFetchShaderSizeEx, uint32_t num_attrib, int32_t fetch_shader_type, int32_t tessellation_mode); -EXPORT_DECL(void, GX2InitFetchShaderEx, GX2FetchShader* fs, void* fs_buffer, uint32_t count, const GX2AttribStream* attribs, int32_t fetch_shader_type, int32_t tessellation_mode); -EXPORT_DECL(void, GX2SetFetchShader, const GX2FetchShader* fs); -EXPORT_DECL(void, GX2SetVertexUniformReg, uint32_t offset, uint32_t count, const void *values); -EXPORT_DECL(void, GX2SetPixelUniformReg, uint32_t offset, uint32_t count, const void *values); -EXPORT_DECL(void, GX2SetPixelTexture, const GX2Texture *texture, uint32_t texture_hw_location); -EXPORT_DECL(void, GX2SetVertexTexture, const GX2Texture *texture, uint32_t texture_hw_location); -EXPORT_DECL(void, GX2SetPixelSampler, const GX2Sampler *sampler, uint32_t sampler_hw_location); -EXPORT_DECL(void, GX2SetVertexSampler, const GX2Sampler *sampler, uint32_t sampler_hw_location); -EXPORT_DECL(void, GX2SetPixelShader, const GX2PixelShader* pixelShader); -EXPORT_DECL(void, GX2SetVertexShader, const GX2VertexShader* vertexShader); -EXPORT_DECL(void, GX2InitSamplerZMFilter, GX2Sampler *sampler, int32_t z_filter, int32_t mip_filter); -EXPORT_DECL(void, GX2SetColorControl, int32_t lop, uint8_t blend_enable_mask, int32_t enable_multi_write, int32_t enable_color_buffer); -EXPORT_DECL(void, GX2SetDepthOnlyControl, int32_t enable_depth, int32_t enable_depth_write, int32_t depth_comp_function); -EXPORT_DECL(void, GX2SetBlendControl, int32_t target, int32_t color_src_blend, int32_t color_dst_blend, int32_t color_combine, int32_t separate_alpha_blend, int32_t alpha_src_blend, int32_t alpha_dst_blend, int32_t alpha_combine); -EXPORT_DECL(void, GX2CalcDRCSize, int32_t drc_mode, int32_t format, int32_t buffering_mode, uint32_t *size, int32_t *scale_needed); -EXPORT_DECL(void, GX2SetDRCBuffer, void *buffer, uint32_t buffer_size, int32_t drc_mode, int32_t surface_format, int32_t buffering_mode); -EXPORT_DECL(void, GX2SetDRCScale, uint32_t width, uint32_t height); -EXPORT_DECL(void, GX2SetDRCEnable, int32_t enable); -EXPORT_DECL(void, GX2SetPolygonControl, int32_t front_face_mode, int32_t cull_front, int32_t cull_back, int32_t enable_mode, int32_t mode_font, int32_t mode_back, int32_t poly_offset_front, int32_t poly_offset_back, int32_t point_line_offset); -EXPORT_DECL(void, GX2SetCullOnlyControl, int32_t front_face_mode, int32_t cull_front, int32_t cull_back); -EXPORT_DECL(void, GX2SetDepthStencilControl, int32_t enable_depth_test, int32_t enable_depth_write, int32_t depth_comp_function, int32_t stencil_test_enable, int32_t back_stencil_enable, - int32_t font_stencil_func, int32_t front_stencil_z_pass, int32_t front_stencil_z_fail, int32_t front_stencil_fail, - int32_t back_stencil_func, int32_t back_stencil_z_pass, int32_t back_stencil_z_fail, int32_t back_stencil_fail); -EXPORT_DECL(void, GX2SetStencilMask, uint8_t mask_front, uint8_t write_mask_front, uint8_t ref_front, uint8_t mask_back, uint8_t write_mask_back, uint8_t ref_back); -EXPORT_DECL(void, GX2SetLineWidth, float width); -EXPORT_DECL(void, GX2SetTVGamma, float val); -EXPORT_DECL(void, GX2SetDRCGamma, float gam); -EXPORT_DECL(int32_t, GX2GetSystemTVScanMode, void); -EXPORT_DECL(int32_t, GX2GetSystemDRCScanMode, void); -EXPORT_DECL(void, GX2RSetAllocator, void * (* allocFunc)(uint32_t, uint32_t, uint32_t), void (* freeFunc)(uint32_t, void*)); -EXPORT_DECL(void, GX2CopySurface, GX2Surface * srcSurface,uint32_t srcMip,uint32_t srcSlice,GX2Surface * dstSurface,uint32_t dstMip,uint32_t dstSlice ); - -EXPORT_DECL(int32_t, GX2GetLastFrame, int32_t target, GX2Texture * texture); -EXPORT_DECL(void, GX2BeginDisplayListEx,void * displayList,uint32_t size,int32_t unkwn); -EXPORT_DECL(uint32_t, GX2EndDisplayList, void * list); -EXPORT_DECL(void, GX2CallDisplayList, void * list, uint32_t size); -EXPORT_DECL(void, GX2ExpandAAColorBuffer,GX2ColorBuffer * buffer); -EXPORT_DECL(void, GX2ResolveAAColorBuffer, const GX2ColorBuffer * srcBuffer, GX2Surface * dstSurface,uint32_t dstMip,uint32_t dstSlice); - -EXPORT_DECL(void, GX2ClearBuffersEx, GX2ColorBuffer * colorBuffer,GX2DepthBuffer * depthBuffer,float r, float g, float b, float a,float depthValue,uint8_t stencilValue,int32_t clearFlags); - -void InitAcquireGX2(void) { - if(coreinit_handle == 0) { - InitAcquireOS(); - }; - OSDynLoad_Acquire("gx2.rpl", &gx2_handle); -} - -void InitGX2FunctionPointers(void) { - uint32_t *funcPointer = 0; - InitAcquireGX2(); - - OS_FIND_EXPORT(gx2_handle, GX2Init); - OS_FIND_EXPORT(gx2_handle, GX2Shutdown); - OS_FIND_EXPORT(gx2_handle, GX2Flush); - OS_FIND_EXPORT(gx2_handle, GX2GetMainCoreId); - OS_FIND_EXPORT(gx2_handle, GX2DrawDone); - OS_FIND_EXPORT(gx2_handle, GX2ClearColor); - OS_FIND_EXPORT(gx2_handle, GX2SetViewport); - OS_FIND_EXPORT(gx2_handle, GX2SetScissor); - OS_FIND_EXPORT(gx2_handle, GX2SetContextState); - OS_FIND_EXPORT(gx2_handle, GX2DrawEx); - OS_FIND_EXPORT(gx2_handle, GX2DrawIndexedEx); - OS_FIND_EXPORT(gx2_handle, GX2ClearDepthStencilEx); - OS_FIND_EXPORT(gx2_handle, GX2CopyColorBufferToScanBuffer); - OS_FIND_EXPORT(gx2_handle, GX2SwapScanBuffers); - OS_FIND_EXPORT(gx2_handle, GX2SetTVEnable); - OS_FIND_EXPORT(gx2_handle, GX2SetSwapInterval); - OS_FIND_EXPORT(gx2_handle, GX2GetSwapInterval); - OS_FIND_EXPORT(gx2_handle, GX2WaitForVsync); - OS_FIND_EXPORT(gx2_handle, GX2CalcTVSize); - OS_FIND_EXPORT(gx2_handle, GX2Invalidate); - OS_FIND_EXPORT(gx2_handle, GX2SetTVBuffer); - OS_FIND_EXPORT(gx2_handle, GX2CalcSurfaceSizeAndAlignment); - OS_FIND_EXPORT(gx2_handle, GX2InitDepthBufferRegs); - OS_FIND_EXPORT(gx2_handle, GX2InitColorBufferRegs); - OS_FIND_EXPORT(gx2_handle, GX2CalcColorBufferAuxInfo); - OS_FIND_EXPORT(gx2_handle, GX2CalcDepthBufferHiZInfo); - OS_FIND_EXPORT(gx2_handle, GX2InitDepthBufferHiZEnable); - OS_FIND_EXPORT(gx2_handle, GX2SetupContextStateEx); - OS_FIND_EXPORT(gx2_handle, GX2SetColorBuffer); - OS_FIND_EXPORT(gx2_handle, GX2SetDepthBuffer); - OS_FIND_EXPORT(gx2_handle, GX2SetAttribBuffer); - OS_FIND_EXPORT(gx2_handle, GX2InitTextureRegs); - OS_FIND_EXPORT(gx2_handle, GX2InitSampler); - OS_FIND_EXPORT(gx2_handle, GX2CalcFetchShaderSizeEx); - OS_FIND_EXPORT(gx2_handle, GX2InitFetchShaderEx); - OS_FIND_EXPORT(gx2_handle, GX2SetFetchShader); - OS_FIND_EXPORT(gx2_handle, GX2SetVertexUniformReg); - OS_FIND_EXPORT(gx2_handle, GX2SetPixelUniformReg); - OS_FIND_EXPORT(gx2_handle, GX2SetPixelTexture); - OS_FIND_EXPORT(gx2_handle, GX2SetVertexTexture); - OS_FIND_EXPORT(gx2_handle, GX2SetPixelSampler); - OS_FIND_EXPORT(gx2_handle, GX2SetVertexSampler); - OS_FIND_EXPORT(gx2_handle, GX2SetPixelShader); - OS_FIND_EXPORT(gx2_handle, GX2SetVertexShader); - OS_FIND_EXPORT(gx2_handle, GX2InitSamplerZMFilter); - OS_FIND_EXPORT(gx2_handle, GX2SetColorControl); - OS_FIND_EXPORT(gx2_handle, GX2SetDepthOnlyControl); - OS_FIND_EXPORT(gx2_handle, GX2SetBlendControl); - OS_FIND_EXPORT(gx2_handle, GX2CalcDRCSize); - OS_FIND_EXPORT(gx2_handle, GX2SetDRCBuffer); - OS_FIND_EXPORT(gx2_handle, GX2SetDRCScale); - OS_FIND_EXPORT(gx2_handle, GX2SetDRCEnable); - OS_FIND_EXPORT(gx2_handle, GX2SetPolygonControl); - OS_FIND_EXPORT(gx2_handle, GX2SetCullOnlyControl); - OS_FIND_EXPORT(gx2_handle, GX2SetDepthStencilControl); - OS_FIND_EXPORT(gx2_handle, GX2SetStencilMask); - OS_FIND_EXPORT(gx2_handle, GX2SetLineWidth); - OS_FIND_EXPORT(gx2_handle, GX2SetDRCGamma); - OS_FIND_EXPORT(gx2_handle, GX2SetTVGamma); - OS_FIND_EXPORT(gx2_handle, GX2GetSystemTVScanMode); - OS_FIND_EXPORT(gx2_handle, GX2GetSystemDRCScanMode); - OS_FIND_EXPORT(gx2_handle, GX2RSetAllocator); - OS_FIND_EXPORT(gx2_handle, GX2CopySurface); - OS_FIND_EXPORT(gx2_handle, GX2GetLastFrame); - OS_FIND_EXPORT(gx2_handle, GX2ClearBuffersEx); - OS_FIND_EXPORT(gx2_handle, GX2BeginDisplayListEx); - OS_FIND_EXPORT(gx2_handle, GX2EndDisplayList); - OS_FIND_EXPORT(gx2_handle, GX2CallDisplayList); - OS_FIND_EXPORT(gx2_handle, GX2ExpandAAColorBuffer); - OS_FIND_EXPORT(gx2_handle, GX2ResolveAAColorBuffer); - OS_FIND_EXPORT(gx2_handle, GX2SetClearDepthStencil); -} diff --git a/src/dynamic_libs/gx2_functions.h b/src/dynamic_libs/gx2_functions.h deleted file mode 100644 index 4cd0e1c..0000000 --- a/src/dynamic_libs/gx2_functions.h +++ /dev/null @@ -1,213 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#ifndef __GX2_FUNCTIONS_H_ -#define __GX2_FUNCTIONS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "gx2_types.h" - -extern uint32_t gx2_handle; - -void InitGX2FunctionPointers(void); -void InitAcquireGX2(void); - -extern void (* GX2Init)(uint32_t * init_attribs); -extern void (* GX2Shutdown)(void); -extern void (* GX2Flush)(void); -extern int32_t (* GX2GetMainCoreId)(void) ; -extern int32_t (* GX2DrawDone)(void); -extern void (* GX2ClearColor)(GX2ColorBuffer *colorBuffer, float r, float g, float b, float a); -extern void (* GX2SetViewport)(float x, float y, float w, float h, float nearZ, float farZ); -extern void (* GX2SetScissor)(uint32_t x_orig, uint32_t y_orig, uint32_t wd, uint32_t ht); -extern void (* GX2SetContextState)(const GX2ContextState* state); -extern void (* GX2DrawEx)(int32_t primitive_type, uint32_t count, uint32_t first_vertex, uint32_t instances_count); -extern void (* GX2DrawIndexedEx)(int32_t primitive_type, uint32_t count, int32_t index_format, const void* idx, uint32_t first_vertex, uint32_t instances_count); -extern void (* GX2ClearDepthStencilEx)(GX2DepthBuffer *depthBuffer, float depth_value, uint8_t stencil_value, int32_t clear_mode); -extern void (* GX2SetClearDepthStencil)(GX2DepthBuffer *depthBuffer, float depth_value, uint8_t stencil_value); -extern void (* GX2CopyColorBufferToScanBuffer)(const GX2ColorBuffer *colorBuffer, int32_t scan_target); -extern void (* GX2SwapScanBuffers)(void); -extern void (* GX2SetTVEnable)(int32_t enable); -extern void (* GX2SetSwapInterval)(uint32_t swap_interval); -extern uint32_t (* GX2GetSwapInterval)(void); -extern void (* GX2WaitForVsync)(void); -extern void (* GX2CalcTVSize)(int32_t tv_render_mode, int32_t format, int32_t buffering_mode, uint32_t * size, int32_t * scale_needed); -extern void (* GX2Invalidate)(int32_t invalidate_type, void * ptr, uint32_t buffer_size); -extern void (* GX2SetTVBuffer)(void *buffer, uint32_t buffer_size, int32_t tv_render_mode, int32_t format, int32_t buffering_mode); -extern void (* GX2CalcSurfaceSizeAndAlignment)(GX2Surface *surface); -extern void (* GX2InitDepthBufferRegs)(GX2DepthBuffer *depthBuffer); -extern void (* GX2InitColorBufferRegs)(GX2ColorBuffer *colorBuffer); -extern void (* GX2CalcColorBufferAuxInfo)(GX2ColorBuffer *colorBuffer, uint32_t *size, uint32_t *align); -extern void (* GX2CalcDepthBufferHiZInfo)(GX2DepthBuffer *depthBuffer, uint32_t *size, uint32_t *align); -extern void (* GX2InitDepthBufferHiZEnable)(GX2DepthBuffer *depthBuffer, int32_t hiZ_enable); -extern void (* GX2SetupContextStateEx)(GX2ContextState* state, int32_t enable_profiling); -extern void (* GX2SetColorBuffer)(const GX2ColorBuffer *colorBuffer, int32_t target); -extern void (* GX2SetDepthBuffer)(const GX2DepthBuffer *depthBuffer); -extern void (* GX2SetAttribBuffer)(uint32_t attr_index, uint32_t attr_size, uint32_t stride, const void* attr); -extern void (* GX2InitTextureRegs)(GX2Texture *texture); -extern void (* GX2InitSampler)(GX2Sampler *sampler, int32_t tex_clamp, int32_t min_mag_filter); -extern uint32_t (* GX2CalcFetchShaderSizeEx)(uint32_t num_attrib, int32_t fetch_shader_type, int32_t tessellation_mode); -extern void (* GX2InitFetchShaderEx)(GX2FetchShader* fs, void* fs_buffer, uint32_t count, const GX2AttribStream* attribs, int32_t fetch_shader_type, int32_t tessellation_mode); -extern void (* GX2SetFetchShader)(const GX2FetchShader* fs); -extern void (* GX2SetVertexUniformReg)(uint32_t offset, uint32_t count, const void *values); -extern void (* GX2SetPixelUniformReg)(uint32_t offset, uint32_t count, const void *values); -extern void (* GX2SetPixelTexture)(const GX2Texture *texture, uint32_t texture_hw_location); -extern void (* GX2SetVertexTexture)(const GX2Texture *texture, uint32_t texture_hw_location); -extern void (* GX2SetPixelSampler)(const GX2Sampler *sampler, uint32_t sampler_hw_location); -extern void (* GX2SetVertexSampler)(const GX2Sampler *sampler, uint32_t sampler_hw_location); -extern void (* GX2SetPixelShader)(const GX2PixelShader* pixelShader); -extern void (* GX2SetVertexShader)(const GX2VertexShader* vertexShader); -extern void (* GX2InitSamplerZMFilter)(GX2Sampler *sampler, int32_t z_filter, int32_t mip_filter); -extern void (* GX2SetColorControl)(int32_t lop, uint8_t blend_enable_mask, int32_t enable_multi_write, int32_t enable_color_buffer); -extern void (* GX2SetDepthOnlyControl)(int32_t enable_depth, int32_t enable_depth_write, int32_t depth_comp_function); -extern void (* GX2SetBlendControl)(int32_t target, int32_t color_src_blend, int32_t color_dst_blend, int32_t color_combine, int32_t separate_alpha_blend, int32_t alpha_src_blend, int32_t alpha_dst_blend, int32_t alpha_combine); -extern void (* GX2CalcDRCSize)(int32_t drc_mode, int32_t format, int32_t buffering_mode, uint32_t *size, int32_t *scale_needed); -extern void (* GX2SetDRCBuffer)(void *buffer, uint32_t buffer_size, int32_t drc_mode, int32_t surface_format, int32_t buffering_mode); -extern void (* GX2SetDRCScale)(uint32_t width, uint32_t height); -extern void (* GX2SetDRCEnable)(int32_t enable); -extern void (* GX2SetPolygonControl)(int32_t front_face_mode, int32_t cull_front, int32_t cull_back, int32_t enable_mode, int32_t mode_font, int32_t mode_back, int32_t poly_offset_front, int32_t poly_offset_back, int32_t point_line_offset); -extern void (* GX2SetCullOnlyControl)(int32_t front_face_mode, int32_t cull_front, int32_t cull_back); -extern void (* GX2SetDepthStencilControl)(int32_t enable_depth_test, int32_t enable_depth_write, int32_t depth_comp_function, int32_t stencil_test_enable, int32_t back_stencil_enable, - int32_t font_stencil_func, int32_t front_stencil_z_pass, int32_t front_stencil_z_fail, int32_t front_stencil_fail, - int32_t back_stencil_func, int32_t back_stencil_z_pass, int32_t back_stencil_z_fail, int32_t back_stencil_fail); -extern void (* GX2SetStencilMask)(uint8_t mask_front, uint8_t write_mask_front, uint8_t ref_front, uint8_t mask_back, uint8_t write_mask_back, uint8_t ref_back); -extern void (* GX2SetLineWidth)(float width); -extern void (* GX2SetTVGamma)(float val); -extern void (* GX2SetDRCGamma)(float val); -extern int32_t (* GX2GetSystemTVScanMode)(void); -extern int32_t (* GX2GetSystemDRCScanMode)(void); -extern void (* GX2RSetAllocator)(void * (*allocFunc)(uint32_t, uint32_t, uint32_t), void (*freeFunc)(uint32_t, void*)); -extern void (* GX2CopySurface)(GX2Surface * srcSurface,uint32_t srcMip,uint32_t srcSlice,GX2Surface * dstSurface,uint32_t dstMip,uint32_t dstSlice ); -extern void (* GX2ClearBuffersEx)(GX2ColorBuffer * colorBuffer,GX2DepthBuffer * depthBuffer,float r, float g, float b, float a,float depthValue,uint8_t stencilValue,int32_t clearFlags); -extern int32_t (* GX2GetLastFrame)(int32_t target, GX2Texture * texture); -extern void (* GX2BeginDisplayListEx)(void * displayList,uint32_t size,int32_t unkwn); -extern uint32_t (*GX2EndDisplayList)(void * list); -extern void (*GX2CallDisplayList)(void * list, uint32_t size); -extern void (*GX2ExpandAAColorBuffer)(GX2ColorBuffer * buffer); -extern void (*GX2ResolveAAColorBuffer)(const GX2ColorBuffer * srcBuffer, GX2Surface * dstSurface,uint32_t dstMip,uint32_t dstSlice); - -static inline void GX2InitDepthBuffer(GX2DepthBuffer *depthBuffer, int32_t dimension, uint32_t width, uint32_t height, uint32_t depth, int32_t format, int32_t aa) { - depthBuffer->surface.dimension = dimension; - depthBuffer->surface.width = width; - depthBuffer->surface.height = height; - depthBuffer->surface.depth = depth; - depthBuffer->surface.num_mips = 1; - depthBuffer->surface.format = format; - depthBuffer->surface.aa = aa; - depthBuffer->surface.use = ((format==GX2_SURFACE_FORMAT_D_D24_S8_UNORM) || (format==GX2_SURFACE_FORMAT_D_D24_S8_FLOAT)) ? GX2_SURFACE_USE_DEPTH_BUFFER : GX2_SURFACE_USE_DEPTH_BUFFER_TEXTURE; - depthBuffer->surface.tile = GX2_TILE_MODE_DEFAULT; - depthBuffer->surface.swizzle = 0; - depthBuffer->view_mip = 0; - depthBuffer->view_first_slice = 0; - depthBuffer->view_slices_count = depth; - depthBuffer->clear_depth = 1.0f; - depthBuffer->clear_stencil = 0; - depthBuffer->hiZ_data = NULL; - depthBuffer->hiZ_size = 0; - GX2CalcSurfaceSizeAndAlignment(&depthBuffer->surface); - GX2InitDepthBufferRegs(depthBuffer); -} - -static inline void GX2InitColorBuffer(GX2ColorBuffer *colorBuffer, int32_t dimension, uint32_t width, uint32_t height, uint32_t depth, int32_t format, int32_t aa) { - colorBuffer->surface.dimension = dimension; - colorBuffer->surface.width = width; - colorBuffer->surface.height = height; - colorBuffer->surface.depth = depth; - colorBuffer->surface.num_mips = 1; - colorBuffer->surface.format = format; - colorBuffer->surface.aa = aa; - colorBuffer->surface.use = GX2_SURFACE_USE_COLOR_BUFFER_TEXTURE_FTV; - colorBuffer->surface.image_size = 0; - colorBuffer->surface.image_data = NULL; - colorBuffer->surface.mip_size = 0; - colorBuffer->surface.mip_data = NULL; - colorBuffer->surface.tile = GX2_TILE_MODE_DEFAULT; - colorBuffer->surface.swizzle = 0; - colorBuffer->surface.align = 0; - colorBuffer->surface.pitch = 0; - uint32_t i; - for(i = 0; i < 13; i++) - colorBuffer->surface.mip_offset[i] = 0; - colorBuffer->view_mip = 0; - colorBuffer->view_first_slice = 0; - colorBuffer->view_slices_count = depth; - colorBuffer->aux_data = NULL; - colorBuffer->aux_size = 0; - for(i = 0; i < 5; i++) - colorBuffer->regs[i] = 0; - - GX2CalcSurfaceSizeAndAlignment(&colorBuffer->surface); - GX2InitColorBufferRegs(colorBuffer); -} - -static inline void GX2InitAttribStream(GX2AttribStream* attr, uint32_t location, uint32_t buffer, uint32_t offset, int32_t format) { - attr->location = location; - attr->buffer = buffer; - attr->offset = offset; - attr->format = format; - attr->index_type = 0; - attr->divisor = 0; - attr->destination_selector = attribute_dest_comp_selector[format & 0xff]; - attr->endian_swap = GX2_ENDIANSWAP_DEFAULT; -} - -static inline void GX2InitTexture(GX2Texture *tex, uint32_t width, uint32_t height, uint32_t depth, uint32_t num_mips, int32_t format, int32_t dimension, int32_t tile) { - tex->surface.dimension = dimension; - tex->surface.width = width; - tex->surface.height = height; - tex->surface.depth = depth; - tex->surface.num_mips = num_mips; - tex->surface.format = format; - tex->surface.aa = GX2_AA_MODE_1X; - tex->surface.use = GX2_SURFACE_USE_TEXTURE; - tex->surface.image_size = 0; - tex->surface.image_data = NULL; - tex->surface.mip_size = 0; - tex->surface.mip_data = NULL; - tex->surface.tile = tile; - tex->surface.swizzle = 0; - tex->surface.align = 0; - tex->surface.pitch = 0; - uint32_t i; - for(i = 0; i < 13; i++) - tex->surface.mip_offset[i] = 0; - tex->view_first_mip = 0; - tex->view_mips_count = num_mips; - tex->view_first_slice = 0; - tex->view_slices_count = depth; - tex->component_selector = texture_comp_selector[format & 0x3f]; - for(i = 0; i < 5; i++) - tex->regs[i] = 0; - - GX2CalcSurfaceSizeAndAlignment(&tex->surface); - GX2InitTextureRegs(tex); -} - -#ifdef __cplusplus -} -#endif - -#endif // __GX2_FUNCTIONS_H_ diff --git a/src/dynamic_libs/gx2_types.h b/src/dynamic_libs/gx2_types.h deleted file mode 100644 index 566a9e9..0000000 --- a/src/dynamic_libs/gx2_types.h +++ /dev/null @@ -1,696 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#ifndef _GX2_TYPES_H_ -#define _GX2_TYPES_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -//!----------------------------------------------------------------------------------------------------------------------- -//! Constants -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_COMMAND_BUFFER_SIZE 0x400000 -#define GX2_SCAN_BUFFER_ALIGNMENT 0x1000 -#define GX2_SHADER_ALIGNMENT 0x100 -#define GX2_CONTEXT_STATE_ALIGNMENT 0x100 -#define GX2_DISPLAY_LIST_ALIGNMENT 0x20 -#define GX2_VERTEX_BUFFER_ALIGNMENT 0x40 -#define GX2_INDEX_BUFFER_ALIGNMENT 0x20 - -#define GX2_CONTEXT_STATE_SIZE 0xA100 - -#define GX2_AUX_BUFFER_CLEAR_VALUE 0xCC - -//!----------------------------------------------------------------------------------------------------------------------- -//! Common -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_FALSE 0 -#define GX2_TRUE 1 -#define GX2_DISABLE 0 -#define GX2_ENABLE 1 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2InitAttrib -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_INIT_ATTRIB_NULL 0 -#define GX2_INIT_ATTRIB_CB_BASE 1 -#define GX2_INIT_ATTRIB_CB_SIZE 2 -#define GX2_INIT_ATTRIB_ARGC 7 -#define GX2_INIT_ATTRIB_ARGV 8 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 compare functions -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_COMPARE_NEVER 0 -#define GX2_COMPARE_LESS 1 -#define GX2_COMPARE_EQUAL 2 -#define GX2_COMPARE_LEQUAL 3 -#define GX2_COMPARE_GREATER 4 -#define GX2_COMPARE_NOTEQUAL 5 -#define GX2_COMPARE_GEQUAL 6 -#define GX2_COMPARE_ALWAYS 7 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 stencil functions -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_STENCIL_KEEP 0 -#define GX2_STENCIL_ZERO 1 -#define GX2_STENCIL_REPLACE 2 -#define GX2_STENCIL_INCR 3 -#define GX2_STENCIL_DECR 4 -#define GX2_STENCIL_INVERT 5 -#define GX2_STENCIL_INCR_WRAP 6 -#define GX2_STENCIL_DECR_WRAP 7 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 logic op functions -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_LOGIC_OP_CLEAR 0x00 -#define GX2_LOGIC_OP_NOR 0x11 -#define GX2_LOGIC_OP_INVAND 0x22 -#define GX2_LOGIC_OP_INVCOPY 0x33 -#define GX2_LOGIC_OP_REVAND 0x44 -#define GX2_LOGIC_OP_INV 0x55 -#define GX2_LOGIC_OP_XOR 0x66 -#define GX2_LOGIC_OP_NAND 0x77 -#define GX2_LOGIC_OP_AND 0x88 -#define GX2_LOGIC_OP_EQUIV 0x99 -#define GX2_LOGIC_OP_NOOP 0xAA -#define GX2_LOGIC_OP_INVOR 0xBB -#define GX2_LOGIC_OP_COPY 0xCC -#define GX2_LOGIC_OP_REVOR 0xDD -#define GX2_LOGIC_OP_OR 0xEE -#define GX2_LOGIC_OP_SET 0xFF - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 blend combination functions -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_BLEND_COMBINE_ADD 0x00 -#define GX2_BLEND_COMBINE_SRC_MINUS_DST 0x01 -#define GX2_BLEND_COMBINE_MIN 0x02 -#define GX2_BLEND_COMBINE_MAX 0x03 -#define GX2_BLEND_COMBINE_DST_MINUS_SRC 0x04 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 blend functions -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_BLEND_ZERO 0x00 -#define GX2_BLEND_ONE 0x01 -#define GX2_BLEND_SRC_ALPHA 0x04 -#define GX2_BLEND_ONE_MINUS_SRC_ALPHA 0x05 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 render targets -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_RENDER_TARGET_0 0 -#define GX2_RENDER_TARGET_1 1 -#define GX2_RENDER_TARGET_2 2 -#define GX2_RENDER_TARGET_3 3 -#define GX2_RENDER_TARGET_4 4 -#define GX2_RENDER_TARGET_5 5 -#define GX2_RENDER_TARGET_6 6 -#define GX2_RENDER_TARGET_7 7 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 cull modes -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_FRONT_FACE_CCW 0 -#define GX2_FRONT_FACE_CW 1 -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 polygon modes -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_POLYGON_MODE_POINT 0 -#define GX2_POLYGON_MODE_LINE 1 -#define GX2_POLYGON_MODE_TRIANGLE 2 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 special states -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_SPECIAL_STATE_CLEAR 0 -#define GX2_SPECIAL_STATE_CLEAR_HIZ 1 -#define GX2_SPECIAL_STATE_COPY 2 -#define GX2_SPECIAL_STATE_EXPAND_COLOR 3 -#define GX2_SPECIAL_STATE_EXPAND_DEPTH 4 -#define GX2_SPECIAL_STATE_CONVERT_DEPTH 5 -#define GX2_SPECIAL_STATE_CONVERT_AADEPTH 6 -#define GX2_SPECIAL_STATE_RESOLVE_COLOR 7 -#define GX2_SPECIAL_STATE_CLEAR_COLOR_AS_DEPTH 8 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 attribute formats -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_ATTRIB_FORMAT_8_UNORM 0x00000000 -#define GX2_ATTRIB_FORMAT_4_4_UNORM 0x00000001 -#define GX2_ATTRIB_FORMAT_16_UNORM 0x00000002 -#define GX2_ATTRIB_FORMAT_8_8_UNORM 0x00000004 -#define GX2_ATTRIB_FORMAT_16_16_UNORM 0x00000007 -#define GX2_ATTRIB_FORMAT_8_8_8_8_UNORM 0x0000000A -#define GX2_ATTRIB_FORMAT_10_10_10_2_UNORM 0x0000000B -#define GX2_ATTRIB_FORMAT_16_16_16_16_UNORM 0x0000000E - -#define GX2_ATTRIB_FORMAT_8_UINT 0x00000100 -#define GX2_ATTRIB_FORMAT_16_UINT 0x00000102 -#define GX2_ATTRIB_FORMAT_8_8_UINT 0x00000104 -#define GX2_ATTRIB_FORMAT_32_UINT 0x00000105 -#define GX2_ATTRIB_FORMAT_16_16_UINT 0x00000107 -#define GX2_ATTRIB_FORMAT_8_8_8_8_UINT 0x0000010A -#define GX2_ATTRIB_FORMAT_10_10_10_2_UINT 0x0000010B -#define GX2_ATTRIB_FORMAT_32_32_UINT 0x0000010C -#define GX2_ATTRIB_FORMAT_16_16_16_16_UINT 0x0000010E -#define GX2_ATTRIB_FORMAT_32_32_32_UINT 0x00000110 -#define GX2_ATTRIB_FORMAT_32_32_32_32_UINT 0x00000112 - -#define GX2_ATTRIB_FORMAT_8_SNORM 0x00000200 -#define GX2_ATTRIB_FORMAT_16_SNORM 0x00000202 -#define GX2_ATTRIB_FORMAT_8_8_SNORM 0x00000204 -#define GX2_ATTRIB_FORMAT_16_16_SNORM 0x00000207 -#define GX2_ATTRIB_FORMAT_8_8_8_8_SNORM 0x0000020A -#define GX2_ATTRIB_FORMAT_10_10_10_2_SNORM 0x0000020B -#define GX2_ATTRIB_FORMAT_16_16_16_16_SNORM 0x0000020E - -#define GX2_ATTRIB_FORMAT_8_SINT 0x00000300 -#define GX2_ATTRIB_FORMAT_16_SINT 0x00000303 -#define GX2_ATTRIB_FORMAT_8_8_SINT 0x00000304 -#define GX2_ATTRIB_FORMAT_32_SINT 0x00000305 -#define GX2_ATTRIB_FORMAT_16_16_SINT 0x00000307 -#define GX2_ATTRIB_FORMAT_8_8_8_8_SINT 0x0000030A -#define GX2_ATTRIB_FORMAT_10_10_10_2_SINT 0x0000030B -#define GX2_ATTRIB_FORMAT_32_32_SINT 0x0000030C -#define GX2_ATTRIB_FORMAT_16_16_16_16_SINT 0x0000030E -#define GX2_ATTRIB_FORMAT_32_32_32_SINT 0x00000310 -#define GX2_ATTRIB_FORMAT_32_32_32_32_SINT 0x00000312 - -#define GX2_ATTRIB_FORMAT_8_UINT_TO_FLOAT 0x00000800 -#define GX2_ATTRIB_FORMAT_16_UINT_TO_FLOAT 0x00000802 -#define GX2_ATTRIB_FORMAT_16_FLOAT 0x00000803 -#define GX2_ATTRIB_FORMAT_8_8_UINT_TO_FLOAT 0x00000804 -#define GX2_ATTRIB_FORMAT_32_FLOAT 0x00000806 -#define GX2_ATTRIB_FORMAT_16_16_UINT_TO_FLOAT 0x00000807 -#define GX2_ATTRIB_FORMAT_16_16_FLOAT 0x00000808 -#define GX2_ATTRIB_FORMAT_10_11_11_FLOAT 0x00000809 -#define GX2_ATTRIB_FORMAT_8_8_8_8_UINT_TO_FLOAT 0x0000080A -#define GX2_ATTRIB_FORMAT_32_32_FLOAT 0x0000080D -#define GX2_ATTRIB_FORMAT_16_16_16_16_UINT_TO_FLOAT 0x0000080E -#define GX2_ATTRIB_FORMAT_16_16_16_16_FLOAT 0x0000080F -#define GX2_ATTRIB_FORMAT_32_32_32_FLOAT 0x00000811 -#define GX2_ATTRIB_FORMAT_32_32_32_32_FLOAT 0x00000813 - -#define GX2_ATTRIB_FORMAT_8_SINT_TO_FLOAT 0x00000A00 -#define GX2_ATTRIB_FORMAT_16_SINT_TO_FLOAT 0x00000A02 -#define GX2_ATTRIB_FORMAT_8_8_SINT_TO_FLOAT 0x00000A04 -#define GX2_ATTRIB_FORMAT_16_16_SINT_TO_FLOAT 0x00000A07 -#define GX2_ATTRIB_FORMAT_8_8_8_8_SINT_TO_FLOAT 0x00000A0A -#define GX2_ATTRIB_FORMAT_16_16_16_16_SINT_TO_FLOAT 0x00000A0E - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 shader modes -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_SHADER_MODE_UNIFORM_REGISTER 0 -#define GX2_SHADER_MODE_UNIFORM_BLOCK 1 -#define GX2_SHADER_MODE_GEOMETRY_SHADER 2 -#define GX2_SHADER_MODE_COMPUTE_SHADER 3 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 shader modes -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_COMP_SEL_NONE 0x04040405 -#define GX2_COMP_SEL_X001 0x00040405 -#define GX2_COMP_SEL_XY01 0x00010405 -#define GX2_COMP_SEL_XYZ1 0x00010205 -#define GX2_COMP_SEL_XYZW 0x00010203 -#define GX2_COMP_SEL_XXXX 0x00000000 -#define GX2_COMP_SEL_YYYY 0x01010101 -#define GX2_COMP_SEL_ZZZZ 0x02020202 -#define GX2_COMP_SEL_WWWW 0x03030303 -#define GX2_COMP_SEL_WZYX 0x03020100 -#define GX2_COMP_SEL_WXYZ 0x03000102 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 variable types -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_VAR_TYPE_VOID 0 -#define GX2_VAR_TYPE_BOOL 1 -#define GX2_VAR_TYPE_INT 2 -#define GX2_VAR_TYPE_UINT 3 -#define GX2_VAR_TYPE_FLOAT 4 -#define GX2_VAR_TYPE_DOUBLE 5 -#define GX2_VAR_TYPE_VEC2 9 -#define GX2_VAR_TYPE_VEC3 10 -#define GX2_VAR_TYPE_VEC4 11 -#define GX2_VAR_TYPE_MAT2 21 -#define GX2_VAR_TYPE_MAT3 25 -#define GX2_VAR_TYPE_MAT4 29 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 sample types -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_SAMPLER_TYPE_2D 1 - - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 index formats -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_INDEX_FORMAT_U16 4 -#define GX2_INDEX_FORMAT_uint32_t 9 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 primitive types -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_PRIMITIVE_POINTS 0x01 -#define GX2_PRIMITIVE_LINES 0x02 -#define GX2_PRIMITIVE_LINE_STRIP 0x03 -#define GX2_PRIMITIVE_TRIANGLES 0x04 -#define GX2_PRIMITIVE_TRIANGLE_FAN 0x05 -#define GX2_PRIMITIVE_TRIANGLE_STRIP 0x06 -#define GX2_PRIMITIVE_RECTS 0x11 -#define GX2_PRIMITIVE_QUADS 0x13 -#define GX2_PRIMITIVE_QUAD_STRIP 0x14 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 clear modes -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_CLEAR_DEPTH 0x01 -#define GX2_CLEAR_STENCIL 0x02 -#define GX2_CLEAR_BOTH (GX2_CLEAR_DEPTH | GX2_CLEAR_STENCIL) - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 surface formats -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_SURFACE_FORMAT_TC_R8_UNORM 0x00000001 -#define GX2_SURFACE_FORMAT_T_R4_G4_UNORM 0x00000002 -#define GX2_SURFACE_FORMAT_TCD_R16_UNORM 0x00000005 -#define GX2_SURFACE_FORMAT_TC_R8_G8_UNORM 0x00000007 -#define GX2_SURFACE_FORMAT_TCS_R5_G6_B5_UNORM 0x00000008 -#define GX2_SURFACE_FORMAT_TC_R5_G5_B5_A1_UNORM 0x0000000a -#define GX2_SURFACE_FORMAT_TC_R4_G4_B4_A4_UNORM 0x0000000b -#define GX2_SURFACE_FORMAT_TC_A1_B5_G5_R5_UNORM 0x0000000c -#define GX2_SURFACE_FORMAT_TC_R16_G16_UNORM 0x0000000f -#define GX2_SURFACE_FORMAT_D_D24_S8_UNORM 0x00000011 -#define GX2_SURFACE_FORMAT_T_R24_UNORM_X8 0x00000011 -#define GX2_SURFACE_FORMAT_TCS_R10_G10_B10_A2_UNORM 0x00000019 -#define GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM 0x0000001a -#define GX2_SURFACE_FORMAT_TCS_A2_B10_G10_R10_UNORM 0x0000001b -#define GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_UNORM 0x0000001f -#define GX2_SURFACE_FORMAT_T_BC1_UNORM 0x00000031 -#define GX2_SURFACE_FORMAT_T_BC2_UNORM 0x00000032 -#define GX2_SURFACE_FORMAT_T_BC3_UNORM 0x00000033 -#define GX2_SURFACE_FORMAT_T_BC4_UNORM 0x00000034 -#define GX2_SURFACE_FORMAT_T_BC5_UNORM 0x00000035 -#define GX2_SURFACE_FORMAT_T_NV12_UNORM 0x00000081 - -#define GX2_SURFACE_FORMAT_TC_R8_UINT 0x00000101 -#define GX2_SURFACE_FORMAT_TC_R16_UINT 0x00000105 -#define GX2_SURFACE_FORMAT_TC_R8_G8_UINT 0x00000107 -#define GX2_SURFACE_FORMAT_TC_R32_UINT 0x0000010d -#define GX2_SURFACE_FORMAT_TC_R16_G16_UINT 0x0000010f -#define GX2_SURFACE_FORMAT_T_X24_G8_UINT 0x00000111 -#define GX2_SURFACE_FORMAT_TC_R10_G10_B10_A2_UINT 0x00000119 -#define GX2_SURFACE_FORMAT_TC_R8_G8_B8_A8_UINT 0x0000011a -#define GX2_SURFACE_FORMAT_TC_A2_B10_G10_R10_UINT 0x0000011b -#define GX2_SURFACE_FORMAT_T_X32_G8_UINT_X24 0x0000011c -#define GX2_SURFACE_FORMAT_TC_R32_G32_UINT 0x0000011d -#define GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_UINT 0x0000011f -#define GX2_SURFACE_FORMAT_TC_R32_G32_B32_A32_UINT 0x00000122 - -#define GX2_SURFACE_FORMAT_TC_R8_SNORM 0x00000201 -#define GX2_SURFACE_FORMAT_TC_R16_SNORM 0x00000205 -#define GX2_SURFACE_FORMAT_TC_R8_G8_SNORM 0x00000207 -#define GX2_SURFACE_FORMAT_TC_R16_G16_SNORM 0x0000020f -#define GX2_SURFACE_FORMAT_T_R10_G10_B10_A2_SNORM 0x00000219 -#define GX2_SURFACE_FORMAT_TC_R10_G10_B10_A2_SNORM 0x00000219 -#define GX2_SURFACE_FORMAT_TC_R8_G8_B8_A8_SNORM 0x0000021a -#define GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_SNORM 0x0000021f -#define GX2_SURFACE_FORMAT_T_BC4_SNORM 0x00000234 -#define GX2_SURFACE_FORMAT_T_BC5_SNORM 0x00000235 - -#define GX2_SURFACE_FORMAT_TC_R8_SINT 0x00000301 -#define GX2_SURFACE_FORMAT_TC_R16_SINT 0x00000305 -#define GX2_SURFACE_FORMAT_TC_R8_G8_SINT 0x00000307 -#define GX2_SURFACE_FORMAT_TC_R32_SINT 0x0000030d -#define GX2_SURFACE_FORMAT_TC_R16_G16_SINT 0x0000030f -#define GX2_SURFACE_FORMAT_TC_R10_G10_B10_A2_SINT 0x00000319 -#define GX2_SURFACE_FORMAT_TC_R8_G8_B8_A8_SINT 0x0000031a -#define GX2_SURFACE_FORMAT_TC_R32_G32_SINT 0x0000031d -#define GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_SINT 0x0000031f -#define GX2_SURFACE_FORMAT_TC_R32_G32_B32_A32_SINT 0x00000322 - -#define GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_SRGB 0x0000041a -#define GX2_SURFACE_FORMAT_T_BC1_SRGB 0x00000431 -#define GX2_SURFACE_FORMAT_T_BC2_SRGB 0x00000432 -#define GX2_SURFACE_FORMAT_T_BC3_SRGB 0x00000433 - -#define GX2_SURFACE_FORMAT_TC_R16_FLOAT 0x00000806 -#define GX2_SURFACE_FORMAT_TCD_R32_FLOAT 0x0000080e -#define GX2_SURFACE_FORMAT_TC_R16_G16_FLOAT 0x00000810 -#define GX2_SURFACE_FORMAT_D_D24_S8_FLOAT 0x00000811 -#define GX2_SURFACE_FORMAT_TC_R11_G11_B10_FLOAT 0x00000816 -#define GX2_SURFACE_FORMAT_D_D32_FLOAT_S8_UINT_X24 0x0000081c -#define GX2_SURFACE_FORMAT_T_R32_FLOAT_X8_X24 0x0000081c -#define GX2_SURFACE_FORMAT_TC_R32_G32_FLOAT 0x0000081e -#define GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_FLOAT 0x00000820 -#define GX2_SURFACE_FORMAT_TC_R32_G32_B32_A32_FLOAT 0x00000823 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 tile modes -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_TILE_MODE_DEFAULT 0x00000000 -#define GX2_TILE_MODE_LINEAR_ALIGNED 0x00000001 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 surface use -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_SURFACE_USE_TEXTURE 0x00000001 -#define GX2_SURFACE_USE_COLOR_BUFFER 0x00000002 -#define GX2_SURFACE_USE_DEPTH_BUFFER 0x00000004 -#define GX2_SURFACE_USE_SCAN_BUFFER 0x00000008 -#define GX2_SURFACE_USE_FTV 0x80000000 -#define GX2_SURFACE_USE_COLOR_BUFFER_TEXTURE (GX2_SURFACE_USE_COLOR_BUFFER | GX2_SURFACE_USE_TEXTURE) -#define GX2_SURFACE_USE_DEPTH_BUFFER_TEXTURE (GX2_SURFACE_USE_DEPTH_BUFFER | GX2_SURFACE_USE_TEXTURE) -#define GX2_SURFACE_USE_COLOR_BUFFER_FTV (GX2_SURFACE_USE_COLOR_BUFFER | GX2_SURFACE_USE_FTV) -#define GX2_SURFACE_USE_COLOR_BUFFER_TEXTURE_FTV (GX2_SURFACE_USE_COLOR_BUFFER_TEXTURE | GX2_SURFACE_USE_FTV) - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 surface dim -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_SURFACE_DIM_1D 0x00000000 -#define GX2_SURFACE_DIM_2D 0x00000001 -#define GX2_SURFACE_DIM_3D 0x00000002 -#define GX2_SURFACE_DIM_CUBE 0x00000003 -#define GX2_SURFACE_DIM_1D_ARRAY 0x00000004 -#define GX2_SURFACE_DIM_2D_ARRAY 0x00000005 -#define GX2_SURFACE_DIM_2D_MSAA 0x00000006 -#define GX2_SURFACE_DIM_2D_MSAA_ARRAY 0x00000007 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 AA modes -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_AA_MODE_1X 0x00000000 -#define GX2_AA_MODE_2X 0x00000001 -#define GX2_AA_MODE_4X 0x00000002 -#define GX2_AA_MODE_8X 0x00000003 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 texture clamp -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_TEX_CLAMP_WRAP 0x00000000 -#define GX2_TEX_CLAMP_MIRROR 0x00000001 -#define GX2_TEX_CLAMP_CLAMP 0x00000002 -#define GX2_TEX_CLAMP_MIRROR_ONCE 0x00000003 -#define GX2_TEX_CLAMP_CLAMP_HALF_BORDER 0x00000004 -#define GX2_TEX_CLAMP_MIRROR_ONCE_HALF_BORDER 0x00000005 -#define GX2_TEX_CLAMP_CLAMP_BORDER 0x00000006 -#define GX2_TEX_CLAMP_MIRROR_ONCE_BORDER 0x00000007 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 texture filter -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_TEX_XY_FILTER_POINT 0x00000000 -#define GX2_TEX_XY_FILTER_BILINEAR 0x00000001 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 TV scan modes -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_TV_SCAN_MODE_NONE 0x00000000 -#define GX2_TV_SCAN_MODE_576I 0x00000001 -#define GX2_TV_SCAN_MODE_480I 0x00000002 -#define GX2_TV_SCAN_MODE_480P 0x00000003 -#define GX2_TV_SCAN_MODE_720P 0x00000004 -#define GX2_TV_SCAN_MODE_1080I 0x00000006 -#define GX2_TV_SCAN_MODE_1080P 0x00000007 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 TV render modes -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_TV_RENDER_480_NARROW 0x00000001 -#define GX2_TV_RENDER_480_WIDE 0x00000002 -#define GX2_TV_RENDER_720 0x00000003 -#define GX2_TV_RENDER_1080 0x00000005 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 DRC render modes -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_DRC_NONE 0x00000000 -#define GX2_DRC_SINGLE 0x00000001 -#define GX2_DRC_DOUBLE 0x00000002 -#define GX2_DRC_SINGLE_30HZ 0x00000004 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 buffering mode -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_BUFFERING_SINGLE 0x00000001 -#define GX2_BUFFERING_DOUBLE 0x00000002 -#define GX2_BUFFERING_TRIPLE 0x00000003 -#define GX2_BUFFERING_QUAD -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 scan targets -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_SCAN_TARGET_TV 0x00000001 -#define GX2_SCAN_TARGET_DRC_FIRST 0x00000004 -#define GX2_SCAN_TARGET_DRC_SECOND 0x00000008 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 invalidate types -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_INVALIDATE_ATTRIB_BUFFER 0x00000001 -#define GX2_INVALIDATE_TEXTURE 0x00000002 -#define GX2_INVALIDATE_UNIFORM_BLOCK 0x00000004 -#define GX2_INVALIDATE_SHADER 0x00000008 -#define GX2_INVALIDATE_COLOR_BUFFER 0x00000010 -#define GX2_INVALIDATE_DEPTH_BUFFER 0x00000020 -#define GX2_INVALIDATE_CPU 0x00000040 -#define GX2_INVALIDATE_CPU_ATTRIB_BUFFER (GX2_INVALIDATE_CPU | GX2_INVALIDATE_ATTRIB_BUFFER) -#define GX2_INVALIDATE_CPU_TEXTURE (GX2_INVALIDATE_CPU | GX2_INVALIDATE_TEXTURE) -#define GX2_INVALIDATE_CPU_UNIFORM_BLOCK (GX2_INVALIDATE_CPU | GX2_INVALIDATE_UNIFORM_BLOCK) -#define GX2_INVALIDATE_CPU_SHADER (GX2_INVALIDATE_CPU | GX2_INVALIDATE_SHADER) - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 swap modes -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_ENDIANSWAP_DEFAULT 0x00000003 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 tessellation modes -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_TESSELLATION_MODE_DISCRETE 0x00000000 -#define GX2_TESSELLATION_MODE_CONTINUOUS 0x00000001 -#define GX2_TESSELLATION_MODE_ADAPTIVE 0x00000002 - -//!----------------------------------------------------------------------------------------------------------------------- -//! GX2 fetch shader types -//!----------------------------------------------------------------------------------------------------------------------- -#define GX2_FETCH_SHADER_TESSELATION_NONE 0x00000000 -#define GX2_FETCH_SHADER_TESSELATION_LINES 0x00000001 -#define GX2_FETCH_SHADER_TESSELATION_TRIANGLES 0x00000002 -#define GX2_FETCH_SHADER_TESSELATION_QUADS 0x00000003 - - -typedef struct _GX2ContextState { - uint8_t data[GX2_CONTEXT_STATE_SIZE]; -} GX2ContextState; - -typedef struct _GX2Surface { - int32_t dimension; - uint32_t width; - uint32_t height; - uint32_t depth; - uint32_t num_mips; - int32_t format; - int32_t aa; - int32_t use; - uint32_t image_size; - void *image_data; - uint32_t mip_size; - void *mip_data; - int32_t tile; - uint32_t swizzle; - uint32_t align; - uint32_t pitch; - uint32_t mip_offset[13]; -} GX2Surface; - -typedef struct _GX2ColorBuffer { - GX2Surface surface; - uint32_t view_mip; - uint32_t view_first_slice; - uint32_t view_slices_count; - void *aux_data; - uint32_t aux_size; - uint32_t regs[5]; -} GX2ColorBuffer; - -typedef struct _GX2DepthBuffer { - GX2Surface surface; - uint32_t view_mip; - uint32_t view_first_slice; - uint32_t view_slices_count; - void *hiZ_data; - uint32_t hiZ_size; - float clear_depth; - uint32_t clear_stencil; - uint32_t regs[7]; -} GX2DepthBuffer; - - -typedef struct _GX2Texture { - GX2Surface surface; - uint32_t view_first_mip; - uint32_t view_mips_count; - uint32_t view_first_slice; - uint32_t view_slices_count; - uint32_t component_selector; - uint32_t regs[5]; -} GX2Texture; - - -typedef struct _GX2Sampler { - uint32_t regs[3]; -} GX2Sampler; - -typedef struct _GX2AttribStream { - uint32_t location; - uint32_t buffer; - uint32_t offset; - int32_t format; - int32_t index_type; - uint32_t divisor; - uint32_t destination_selector; - int32_t endian_swap; -} GX2AttribStream; - -typedef struct _GX2FetchShader { - int32_t type; - uint32_t reg; - uint32_t shader_size; - void *shader_program; - uint32_t attributes_count; - uint32_t divisor[3]; -} GX2FetchShader; - -typedef struct _GX2AttribVar { - const char *name; - int32_t var_type; - uint32_t array_count; - uint32_t location; -} GX2AttribVar; - - -typedef struct _GX2UniformBlock { - const char *name; - uint32_t location; - uint32_t block_size; -} GX2UniformBlock; - -typedef struct _GX2UniformInitialValue { - float value[4]; - uint32_t offset; -} GX2UniformInitialValue; - -typedef struct _GX2SamplerVar { - const char *name; - int32_t sampler_type; - uint32_t location; -} GX2SamplerVar; - -typedef struct _GX2UniformVar { - const char *name; - int32_t var_type; - uint32_t array_count; - uint32_t offset; - uint32_t block_index; -} GX2UniformVar; - -typedef struct _GX2VertexShader { - uint32_t regs[52]; - uint32_t shader_size; - void *shader_data; - int32_t shader_mode; - uint32_t uniform_blocks_count; - GX2UniformBlock *uniform_block; - uint32_t uniform_vars_count; - GX2UniformVar *uniform_var; - uint32_t initial_values_count; - GX2UniformInitialValue *initial_value; - uint32_t loops_count; - void *loops_data; - uint32_t sampler_vars_count; - GX2SamplerVar *sampler_var; - uint32_t attribute_vars_count; - GX2AttribVar *attribute_var; - uint32_t data[6]; - uint32_t shader_program_buffer[16]; -} GX2VertexShader; - -typedef struct _GX2PixelShader { - uint32_t regs[41]; - uint32_t shader_size; - void *shader_data; - int32_t shader_mode; - uint32_t uniform_blocks_count; - GX2UniformBlock *uniform_block; - uint32_t uniform_vars_count; - GX2UniformVar *uniform_var; - uint32_t initial_values_count; - GX2UniformInitialValue *initial_value; - uint32_t loops_count; - void *loops_data; - uint32_t sampler_vars_count; - GX2SamplerVar *sampler_var; - uint32_t shader_program_buffer[16]; -} GX2PixelShader; - -static const uint32_t attribute_dest_comp_selector[20] = { - GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_X001, GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_X001, - GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, - GX2_COMP_SEL_XY01, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZ1, - GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW -}; - -static const uint32_t texture_comp_selector[54] = { - GX2_COMP_SEL_NONE, GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_X001, - GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, - GX2_COMP_SEL_WZYX, GX2_COMP_SEL_X001, GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XY01, GX2_COMP_SEL_NONE, - GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_NONE, - GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_WZYX, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XY01, - GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, - GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_X001, - GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZ1, - GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01 -}; - -typedef struct _GX2Color { - uint8_t r, g, b, a; -} GX2Color; - -typedef struct _GX2Colorfloat { - float r, g, b, a; -} GX2Colorfloat; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/dynamic_libs/socket_functions.c b/src/dynamic_libs/socket_functions.c deleted file mode 100644 index 529b40b..0000000 --- a/src/dynamic_libs/socket_functions.c +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#include "coreinit.h" -#include "socket_functions.h" - -uint32_t hostIpAddress = 0; - -uint32_t nsysnet_handle __attribute__((section(".data"))) = 0; - -EXPORT_DECL(int32_t, socket_lib_init, void); -EXPORT_DECL(int32_t, socket_lib_finish, void); -EXPORT_DECL(int32_t, socket, int32_t domain, int32_t type, int32_t protocol); -EXPORT_DECL(int32_t, socketclose, int32_t s); -EXPORT_DECL(int32_t, shutdown, int32_t s, int32_t how); -EXPORT_DECL(int32_t, connect, int32_t s, void *addr, int32_t addrlen); -EXPORT_DECL(int32_t, bind, int32_t s,struct sockaddr *name,int32_t namelen); -EXPORT_DECL(int32_t, listen, int32_t s,uint32_t backlog); -EXPORT_DECL(int32_t, accept, int32_t s,struct sockaddr *addr,int32_t *addrlen); -EXPORT_DECL(int32_t, send, int32_t s, const void *buffer, int32_t size, int32_t flags); -EXPORT_DECL(int32_t, recv, int32_t s, void *buffer, int32_t size, int32_t flags); -EXPORT_DECL(int32_t, recvfrom,int32_t sockfd, void *buf, int32_t len, int32_t flags,struct sockaddr *src_addr, int32_t *addrlen); -EXPORT_DECL(int32_t, sendto, int32_t s, const void *buffer, int32_t size, int32_t flags, const struct sockaddr *dest, int32_t dest_len); -EXPORT_DECL(int32_t, setsockopt, int32_t s, int32_t level, int32_t optname, void *optval, int32_t optlen); -EXPORT_DECL(char *, inet_ntoa, struct in_addr in); -EXPORT_DECL(int32_t, inet_aton, const char *cp, struct in_addr *inp); -EXPORT_DECL(const char *, inet_ntop, int32_t af, const void *src, char *dst, int32_t size); -EXPORT_DECL(int32_t, inet_pton, int32_t af, const char *src, void *dst); -EXPORT_DECL(int32_t, socketlasterr, void); - -EXPORT_DECL(int32_t, NSSLInit, void); -EXPORT_DECL(int32_t, NSSLFinish, void); -EXPORT_DECL(int32_t, NSSLCreateContext, int32_t unkwn); -EXPORT_DECL(int32_t, NSSLDestroyContext, int32_t context); -EXPORT_DECL(int32_t, NSSLAddServerPKI, int32_t context, int32_t pki); -EXPORT_DECL(int32_t, NSSLAddServerPKIExternal, int32_t context, const uint8_t* cert, int32_t length, int32_t unkwn); -EXPORT_DECL(int32_t, NSSLWrite, int32_t connection, const void* buf, int32_t len,int32_t * written); -EXPORT_DECL(int32_t, NSSLRead, int32_t connection, const void* buf, int32_t len,int32_t * read); -EXPORT_DECL(int32_t, NSSLCreateConnection, int32_t context, const char* host, int32_t hotlen,int32_t options,int32_t sock,int32_t block); - -void InitAcquireSocket(void) { - OSDynLoad_Acquire("nsysnet.rpl", &nsysnet_handle); -} - -void InitSocketFunctionPointers(void) { - uint32_t *funcPointer = 0; - - InitAcquireSocket(); - - uint32_t nn_ac_handle; - int32_t(*ACInitialize)(); - int32_t(*ACGetStartupId) (uint32_t *id); - int32_t(*ACConnectWithConfigId) (uint32_t id); - int32_t(*ACGetAssignedAddress) (uint32_t * ip); - OSDynLoad_Acquire("nn_ac.rpl", &nn_ac_handle); - OSDynLoad_FindExport(nn_ac_handle, 0, "ACInitialize", &ACInitialize); - OSDynLoad_FindExport(nn_ac_handle, 0, "ACGetStartupId", &ACGetStartupId); - OSDynLoad_FindExport(nn_ac_handle, 0, "ACConnectWithConfigId",&ACConnectWithConfigId); - OSDynLoad_FindExport(nn_ac_handle, 0, "ACGetAssignedAddress",&ACGetAssignedAddress); - - OS_FIND_EXPORT(nsysnet_handle, socket_lib_init); - OS_FIND_EXPORT(nsysnet_handle, socket_lib_finish); - OS_FIND_EXPORT(nsysnet_handle, socketlasterr); - OS_FIND_EXPORT(nsysnet_handle, socket); - OS_FIND_EXPORT(nsysnet_handle, socketclose); - OS_FIND_EXPORT(nsysnet_handle, shutdown); - OS_FIND_EXPORT(nsysnet_handle, connect); - OS_FIND_EXPORT(nsysnet_handle, bind); - OS_FIND_EXPORT(nsysnet_handle, listen); - OS_FIND_EXPORT(nsysnet_handle, accept); - OS_FIND_EXPORT(nsysnet_handle, send); - OS_FIND_EXPORT(nsysnet_handle, recv); - OS_FIND_EXPORT(nsysnet_handle, recvfrom); - OS_FIND_EXPORT(nsysnet_handle, sendto); - OS_FIND_EXPORT(nsysnet_handle, setsockopt); - OS_FIND_EXPORT(nsysnet_handle, inet_ntoa); - OS_FIND_EXPORT(nsysnet_handle, inet_aton); - OS_FIND_EXPORT(nsysnet_handle, inet_ntop); - OS_FIND_EXPORT(nsysnet_handle, inet_pton); - - OS_FIND_EXPORT(nsysnet_handle, NSSLInit); - OS_FIND_EXPORT(nsysnet_handle, NSSLFinish); - OS_FIND_EXPORT(nsysnet_handle, NSSLCreateContext); - OS_FIND_EXPORT(nsysnet_handle, NSSLDestroyContext); - OS_FIND_EXPORT(nsysnet_handle, NSSLAddServerPKI); - OS_FIND_EXPORT(nsysnet_handle, NSSLAddServerPKIExternal); - OS_FIND_EXPORT(nsysnet_handle, NSSLWrite); - OS_FIND_EXPORT(nsysnet_handle, NSSLRead); - OS_FIND_EXPORT(nsysnet_handle, NSSLCreateConnection); - - uint32_t nn_startupid; - ACInitialize(); - ACGetStartupId(&nn_startupid); - ACConnectWithConfigId(nn_startupid); - ACGetAssignedAddress(&hostIpAddress); - - socket_lib_init(); -} diff --git a/src/dynamic_libs/socket_functions.h b/src/dynamic_libs/socket_functions.h deleted file mode 100644 index e00675d..0000000 --- a/src/dynamic_libs/socket_functions.h +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#ifndef __SOCKET_FUNCTIONS_H_ -#define __SOCKET_FUNCTIONS_H_ - -#ifdef __cplusplus -extern "C" { -#endif -#include - -extern uint32_t nsysnet_handle; - -extern uint32_t hostIpAddress; - -#define INADDR_ANY 0 -#define INADDR_BROADCAST 0xFFFFFFFF - -#define AF_INET 2 - -#define SHUT_RD 0 -#define SHUT_WR 1 -#define SHUT_RDWR 2 - -#define SOCK_STREAM 1 -#define SOCK_DGRAM 2 - -#define IPPROTO_IP 0 -#define IPPROTO_TCP 6 -#define IPPROTO_UDP 17 - -#define TCP_NODELAY 0x2004 - -#define SOL_SOCKET -1 -#define SO_REUSEADDR 0x0004 -#define SO_BROADCAST 0x0020 // broadcast -#define SO_NONBLOCK 0x1016 -#define SO_MYADDR 0x1013 -#define SO_RCVTIMEO 0x1006 - -#define SOL_SOCKET -1 -#define MSG_DONTWAIT 32 - -#define htonl(x) x -#define htons(x) x -#define ntohl(x) x -#define ntohs(x) x - -struct in_addr { - uint32_t s_addr; -}; -struct sockaddr_in { - short sin_family; - unsigned short sin_port; - struct in_addr sin_addr; - char sin_zero[8]; -}; - -struct sockaddr { - unsigned short sa_family; - char sa_data[14]; -}; - - -void InitSocketFunctionPointers(void); -void InitAcquireSocket(void); - -extern int32_t (*socket_lib_init)(void); -extern int32_t (*socket_lib_finish)(void); -extern int32_t (*socket)(int32_t domain, int32_t type, int32_t protocol); -extern int32_t (*socketclose)(int32_t s); -extern int32_t (*shutdown)(int32_t s, int32_t how); -extern int32_t (*connect)(int32_t s, void *addr, int32_t addrlen); -extern int32_t (*bind)(int32_t s,struct sockaddr *name,int32_t namelen); -extern int32_t (*listen)(int32_t s,uint32_t backlog); -extern int32_t (*accept)(int32_t s,struct sockaddr *addr,int32_t *addrlen); -extern int32_t (*send)(int32_t s, const void *buffer, int32_t size, int32_t flags); -extern int32_t (*recv)(int32_t s, void *buffer, int32_t size, int32_t flags); -extern int32_t (*recvfrom)(int32_t sockfd, void *buf, int32_t len, int32_t flags,struct sockaddr *src_addr, int32_t *addrlen); -extern int32_t (*socketlasterr)(void); - -extern int32_t (*sendto)(int32_t s, const void *buffer, int32_t size, int32_t flags, const struct sockaddr *dest, int32_t dest_len); -extern int32_t (*setsockopt)(int32_t s, int32_t level, int32_t optname, void *optval, int32_t optlen); - -extern int32_t (* NSSLInit)(void); -extern int32_t (* NSSLFinish)(void); -extern int32_t (* NSSLCreateContext)(int32_t unkwn); -extern int32_t (* NSSLDestroyContext)(int32_t context); -extern int32_t (* NSSLAddServerPKIExternal)(int32_t context, const uint8_t* cert, int32_t length, int32_t unkwn); -extern int32_t (* NSSLAddServerPKI)(int32_t context, int32_t pki); -extern int32_t (* NSSLWrite)(int32_t connection, const void* buf, int32_t len,int32_t * written); -extern int32_t (* NSSLRead)(int32_t connection, const void* buf, int32_t len,int32_t * read); -extern int32_t (* NSSLCreateConnection)(int32_t context, const char* host, int32_t hotlen,int32_t options,int32_t sock,int32_t block); - -extern char * (*inet_ntoa)(struct in_addr in); -extern int32_t (*inet_aton)(const char *cp, struct in_addr *inp); -extern const char * (*inet_ntop)(int32_t af, const void *src, char *dst, int32_t size); -extern int32_t (*inet_pton)(int32_t af, const char *src, void *dst); - -#ifdef __cplusplus -} -#endif - -#endif // __SOCKET_FUNCTIONS_H_ diff --git a/src/dynamic_libs/vpad_functions.c b/src/dynamic_libs/vpad_functions.c deleted file mode 100644 index 3f3d60b..0000000 --- a/src/dynamic_libs/vpad_functions.c +++ /dev/null @@ -1,170 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#include "coreinit.h" -#include "vpad_functions.h" - -uint32_t vpad_handle __attribute__((section(".data"))) = 0; -uint32_t vpadbase_handle __attribute__((section(".data"))) = 0; - -EXPORT_DECL(void, VPADInit, void); -EXPORT_DECL(void, VPADShutdown, void); -EXPORT_DECL(int32_t, VPADRead, int32_t chan, VPADData *buffer, uint32_t buffer_size, int32_t *error); -EXPORT_DECL(void, VPADSetAccParam, int32_t chan, float play_radius, float sensitivity); -EXPORT_DECL(void, VPADGetAccParam, int32_t chan, float *play_radius, float *sensitivity); -EXPORT_DECL(void, VPADSetBtnRepeat, int32_t chan, float delay_sec, float pulse_sec); -EXPORT_DECL(void, VPADEnableStickCrossClamp, int32_t chan); -EXPORT_DECL(void, VPADDisableStickCrossClamp, int32_t chan); -EXPORT_DECL(void, VPADSetLStickClampThreshold, int32_t chan, int32_t max, int32_t min); -EXPORT_DECL(void, VPADSetRStickClampThreshold, int32_t chan, int32_t max, int32_t min); -EXPORT_DECL(void, VPADGetLStickClampThreshold, int32_t chan, int32_t* max, int32_t* min); -EXPORT_DECL(void, VPADGetRStickClampThreshold, int32_t chan, int32_t* max, int32_t* min); -EXPORT_DECL(void, VPADSetStickOrigin, int32_t chan); -EXPORT_DECL(void, VPADDisableLStickZeroClamp, int32_t chan); -EXPORT_DECL(void, VPADDisableRStickZeroClamp, int32_t chan); -EXPORT_DECL(void, VPADEnableLStickZeroClamp, int32_t chan); -EXPORT_DECL(void, VPADEnableRStickZeroClamp, int32_t chan); -EXPORT_DECL(void, VPADSetCrossStickEmulationParamsL, int32_t chan, float rot_deg, float xy_deg, float radius); -EXPORT_DECL(void, VPADSetCrossStickEmulationParamsR, int32_t chan, float rot_deg, float xy_deg, float radius); -EXPORT_DECL(void, VPADGetCrossStickEmulationParamsL, int32_t chan, float* rot_deg, float* xy_deg, float* radius); -EXPORT_DECL(void, VPADGetCrossStickEmulationParamsR, int32_t chan, float* rot_deg, float* xy_deg, float* radius); -EXPORT_DECL(void, VPADSetGyroAngle, int32_t chan, float ax, float ay, float az); -EXPORT_DECL(void, VPADSetGyroDirection, int32_t chan, VPADDir *dir); -EXPORT_DECL(void, VPADSetGyroDirectionMag, int32_t chan, float mag); -EXPORT_DECL(void, VPADSetGyroMagnification, int32_t chan, float pitch, float yaw, float roll); -EXPORT_DECL(void, VPADEnableGyroZeroPlay, int32_t chan); -EXPORT_DECL(void, VPADEnableGyroDirRevise, int32_t chan); -EXPORT_DECL(void, VPADEnableGyroAccRevise, int32_t chan); -EXPORT_DECL(void, VPADDisableGyroZeroPlay, int32_t chan); -EXPORT_DECL(void, VPADDisableGyroDirRevise, int32_t chan); -EXPORT_DECL(void, VPADDisableGyroAccRevise, int32_t chan); -EXPORT_DECL(float, VPADIsEnableGyroZeroPlay, int32_t chan); -EXPORT_DECL(float, VPADIsEnableGyroZeroDrift, int32_t chan); -EXPORT_DECL(float, VPADIsEnableGyroDirRevise, int32_t chan); -EXPORT_DECL(float, VPADIsEnableGyroAccRevise, int32_t chan); -EXPORT_DECL(void, VPADSetGyroZeroPlayParam, int32_t chan, float radius); -EXPORT_DECL(void, VPADSetGyroDirReviseParam, int32_t chan, float revis_pw); -EXPORT_DECL(void, VPADSetGyroAccReviseParam, int32_t chan, float revise_pw, float revise_range); -EXPORT_DECL(void, VPADSetGyroDirReviseBase, int32_t chan, VPADDir *base); -EXPORT_DECL(void, VPADGetGyroZeroPlayParam, int32_t chan, float *radius); -EXPORT_DECL(void, VPADGetGyroDirReviseParam, int32_t chan, float *revise_pw); -EXPORT_DECL(void, VPADGetGyroAccReviseParam, int32_t chan, float *revise_pw, float *revise_range); -EXPORT_DECL(void, VPADInitGyroZeroPlayParam, int32_t chan); -EXPORT_DECL(void, VPADInitGyroDirReviseParam, int32_t chan); -EXPORT_DECL(void, VPADInitGyroAccReviseParam, int32_t chan); -EXPORT_DECL(void, VPADInitGyroZeroDriftMode, int32_t chan); -EXPORT_DECL(void, VPADSetGyroZeroDriftMode, int32_t chan, VPADGyroZeroDriftMode mode); -EXPORT_DECL(void, VPADGetGyroZeroDriftMode, int32_t chan, VPADGyroZeroDriftMode *mode); -EXPORT_DECL(int16_t, VPADCalcTPCalibrationParam, VPADTPCalibrationParam* param, uint16_t rawX1, uint16_t rawY1, uint16_t x1, uint16_t y1, uint16_t rawX2, uint16_t rawY2, uint16_t x2, uint16_t y2); -EXPORT_DECL(void, VPADSetTPCalibrationParam, int32_t chan, const VPADTPCalibrationParam param); -EXPORT_DECL(void, VPADGetTPCalibrationParam, int32_t chan, VPADTPCalibrationParam* param); -EXPORT_DECL(void, VPADGetTPCalibratedPoint, int32_t chan, VPADTPData *disp, const VPADTPData *raw); -EXPORT_DECL(void, VPADGetTPCalibratedPointEx, int32_t chan, VPADTPResolution tpReso, VPADTPData *disp, const VPADTPData *raw); -EXPORT_DECL(int32_t, VPADControlMotor, int32_t chan, uint8_t* pattern, uint8_t length); -EXPORT_DECL(void, VPADStopMotor, int32_t chan); -EXPORT_DECL(int32_t, VPADSetLcdMode, int32_t chan, int32_t lcdmode); -EXPORT_DECL(int32_t, VPADGetLcdMode, int32_t chan, int32_t *lcdmode); -EXPORT_DECL(int32_t, VPADBASEGetMotorOnRemainingCount, int32_t lcdmode); -EXPORT_DECL(int32_t, VPADBASESetMotorOnRemainingCount, int32_t lcdmode, int32_t counter); -EXPORT_DECL(void, VPADBASESetSensorBarSetting, int32_t chan, char setting); -EXPORT_DECL(void, VPADBASEGetSensorBarSetting, int32_t chan, char *setting); -EXPORT_DECL(int32_t, VPADSetSensorBar, int32_t chan, int32_t on); -EXPORT_DECL(samplingCallback, VPADSetSamplingCallback, int32_t chan, samplingCallback callbackn); - -void InitAcquireVPad(void) { - if(coreinit_handle == 0) { - InitAcquireOS(); - }; - OSDynLoad_Acquire("vpad.rpl", &vpad_handle); - OSDynLoad_Acquire("vpadbase.rpl", &vpadbase_handle); -} - -void InitVPadFunctionPointers(void) { - uint32_t *funcPointer = 0; - - InitAcquireVPad(); - - OS_FIND_EXPORT(vpad_handle, VPADInit); - OS_FIND_EXPORT(vpad_handle, VPADShutdown); - OS_FIND_EXPORT(vpad_handle, VPADRead); - OS_FIND_EXPORT(vpad_handle, VPADSetAccParam); - OS_FIND_EXPORT(vpad_handle, VPADGetAccParam); - OS_FIND_EXPORT(vpad_handle, VPADSetBtnRepeat); - OS_FIND_EXPORT(vpad_handle, VPADEnableStickCrossClamp); - OS_FIND_EXPORT(vpad_handle, VPADDisableStickCrossClamp); - OS_FIND_EXPORT(vpad_handle, VPADSetLStickClampThreshold); - OS_FIND_EXPORT(vpad_handle, VPADSetRStickClampThreshold); - OS_FIND_EXPORT(vpad_handle, VPADGetLStickClampThreshold); - OS_FIND_EXPORT(vpad_handle, VPADGetRStickClampThreshold); - OS_FIND_EXPORT(vpad_handle, VPADSetStickOrigin); - OS_FIND_EXPORT(vpad_handle, VPADDisableLStickZeroClamp); - OS_FIND_EXPORT(vpad_handle, VPADDisableRStickZeroClamp); - OS_FIND_EXPORT(vpad_handle, VPADEnableLStickZeroClamp); - OS_FIND_EXPORT(vpad_handle, VPADEnableRStickZeroClamp); - OS_FIND_EXPORT(vpad_handle, VPADSetCrossStickEmulationParamsL); - OS_FIND_EXPORT(vpad_handle, VPADSetCrossStickEmulationParamsR); - OS_FIND_EXPORT(vpad_handle, VPADGetCrossStickEmulationParamsL); - OS_FIND_EXPORT(vpad_handle, VPADGetCrossStickEmulationParamsR); - OS_FIND_EXPORT(vpad_handle, VPADSetGyroAngle); - OS_FIND_EXPORT(vpad_handle, VPADSetGyroDirection); - OS_FIND_EXPORT(vpad_handle, VPADSetGyroDirectionMag); - OS_FIND_EXPORT(vpad_handle, VPADSetGyroMagnification); - OS_FIND_EXPORT(vpad_handle, VPADEnableGyroZeroPlay); - OS_FIND_EXPORT(vpad_handle, VPADEnableGyroDirRevise); - OS_FIND_EXPORT(vpad_handle, VPADEnableGyroAccRevise); - OS_FIND_EXPORT(vpad_handle, VPADDisableGyroZeroPlay); - OS_FIND_EXPORT(vpad_handle, VPADDisableGyroDirRevise); - OS_FIND_EXPORT(vpad_handle, VPADDisableGyroAccRevise); - OS_FIND_EXPORT(vpad_handle, VPADIsEnableGyroZeroPlay); - OS_FIND_EXPORT(vpad_handle, VPADIsEnableGyroZeroDrift); - OS_FIND_EXPORT(vpad_handle, VPADIsEnableGyroDirRevise); - OS_FIND_EXPORT(vpad_handle, VPADIsEnableGyroAccRevise); - OS_FIND_EXPORT(vpad_handle, VPADSetGyroZeroPlayParam); - OS_FIND_EXPORT(vpad_handle, VPADSetGyroDirReviseParam); - OS_FIND_EXPORT(vpad_handle, VPADSetGyroAccReviseParam); - OS_FIND_EXPORT(vpad_handle, VPADSetGyroDirReviseBase); - OS_FIND_EXPORT(vpad_handle, VPADGetGyroZeroPlayParam); - OS_FIND_EXPORT(vpad_handle, VPADGetGyroDirReviseParam); - OS_FIND_EXPORT(vpad_handle, VPADGetGyroAccReviseParam); - OS_FIND_EXPORT(vpad_handle, VPADInitGyroZeroPlayParam); - OS_FIND_EXPORT(vpad_handle, VPADInitGyroDirReviseParam); - OS_FIND_EXPORT(vpad_handle, VPADInitGyroAccReviseParam); - OS_FIND_EXPORT(vpad_handle, VPADInitGyroZeroDriftMode); - OS_FIND_EXPORT(vpad_handle, VPADSetGyroZeroDriftMode); - OS_FIND_EXPORT(vpad_handle, VPADGetGyroZeroDriftMode); - OS_FIND_EXPORT(vpad_handle, VPADCalcTPCalibrationParam); - OS_FIND_EXPORT(vpad_handle, VPADSetTPCalibrationParam); - OS_FIND_EXPORT(vpad_handle, VPADGetTPCalibrationParam); - OS_FIND_EXPORT(vpad_handle, VPADGetTPCalibratedPoint); - OS_FIND_EXPORT(vpad_handle, VPADGetTPCalibratedPointEx); - OS_FIND_EXPORT(vpad_handle, VPADControlMotor); - OS_FIND_EXPORT(vpad_handle, VPADStopMotor); - OS_FIND_EXPORT(vpad_handle, VPADSetLcdMode); - OS_FIND_EXPORT(vpad_handle, VPADGetLcdMode); - OS_FIND_EXPORT(vpad_handle, VPADSetSensorBar); - OS_FIND_EXPORT(vpad_handle, VPADSetSamplingCallback); - OS_FIND_EXPORT(vpadbase_handle, VPADBASEGetMotorOnRemainingCount); - OS_FIND_EXPORT(vpadbase_handle, VPADBASESetMotorOnRemainingCount); - OS_FIND_EXPORT(vpadbase_handle, VPADBASESetSensorBarSetting); - OS_FIND_EXPORT(vpadbase_handle, VPADBASEGetSensorBarSetting); -} diff --git a/src/dynamic_libs/vpad_functions.h b/src/dynamic_libs/vpad_functions.h deleted file mode 100644 index 3a11c4e..0000000 --- a/src/dynamic_libs/vpad_functions.h +++ /dev/null @@ -1,207 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#ifndef __VPAD_FUNCTIONS_H_ -#define __VPAD_FUNCTIONS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -extern uint32_t vpad_handle; -extern uint32_t vpadbase_handle; - -#define VPAD_BUTTON_A 0x8000 -#define VPAD_BUTTON_B 0x4000 -#define VPAD_BUTTON_X 0x2000 -#define VPAD_BUTTON_Y 0x1000 -#define VPAD_BUTTON_LEFT 0x0800 -#define VPAD_BUTTON_RIGHT 0x0400 -#define VPAD_BUTTON_UP 0x0200 -#define VPAD_BUTTON_DOWN 0x0100 -#define VPAD_BUTTON_ZL 0x0080 -#define VPAD_BUTTON_ZR 0x0040 -#define VPAD_BUTTON_L 0x0020 -#define VPAD_BUTTON_R 0x0010 -#define VPAD_BUTTON_PLUS 0x0008 -#define VPAD_BUTTON_MINUS 0x0004 -#define VPAD_BUTTON_HOME 0x0002 -#define VPAD_BUTTON_SYNC 0x0001 -#define VPAD_BUTTON_STICK_R 0x00020000 -#define VPAD_BUTTON_STICK_L 0x00040000 -#define VPAD_BUTTON_TV 0x00010000 - -#define VPAD_STICK_R_EMULATION_LEFT 0x04000000 -#define VPAD_STICK_R_EMULATION_RIGHT 0x02000000 -#define VPAD_STICK_R_EMULATION_UP 0x01000000 -#define VPAD_STICK_R_EMULATION_DOWN 0x00800000 - -#define VPAD_STICK_L_EMULATION_LEFT 0x40000000 -#define VPAD_STICK_L_EMULATION_RIGHT 0x20000000 -#define VPAD_STICK_L_EMULATION_UP 0x10000000 -#define VPAD_STICK_L_EMULATION_DOWN 0x08000000 - -//! Own definitions -#define VPAD_BUTTON_TOUCH 0x00080000 -#define VPAD_MASK_EMULATED_STICKS 0x7F800000 -#define VPAD_MASK_BUTTONS ~VPAD_MASK_EMULATED_STICKS - -typedef enum VPADTPResolution { - VPAD_TP_1920x1080, - VPAD_TP_1280x720, - VPAD_TP_854x480 -} VPADTPResolution; - -typedef enum VPADGyroZeroDriftMode { - VPAD_GYRO_ZERODRIFT_LOOSE, - VPAD_GYRO_ZERODRIFT_STANDARD, - VPAD_GYRO_ZERODRIFT_TIGHT -} VPADGyroZeroDriftMode; - -typedef struct { - float x,y; -} Vec2D; - -typedef struct { - float x,y,z; -} Vec3D; - -typedef struct { - Vec3D X,Y,Z; -} VPADDir; - -typedef struct { - uint16_t x, y; /* Touch coordinates */ - uint16_t touched; /* 1 = Touched, 0 = Not touched */ - uint16_t invalid; /* 0 = All valid, 1 = X invalid, 2 = Y invalid, 3 = Both invalid? */ -} VPADTPData; - -typedef struct { - int16_t offsetX; - int16_t offsetY; - float scaleX; - float scaleY; -} VPADTPCalibrationParam; - -typedef struct { - uint32_t btns_h; /* Held buttons */ - uint32_t btns_d; /* Buttons that are pressed at that instant */ - uint32_t btns_r; /* Released buttons */ - Vec2D lstick, rstick; /* Each contains 4-byte X and Y components */ - Vec3D acc; /* Status of DRC accelerometer */ - float acc_magnitude; /* Accelerometer magnitude */ - float acc_variation; /* Accelerometer variation */ - Vec2D acc_vertical; /* Vertical */ - Vec3D gyro; /* Gyro data */ - Vec3D angle; /* Angle data */ - char error; /* Error */ - VPADTPData tpdata; /* Normal touchscreen data */ - VPADTPData tpdata1; /* Modified touchscreen data 1 */ - VPADTPData tpdata2; /* Modified touchscreen data 2 */ - VPADDir dir; /* Orientation in three-dimensional space */ - int32_t headphone; /* Set to TRUE if headphones are plugged in, FALSE otherwise */ - Vec3D mag; /* Magnetometer data */ - uint8_t volume; /* 0 to 255 */ - uint8_t battery; /* 0 to 6 */ - uint8_t mic; /* Microphone status */ - uint8_t unk_volume; /* One less than volume */ - uint8_t paddings[7]; -} VPADData; - -void InitVPadFunctionPointers(void); -void InitAcquireVPad(void); - -extern void (* VPADInit)(void); -extern void (* VPADShutdown)(void); -extern int32_t (* VPADRead)(int32_t chan, VPADData *buffer, uint32_t buffer_size, int32_t *error); -extern void (* VPADSetAccParam)(int32_t chan, float play_radius, float sensitivity); -extern void (* VPADGetAccParam)(int32_t chan, float *play_radius, float *sensitivity); -extern void (* VPADSetBtnRepeat)(int32_t chan, float delay_sec, float pulse_sec); -extern void (* VPADEnableStickCrossClamp)(int32_t chan); -extern void (* VPADDisableStickCrossClamp)(int32_t chan); -extern void (* VPADSetLStickClampThreshold)(int32_t chan, int32_t max, int32_t min); -extern void (* VPADSetRStickClampThreshold)(int32_t chan, int32_t max, int32_t min); -extern void (* VPADGetLStickClampThreshold)(int32_t chan, int32_t* max, int32_t* min); -extern void (* VPADGetRStickClampThreshold)(int32_t chan, int32_t* max, int32_t* min); -extern void (* VPADSetStickOrigin)(int32_t chan); -extern void (* VPADDisableLStickZeroClamp)(int32_t chan); -extern void (* VPADDisableRStickZeroClamp)(int32_t chan); -extern void (* VPADEnableLStickZeroClamp)(int32_t chan); -extern void (* VPADEnableRStickZeroClamp)(int32_t chan); -extern void (* VPADSetCrossStickEmulationParamsL)(int32_t chan, float rot_deg, float xy_deg, float radius); -extern void (* VPADSetCrossStickEmulationParamsR)(int32_t chan, float rot_deg, float xy_deg, float radius); -extern void (* VPADGetCrossStickEmulationParamsL)(int32_t chan, float* rot_deg, float* xy_deg, float* radius); -extern void (* VPADGetCrossStickEmulationParamsR)(int32_t chan, float* rot_deg, float* xy_deg, float* radius); -extern void (* VPADSetGyroAngle)(int32_t chan, float ax, float ay, float az); -extern void (* VPADSetGyroDirection)(int32_t chan, VPADDir *dir); -extern void (* VPADSetGyroDirectionMag)(int32_t chan, float mag); -extern void (* VPADSetGyroMagnification)(int32_t chan, float pitch, float yaw, float roll); -extern void (* VPADEnableGyroZeroPlay)(int32_t chan); -extern void (* VPADEnableGyroDirRevise)(int32_t chan); -extern void (* VPADEnableGyroAccRevise)(int32_t chan); -extern void (* VPADDisableGyroZeroPlay)(int32_t chan); -extern void (* VPADDisableGyroDirRevise)(int32_t chan); -extern void (* VPADDisableGyroAccRevise)(int32_t chan); -extern float (* VPADIsEnableGyroZeroPlay)(int32_t chan); -extern float (* VPADIsEnableGyroZeroDrift)(int32_t chan); -extern float (* VPADIsEnableGyroDirRevise)(int32_t chan); -extern float (* VPADIsEnableGyroAccRevise)(int32_t chan); -extern void (* VPADSetGyroZeroPlayParam)(int32_t chan, float radius); -extern void (* VPADSetGyroDirReviseParam)(int32_t chan, float revis_pw); -extern void (* VPADSetGyroAccReviseParam)(int32_t chan, float revise_pw, float revise_range); -extern void (* VPADSetGyroDirReviseBase)(int32_t chan, VPADDir *base); -extern void (* VPADGetGyroZeroPlayParam)(int32_t chan, float *radius); -extern void (* VPADGetGyroDirReviseParam)(int32_t chan, float *revise_pw); -extern void (* VPADGetGyroAccReviseParam)(int32_t chan, float *revise_pw, float *revise_range); -extern void (* VPADInitGyroZeroPlayParam)(int32_t chan); -extern void (* VPADInitGyroDirReviseParam)(int32_t chan); -extern void (* VPADInitGyroAccReviseParam)(int32_t chan); -extern void (* VPADInitGyroZeroDriftMode)(int32_t chan); -extern void (* VPADSetGyroZeroDriftMode)(int32_t chan, VPADGyroZeroDriftMode mode); -extern void (* VPADGetGyroZeroDriftMode)(int32_t chan, VPADGyroZeroDriftMode *mode); -extern int16_t (* VPADCalcTPCalibrationParam)(VPADTPCalibrationParam* param, uint16_t rawX1, uint16_t rawY1, uint16_t x1, uint16_t y1, uint16_t rawX2, uint16_t rawY2, uint16_t x2, uint16_t y2); -extern void (* VPADSetTPCalibrationParam)(int32_t chan, const VPADTPCalibrationParam param); -extern void (* VPADGetTPCalibrationParam)(int32_t chan, VPADTPCalibrationParam* param); -extern void (* VPADGetTPCalibratedPoint)(int32_t chan, VPADTPData *disp, const VPADTPData *raw); -extern void (* VPADGetTPCalibratedPointEx)(int32_t chan, VPADTPResolution tpReso, VPADTPData *disp, const VPADTPData *raw); -extern int32_t (* VPADControlMotor)(int32_t chan, uint8_t* pattern, uint8_t length); -extern void (* VPADStopMotor)(int32_t chan); -extern int32_t (* VPADSetLcdMode)(int32_t chan, int32_t lcdmode); -extern int32_t (* VPADGetLcdMode)(int32_t chan, int32_t *lcdmode); -extern int32_t (* VPADBASEGetMotorOnRemainingCount)(int32_t lcdmode); -extern int32_t (* VPADBASESetMotorOnRemainingCount)(int32_t lcdmode, int32_t counter); -extern void (* VPADBASESetSensorBarSetting)(int32_t chan, char setting); -extern void (* VPADBASEGetSensorBarSetting)(int32_t chan, char *setting); -extern int32_t (*VPADSetSensorBar)(int32_t chan, int32_t on); - -typedef void(*samplingCallback)(int32_t chan); -extern samplingCallback ( *VPADSetSamplingCallback)(int32_t chan, samplingCallback callback); - - -#ifdef __cplusplus -} -#endif - -#endif // __VPAD_FUNCTIONS_H_ diff --git a/src/entry.cpp b/src/entry.cpp deleted file mode 100644 index d672f8e..0000000 --- a/src/entry.cpp +++ /dev/null @@ -1,276 +0,0 @@ -#include -#include -#include "dynamic_libs/coreinit.h" -#include "dynamic_libs/socket_functions.h" -#include "dynamic_libs/fs_functions.h" -#include "dynamic_libs/gx2_functions.h" -#include "dynamic_libs/vpad_functions.h" -#include "kernel/kernel_utils.h" -#include "memory/memory_mapping.h" -#include "memory/memory.h" -#include "utils/ConfigUtils.h" -#include "utils/function_patcher.h" -#include "utils/logger.h" -#include "utils/mem_utils.h" -#include "utils/ipc.h" -#include "utils.h" -#include "system/CThread.h" -#include "common/retain_vars.h" -#include "plugin/PluginLoader.h" -#include "plugin/DynamicLinkingHelper.h" - -#include - -#include "patcher/function_patcher.h" -#include "patcher/hooks_patcher.h" -#include "patcher/hooks_patcher_static.h" - -int SplashScreen(int32_t time,const char * message,uint8_t pos,uint32_t button) { - //Call the Screen initilzation function. - OSScreenInit(); - - - int result = 0; - // Prepare screen - int32_t screen_buf0_size = 0; - - // Init screen and screen buffers - OSScreenInit(); - screen_buf0_size = OSScreenGetBufferSizeEx(0); - OSScreenSetBufferEx(0, (void *)0xF4000000); - OSScreenSetBufferEx(1, (void *)(0xF4000000 + screen_buf0_size)); - - OSScreenEnableEx(0, 1); - OSScreenEnableEx(1, 1); - - // Clear screens - OSScreenClearBufferEx(0, 0); - OSScreenClearBufferEx(1, 0); - - // Flip buffers - OSScreenFlipBuffersEx(0); - OSScreenFlipBuffersEx(1); - - OSScreenPutFontEx(0, 0, pos, message); - OSScreenPutFontEx(1, 0, pos, message); - - OSScreenFlipBuffersEx(0); - OSScreenFlipBuffersEx(1); - - int32_t tickswait = time * 1000*1000; - int32_t times = 1000; - int32_t sleepingtime = tickswait / 1000; - int32_t i=0; - - void(*OSSleepTicks)(uint64_t x); - OSDynLoad_FindExport(coreinit_handle, 0, "OSSleepTicks", &OSSleepTicks); - - while(i=0; plugin_index--) { - new_RestoreInvidualInstructions(&gbl_replacement_data.plugin_data[plugin_index]); - } - RestoreInvidualInstructions(method_hooks_hooks, method_hooks_size_hooks); - RestoreInvidualInstructions(method_hooks_hooks_static, method_hooks_size_hooks_static); -} - -void RestoreEverything() { - CallHook(WUPS_LOADER_HOOK_RELEASE_FOREGROUND); - CallHook(WUPS_LOADER_HOOK_APPLICATION_END); - CallHook(WUPS_LOADER_HOOK_DEINIT_PLUGIN); - - CallHook(WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB); - CallHook(WUPS_LOADER_HOOK_FINI_WUT_STDCPP); - CallHook(WUPS_LOADER_HOOK_FINI_WUT_NEWLIB); - CallHook(WUPS_LOADER_HOOK_FINI_WUT_MALLOC); - - // Restore patches as the patched functions could change. - RestorePatches(); - DynamicLinkingHelper::getInstance()->clearAll(); - gInBackground = false; -} - - -void ResolveRelocations() { - std::vector relocations = DynamicLinkingHelper::getInstance()->getAllValidDynamicLinkingRelocations(); - DEBUG_FUNCTION_LINE("Found relocation information for %d functions\n",relocations.size()); - - if(!DynamicLinkingHelper::getInstance()->fillRelocations(relocations)) { - OSFatal("fillRelocations failed."); - } -} - -void clearBSS(){ - for(int32_t plugin_index=0; plugin_indexbssAddr != 0){ - DEBUG_FUNCTION_LINE("Clearing .bss section for %s. Addr: %08X size: %08X\n", curData->plugin_name, curData->bssAddr, curData->bssSize); - memset((void*)curData->bssAddr, 0, curData->bssSize); - } - if(curData->bssAddr != 0){ - DEBUG_FUNCTION_LINE("Clearin .sbss section for %s. Addr: %08X size: %08X\n", curData->plugin_name, curData->sbssAddr, curData->sbssSize); - memset((void*)curData->sbssAddr, 0, curData->sbssSize); - } - } -} - -void afterLoadAndLink() { - ResolveRelocations(); - - CallHook(WUPS_LOADER_HOOK_INIT_WUT_MALLOC); - CallHook(WUPS_LOADER_HOOK_INIT_WUT_NEWLIB); - CallHook(WUPS_LOADER_HOOK_INIT_WUT_STDCPP); - - CallHook(WUPS_LOADER_HOOK_INIT_VID_MEM); - CallHook(WUPS_LOADER_HOOK_INIT_KERNEL); - CallHook(WUPS_LOADER_HOOK_INIT_OVERLAY); - ConfigUtils::loadConfigFromSD(); - CallHook(WUPS_LOADER_HOOK_INIT_PLUGIN); -} - -extern "C" void doStart(int argc, char **argv); -// We need to wrap it to make sure the main function is called AFTER our code. -// The compiler tries to optimize this otherwise and calling the main function earlier -extern "C" int _start(int argc, char **argv) { - doStart(argc,argv); - return ( (int (*)(int, char **))(*(unsigned int*)0x1005E040) )(argc, argv); -} - -extern "C" void doStart(int argc, char **argv) { - coreinit_handle = 0; - InitOSFunctionPointers(); - - if(gInBackground) { - CallHook(WUPS_LOADER_HOOK_APPLET_START); - return; - } - - gInBackground = true; - - coreinit_handle = 0; - InitOSFunctionPointers(); - InitSocketFunctionPointers(); - InitFSFunctionPointers(); - InitVPadFunctionPointers(); - InitGX2FunctionPointers(); - - // is called once. - kernelInitialize(); - - gGameTitleID = OSGetTitleID(); - - memset(&tv_store,0,sizeof(tv_store)); - memset(&drc_store,0,sizeof(drc_store)); - - log_init(); - - if(!MemoryMapping::isMemoryMapped()) { - MemoryMapping::setupMemoryMapping(); - memset((void*)&gbl_replacement_data,0,sizeof(gbl_replacement_data)); - DCFlushRange((void*)&gbl_replacement_data,sizeof(gbl_replacement_data)); - ICInvalidateRange((void*)&gbl_replacement_data,sizeof(gbl_replacement_data)); - - memset((void*)&gbl_dyn_linking_data,0,sizeof(gbl_dyn_linking_data)); - DCFlushRange((void*)&gbl_dyn_linking_data,sizeof(gbl_dyn_linking_data)); - ICInvalidateRange((void*)&gbl_dyn_linking_data,sizeof(gbl_dyn_linking_data)); - - // Switch to custom heap - //Does not work =( - //initMemory(); - //SplashScreen(1, "Memory mapping was completed!", 0,0); - - memset(gbl_to_link_and_load_data,0, sizeof(gbl_to_link_and_load_data)); - - // Init space - DynamicLinkingHelper::getInstance()->clearAll(); - - // Init IPC - uint32_t* ipcFunction = (uint32_t*)(MEMORY_START_PLUGIN_SPACE); - *ipcFunction = (uint32_t) &ipc_ioctl; - DCFlushRange(ipcFunction,4); - ICInvalidateRange(ipcFunction,4); - - // Do patches so memory mapping works fine with some functions. - PatchInvidualMethodHooks(method_hooks_hooks_static, method_hooks_size_hooks_static, method_calls_hooks_static); - - // mount sd card. - mount_sd_fat("sd"); - - DEBUG_FUNCTION_LINE("Mounted SD\n"); - - PluginLoader * pluginLoader = new PluginLoader((void*)PLUGIN_LOCATION_START_ADDRESS, (void*)PLUGIN_LOCATION_END_ADDRESS); - std::vector pluginList = pluginLoader->getPluginInformation("sd:/wiiu/autoboot_plugins/"); - pluginLoader->loadAndLinkPlugins(pluginList); - pluginLoader->clearPluginInformation(pluginList); - delete pluginLoader; - clearBSS(); - afterLoadAndLink(); - } else { - DEBUG_FUNCTION_LINE("Mapping was already done\n"); - //unmount_sd_fat("sd"); - mount_sd_fat("sd"); - - //SplashScreen(5, "Memory mapping was already done!!", 0,0); - //readAndPrintSegmentRegister(NULL,NULL); - //MemoryMapping::writeTestValuesToMemory(); - //MemoryMapping::readTestValuesFromMemory(); - } - - clearBSS(); - - if(gbl_to_link_and_load_data[0].name[0] != 0) { - ResolveRelocations(); - CallHook(WUPS_LOADER_HOOK_DEINIT_PLUGIN); - - // Restore patches as the patched functions could change. - RestorePatches(); - DynamicLinkingHelper::getInstance()->clearAll(); - - PluginLoader * pluginLoader = new PluginLoader((void*)PLUGIN_LOCATION_START_ADDRESS, (void*)PLUGIN_LOCATION_END_ADDRESS); - std::vector pluginList; - for(int i = 0; gbl_to_link_and_load_data[i].name[0] != 0; i++) { - PluginInformation * info = PluginInformation::loadPluginInformation(gbl_to_link_and_load_data[i].name); - if(info != NULL) { - pluginList.push_back(info); - } - } - pluginLoader->loadAndLinkPlugins(pluginList); - pluginLoader->clearPluginInformation(pluginList); - delete pluginLoader; - clearBSS(); - afterLoadAndLink(); - memset(gbl_to_link_and_load_data,0, sizeof(gbl_to_link_and_load_data)); - } - - - - ResolveRelocations(); - - MemoryUtils::init(); - - DEBUG_FUNCTION_LINE("Apply patches.\n"); - ApplyPatchesAndCallHookStartingApp(); - DEBUG_FUNCTION_LINE("Patches applied. Running application.\n"); - -} diff --git a/src/fs/CFile.cpp b/src/fs/CFile.cpp deleted file mode 100644 index eefae16..0000000 --- a/src/fs/CFile.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#include -#include -#include -#include "CFile.hpp" - -CFile::CFile() { - iFd = -1; - mem_file = NULL; - filesize = 0; - pos = 0; -} - -CFile::CFile(const std::string & filepath, eOpenTypes mode) { - iFd = -1; - this->open(filepath, mode); -} - -CFile::CFile(const uint8_t * mem, int32_t size) { - iFd = -1; - this->open(mem, size); -} - -CFile::~CFile() { - this->close(); -} - -int32_t CFile::open(const std::string & filepath, eOpenTypes mode) { - this->close(); - - int32_t openMode = 0; - - switch(mode) { - default: - case ReadOnly: - openMode = O_RDONLY; - break; - case WriteOnly: - openMode = O_WRONLY; - break; - case ReadWrite: - openMode = O_RDWR; - break; - case Append: - openMode = O_APPEND | O_WRONLY; - break; - } - - //! Using fopen works only on the first launch as expected - //! on the second launch it causes issues because we don't overwrite - //! the .data sections which is needed for a normal application to re-init - //! this will be added with launching as RPX - iFd = ::open(filepath.c_str(), openMode); - if(iFd < 0) - return iFd; - - - filesize = ::lseek(iFd, 0, SEEK_END); - ::lseek(iFd, 0, SEEK_SET); - - return 0; -} - -int32_t CFile::open(const uint8_t * mem, int32_t size) { - this->close(); - - mem_file = mem; - filesize = size; - - return 0; -} - -void CFile::close() { - if(iFd >= 0) - ::close(iFd); - - iFd = -1; - mem_file = NULL; - filesize = 0; - pos = 0; -} - -int32_t CFile::read(uint8_t * ptr, size_t size) { - if(iFd >= 0) { - int32_t ret = ::read(iFd, ptr,size); - if(ret > 0) - pos += ret; - return ret; - } - - int32_t readsize = size; - - if(readsize > (int64_t) (filesize-pos)) - readsize = filesize-pos; - - if(readsize <= 0) - return readsize; - - if(mem_file != NULL) { - memcpy(ptr, mem_file+pos, readsize); - pos += readsize; - return readsize; - } - - return -1; -} - -int32_t CFile::write(const uint8_t * ptr, size_t size) { - if(iFd >= 0) { - size_t done = 0; - while(done < size) { - int32_t ret = ::write(iFd, ptr, size - done); - if(ret <= 0) - return ret; - - ptr += ret; - done += ret; - pos += ret; - } - return done; - } - - return -1; -} - -int32_t CFile::seek(long int offset, int32_t origin) { - int32_t ret = 0; - int64_t newPos = pos; - - if(origin == SEEK_SET) { - newPos = offset; - } else if(origin == SEEK_CUR) { - newPos += offset; - } else if(origin == SEEK_END) { - newPos = filesize+offset; - } - - if(newPos < 0) { - pos = 0; - } else { - pos = newPos; - } - - if(iFd >= 0) - ret = ::lseek(iFd, pos, SEEK_SET); - - if(mem_file != NULL) { - if(pos > filesize) { - pos = filesize; - } - } - - return ret; -} - -int32_t CFile::fwrite(const char *format, ...) { - int32_t result = -1; - char * tmp = NULL; - - va_list va; - va_start(va, format); - if((vasprintf(&tmp, format, va) >= 0) && tmp) { - result = this->write((uint8_t *)tmp, strlen(tmp)); - } - va_end(va); - - if(tmp) { - free(tmp); - tmp = NULL; - } - - return result; -} - - diff --git a/src/fs/CFile.hpp b/src/fs/CFile.hpp deleted file mode 100644 index 6aadcb3..0000000 --- a/src/fs/CFile.hpp +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef CFILE_HPP_ -#define CFILE_HPP_ - -#include -#include -#include -#include -#include -#include - -class CFile { -public: - enum eOpenTypes { - ReadOnly, - WriteOnly, - ReadWrite, - Append - }; - - CFile(); - CFile(const std::string & filepath, eOpenTypes mode); - CFile(const uint8_t * memory, int32_t memsize); - virtual ~CFile(); - - int32_t open(const std::string & filepath, eOpenTypes mode); - int32_t open(const uint8_t * memory, int32_t memsize); - - bool isOpen() const { - if(iFd >= 0) - return true; - - if(mem_file) - return true; - - return false; - } - - void close(); - - int32_t read(uint8_t * ptr, size_t size); - int32_t write(const uint8_t * ptr, size_t size); - int32_t fwrite(const char *format, ...); - int32_t seek(long int offset, int32_t origin); - uint64_t tell() { - return pos; - }; - uint64_t size() { - return filesize; - }; - void rewind() { - this->seek(0, SEEK_SET); - }; - -protected: - int32_t iFd; - const uint8_t * mem_file; - uint64_t filesize; - uint64_t pos; -}; - -#endif diff --git a/src/fs/DirList.cpp b/src/fs/DirList.cpp deleted file mode 100644 index dd41237..0000000 --- a/src/fs/DirList.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2010 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - * - * DirList Class - * for WiiXplorer 2010 - ***************************************************************************/ -#include -#include -#include -#include -#include -#include -#include - -#include "DirList.h" -#include "utils/StringTools.h" - -DirList::DirList() { - Flags = 0; - Filter = 0; - Depth = 0; -} - -DirList::DirList(const std::string & path, const char *filter, uint32_t flags, uint32_t maxDepth) { - this->LoadPath(path, filter, flags, maxDepth); - this->SortList(); -} - -DirList::~DirList() { - ClearList(); -} - -bool DirList::LoadPath(const std::string & folder, const char *filter, uint32_t flags, uint32_t maxDepth) { - if(folder.empty()) return false; - - Flags = flags; - Filter = filter; - Depth = maxDepth; - - std::string folderpath(folder); - uint32_t length = folderpath.size(); - - //! clear path of double slashes - StringTools::RemoveDoubleSlashs(folderpath); - - //! remove last slash if exists - if(length > 0 && folderpath[length-1] == '/') - folderpath.erase(length-1); - - //! add root slash if missing - if(folderpath.find('/') == std::string::npos) { - folderpath += '/'; - } - - return InternalLoadPath(folderpath); -} - -bool DirList::InternalLoadPath(std::string &folderpath) { - if(folderpath.size() < 3) - return false; - - struct dirent *dirent = NULL; - DIR *dir = NULL; - - dir = opendir(folderpath.c_str()); - if (dir == NULL) - return false; - - while ((dirent = readdir(dir)) != 0) { - bool isDir = dirent->d_type & DT_DIR; - const char *filename = dirent->d_name; - - if(isDir) { - if(strcmp(filename,".") == 0 || strcmp(filename,"..") == 0) - continue; - - if((Flags & CheckSubfolders) && (Depth > 0)) { - int32_t length = folderpath.size(); - if(length > 2 && folderpath[length-1] != '/') { - folderpath += '/'; - } - folderpath += filename; - - Depth--; - InternalLoadPath(folderpath); - folderpath.erase(length); - Depth++; - } - - if(!(Flags & Dirs)) - continue; - } else if(!(Flags & Files)) { - continue; - } - - if(Filter) { - char * fileext = strrchr(filename, '.'); - if(!fileext) - continue; - - if(StringTools::strtokcmp(fileext, Filter, ",") == 0) - AddEntrie(folderpath, filename, isDir); - } else { - AddEntrie(folderpath, filename, isDir); - } - } - closedir(dir); - - return true; -} - -void DirList::AddEntrie(const std::string &filepath, const char * filename, bool isDir) { - if(!filename) - return; - - int32_t pos = FileInfo.size(); - - FileInfo.resize(pos+1); - - FileInfo[pos].FilePath = (char *) malloc(filepath.size()+strlen(filename)+2); - if(!FileInfo[pos].FilePath) { - FileInfo.resize(pos); - return; - } - - sprintf(FileInfo[pos].FilePath, "%s/%s", filepath.c_str(), filename); - FileInfo[pos].isDir = isDir; -} - -void DirList::ClearList() { - for(uint32_t i = 0; i < FileInfo.size(); ++i) { - if(FileInfo[i].FilePath) { - free(FileInfo[i].FilePath); - FileInfo[i].FilePath = NULL; - } - } - - FileInfo.clear(); - std::vector().swap(FileInfo); -} - -const char * DirList::GetFilename(int32_t ind) const { - if (!valid(ind)) - return ""; - - return StringTools::FullpathToFilename(FileInfo[ind].FilePath); -} - -static bool SortCallback(const DirEntry & f1, const DirEntry & f2) { - if(f1.isDir && !(f2.isDir)) return true; - if(!(f1.isDir) && f2.isDir) return false; - - if(f1.FilePath && !f2.FilePath) return true; - if(!f1.FilePath) return false; - - if(strcasecmp(f1.FilePath, f2.FilePath) > 0) - return false; - - return true; -} - -void DirList::SortList() { - if(FileInfo.size() > 1) - std::sort(FileInfo.begin(), FileInfo.end(), SortCallback); -} - -void DirList::SortList(bool (*SortFunc)(const DirEntry &a, const DirEntry &b)) { - if(FileInfo.size() > 1) - std::sort(FileInfo.begin(), FileInfo.end(), SortFunc); -} - -uint64_t DirList::GetFilesize(int32_t index) const { - struct stat st; - const char *path = GetFilepath(index); - - if(!path || stat(path, &st) != 0) - return 0; - - return st.st_size; -} - -int32_t DirList::GetFileIndex(const char *filename) const { - if(!filename) - return -1; - - for (uint32_t i = 0; i < FileInfo.size(); ++i) { - if (strcasecmp(GetFilename(i), filename) == 0) - return i; - } - - return -1; -} diff --git a/src/fs/DirList.h b/src/fs/DirList.h deleted file mode 100644 index 5c575e0..0000000 --- a/src/fs/DirList.h +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2010 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - * - * DirList Class - * for WiiXplorer 2010 - ***************************************************************************/ -#ifndef ___DIRLIST_H_ -#define ___DIRLIST_H_ - -#include -#include -#include - -typedef struct { - char * FilePath; - bool isDir; -} DirEntry; - -class DirList { -public: - //!Constructor - DirList(void); - //!\param path Path from where to load the filelist of all files - //!\param filter A fileext that needs to be filtered - //!\param flags search/filter flags from the enum - DirList(const std::string & path, const char *filter = NULL, uint32_t flags = Files | Dirs, uint32_t maxDepth = 0xffffffff); - //!Destructor - virtual ~DirList(); - //! Load all the files from a directory - bool LoadPath(const std::string & path, const char *filter = NULL, uint32_t flags = Files | Dirs, uint32_t maxDepth = 0xffffffff); - //! Get a filename of the list - //!\param list index - const char * GetFilename(int32_t index) const; - //! Get the a filepath of the list - //!\param list index - const char *GetFilepath(int32_t index) const { - if (!valid(index)) return ""; - else return FileInfo[index].FilePath; - } - //! Get the a filesize of the list - //!\param list index - uint64_t GetFilesize(int32_t index) const; - //! Is index a dir or a file - //!\param list index - bool IsDir(int32_t index) const { - if(!valid(index)) return false; - return FileInfo[index].isDir; - }; - //! Get the filecount of the whole list - int32_t GetFilecount() const { - return FileInfo.size(); - }; - //! Sort list by filepath - void SortList(); - //! Custom sort command for custom sort functions definitions - void SortList(bool (*SortFunc)(const DirEntry &a, const DirEntry &b)); - //! Get the index of the specified filename - int32_t GetFileIndex(const char *filename) const; - //! Enum for search/filter flags - enum { - Files = 0x01, - Dirs = 0x02, - CheckSubfolders = 0x08, - }; -protected: - // Internal parser - bool InternalLoadPath(std::string &path); - //!Add a list entrie - void AddEntrie(const std::string &filepath, const char * filename, bool isDir); - //! Clear the list - void ClearList(); - //! Check if valid pos is requested - inline bool valid(uint32_t pos) const { - return (pos < FileInfo.size()); - }; - - uint32_t Flags; - uint32_t Depth; - const char *Filter; - std::vector FileInfo; -}; - -#endif diff --git a/src/fs/FSOSUtils.cpp b/src/fs/FSOSUtils.cpp deleted file mode 100644 index fad7cea..0000000 --- a/src/fs/FSOSUtils.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include -#include -#include -#include "FSOSUtils.h" -#include "dynamic_libs/coreinit.h" -#include "dynamic_libs/fs_defs.h" -#include "dynamic_libs/fs_functions.h" -#include "utils/logger.h" - -int32_t FSOSUtils::MountFS(void *pClient, void *pCmd, char **mount_path) { - InitOSFunctionPointers(); - int32_t result = -1; - - void *mountSrc = ((void * (*)(size_t))(*pMEMAllocFromDefaultHeap))(FS_MOUNT_SOURCE_SIZE); - if(!mountSrc) { - return -3; - } - - char* mountPath = (char*) ((void * (*)(size_t))(*pMEMAllocFromDefaultHeap))(FS_MAX_MOUNTPATH_SIZE); - if(!mountPath) { - free(mountSrc); - mountSrc = NULL; - return -4; - } - - memset(mountSrc, 0, FS_MOUNT_SOURCE_SIZE); - memset(mountPath, 0, FS_MAX_MOUNTPATH_SIZE); - // Mount sdcard - if (FSGetMountSource(pClient, pCmd, FS_SOURCETYPE_EXTERNAL, mountSrc, -1) == 0) { - result = FSMount(pClient, pCmd, mountSrc, mountPath, FS_MAX_MOUNTPATH_SIZE, -1); - if((result == 0) && mount_path) { - *mount_path = (char*)malloc(strlen(mountPath) + 1); - if(*mount_path) - strcpy(*mount_path, mountPath); - } - } - DEBUG_FUNCTION_LINE(".\n"); - ((void (*)(void *))(*pMEMFreeToDefaultHeap))(mountPath); - ((void (*)(void *))(*pMEMFreeToDefaultHeap))(mountSrc); - //free(mountPath); - //free(mountSrc); - - mountPath = NULL; - mountSrc = NULL; - - return result; -} - -int32_t FSOSUtils::UmountFS(void *pClient, void *pCmd, const char *mountPath) { - int32_t result = -1; - result = FSUnmount(pClient, pCmd, mountPath, -1); - - return result; -} diff --git a/src/fs/FSOSUtils.h b/src/fs/FSOSUtils.h deleted file mode 100644 index aa14912..0000000 --- a/src/fs/FSOSUtils.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __FS_OS_UTILS_H_ -#define __FS_OS_UTILS_H_ - -#include - -class FSOSUtils { -public: - - static int32_t MountFS(void *pClient, void *pCmd, char **mount_path); - static int32_t UmountFS(void *pClient, void *pCmd, const char *mountPath); -}; - -#endif // __FS_OS_UTILS_H_ diff --git a/src/fs/FSUtils.cpp b/src/fs/FSUtils.cpp deleted file mode 100644 index 0506ecf..0000000 --- a/src/fs/FSUtils.cpp +++ /dev/null @@ -1,144 +0,0 @@ -#include -#include -#include -#include -#include -#include "FSUtils.h" -#include "CFile.hpp" -#include "utils/logger.h" - -int32_t FSUtils::LoadFileToMem(const char *filepath, uint8_t **inbuffer, uint32_t *size) { - //! always initialze input - *inbuffer = NULL; - if(size) - *size = 0; - - int32_t iFd = open(filepath, O_RDONLY); - if (iFd < 0) - return -1; - - uint32_t filesize = lseek(iFd, 0, SEEK_END); - lseek(iFd, 0, SEEK_SET); - - uint8_t *buffer = (uint8_t *) malloc(filesize); - if (buffer == NULL) { - close(iFd); - return -2; - } - - uint32_t blocksize = 0x4000; - uint32_t done = 0; - int32_t readBytes = 0; - - while(done < filesize) { - if(done + blocksize > filesize) { - blocksize = filesize - done; - } - readBytes = read(iFd, buffer + done, blocksize); - if(readBytes <= 0) - break; - done += readBytes; - } - - close(iFd); - - if (done != filesize) { - free(buffer); - buffer = NULL; - return -3; - } - - *inbuffer = buffer; - - //! sign is optional input - if(size) { - *size = filesize; - } - - return filesize; -} - -int32_t FSUtils::CheckFile(const char * filepath) { - if(!filepath) - return 0; - - struct stat filestat; - - char dirnoslash[strlen(filepath)+2]; - snprintf(dirnoslash, sizeof(dirnoslash), "%s", filepath); - - while(dirnoslash[strlen(dirnoslash)-1] == '/') - dirnoslash[strlen(dirnoslash)-1] = '\0'; - - char * notRoot = strrchr(dirnoslash, '/'); - if(!notRoot) { - strcat(dirnoslash, "/"); - } - - if (stat(dirnoslash, &filestat) == 0) - return 1; - - return 0; -} - -int32_t FSUtils::CreateSubfolder(const char * fullpath) { - if(!fullpath) - return 0; - - int32_t result = 0; - - char dirnoslash[strlen(fullpath)+1]; - strcpy(dirnoslash, fullpath); - - int32_t pos = strlen(dirnoslash)-1; - while(dirnoslash[pos] == '/') { - dirnoslash[pos] = '\0'; - pos--; - } - - if(CheckFile(dirnoslash)) { - return 1; - } else { - char parentpath[strlen(dirnoslash)+2]; - strcpy(parentpath, dirnoslash); - char * ptr = strrchr(parentpath, '/'); - - if(!ptr) { - //!Device root directory (must be with '/') - strcat(parentpath, "/"); - struct stat filestat; - if (stat(parentpath, &filestat) == 0) - return 1; - - return 0; - } - - ptr++; - ptr[0] = '\0'; - - result = CreateSubfolder(parentpath); - } - - if(!result) - return 0; - - if (mkdir(dirnoslash, 0777) == -1) { - return 0; - } - - return 1; -} - -bool FSUtils::saveBufferToFile(const char * path, void * buffer, uint32_t size) { - int32_t res = open(path, O_CREAT | O_TRUNC | O_WRONLY); - close(res); - CFile file(path, CFile::WriteOnly); - if (!file.isOpen()) { - DEBUG_FUNCTION_LINE("Failed to open %s\n",path); - return false; - } - file.write((const uint8_t*) buffer,size); - file.close(); - return true; -} - diff --git a/src/fs/FSUtils.h b/src/fs/FSUtils.h deleted file mode 100644 index 51299db..0000000 --- a/src/fs/FSUtils.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __FS_UTILS_H_ -#define __FS_UTILS_H_ -#include - -class FSUtils { -public: - static int32_t LoadFileToMem(const char *filepath, uint8_t **inbuffer, uint32_t *size); - - //! todo: C++ class - static int32_t CreateSubfolder(const char * fullpath); - static int32_t CheckFile(const char * filepath); - static bool saveBufferToFile(const char * path, void * buffer, uint32_t size); -}; - -#endif // __FS_UTILS_H_ diff --git a/src/fs/disc_io.h b/src/fs/disc_io.h deleted file mode 100644 index fff9401..0000000 --- a/src/fs/disc_io.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - disc_io.h - Interface template for low level disc functions. - - Copyright (c) 2006 Michael "Chishm" Chisholm - Based on code originally written by MightyMax - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef OGC_DISC_IO_INCLUDE -#define OGC_DISC_IO_INCLUDE - -#include - - -#define FEATURE_MEDIUM_CANREAD 0x00000001 -#define FEATURE_MEDIUM_CANWRITE 0x00000002 -#define FEATURE_GAMECUBE_SLOTA 0x00000010 -#define FEATURE_GAMECUBE_SLOTB 0x00000020 -#define FEATURE_GAMECUBE_DVD 0x00000040 -#define FEATURE_WII_SD 0x00000100 -#define FEATURE_WII_USB 0x00000200 -#define FEATURE_WII_DVD 0x00000400 - -typedef uint32_t sec_t; - -typedef bool (* FN_MEDIUM_STARTUP)(void) ; -typedef bool (* FN_MEDIUM_ISINSERTED)(void) ; -typedef bool (* FN_MEDIUM_READSECTORS)(sec_t sector, sec_t numSectors, void* buffer) ; -typedef bool (* FN_MEDIUM_WRITESECTORS)(sec_t sector, sec_t numSectors, const void* buffer) ; -typedef bool (* FN_MEDIUM_CLEARSTATUS)(void) ; -typedef bool (* FN_MEDIUM_SHUTDOWN)(void) ; - -struct DISC_INTERFACE_STRUCT { - unsigned long ioType ; - unsigned long features ; - FN_MEDIUM_STARTUP startup ; - FN_MEDIUM_ISINSERTED isInserted ; - FN_MEDIUM_READSECTORS readSectors ; - FN_MEDIUM_WRITESECTORS writeSectors ; - FN_MEDIUM_CLEARSTATUS clearStatus ; - FN_MEDIUM_SHUTDOWN shutdown ; -} ; - -typedef struct DISC_INTERFACE_STRUCT DISC_INTERFACE ; - -#endif // define OGC_DISC_IO_INCLUDE diff --git a/src/fs/sd_fat_devoptab.cpp b/src/fs/sd_fat_devoptab.cpp deleted file mode 100644 index 0a114f0..0000000 --- a/src/fs/sd_fat_devoptab.cpp +++ /dev/null @@ -1,1035 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "disc_io.h" -#include "FSOSUtils.h" -#include "sd_fat_devoptab.h" -#include "utils/StringTools.h" -#include "utils/logger.h" - -#define FS_ALIGNMENT 0x40 -#define FS_ALIGN(x) (((x) + FS_ALIGNMENT - 1) & ~(FS_ALIGNMENT - 1)) - -#define mymalloc(x) ((void * (*)(size_t))(*pMEMAllocFromDefaultHeap))(x) -#define myfree(x) ((void (*)(void *))(*pMEMFreeToDefaultHeap))(x) - -typedef struct _sd_fat_private_t { - char *mount_path; - void *pClient; - void *pCmd; - void *pMutex; -} sd_fat_private_t; - -typedef struct _sd_fat_file_state_t { - sd_fat_private_t *dev; - int fd; /* File descriptor */ - int flags; /* Opening flags */ - bool read; /* True if allowed to read from file */ - bool write; /* True if allowed to write to file */ - bool append; /* True if allowed to append to file */ - uint64_t pos; /* Current position within the file (in bytes) */ - uint64_t len; /* Total length of the file (in bytes) */ - struct _sd_fat_file_state_t *prevOpenFile; /* The previous entry in a double-linked FILO list of open files */ - struct _sd_fat_file_state_t *nextOpenFile; /* The next entry in a double-linked FILO list of open files */ -} sd_fat_file_state_t; - -typedef struct _sd_fat_dir_entry_t { - sd_fat_private_t *dev; - int dirHandle; -} sd_fat_dir_entry_t; - -static sd_fat_private_t *sd_fat_get_device_data(const char *path) { - const devoptab_t *devoptab = NULL; - char name[128] = {0}; - int i; - - // Get the device name from the path - strncpy(name, path, 127); - strtok(name, ":/"); - - // Search the devoptab table for the specified device name - // NOTE: We do this manually due to a 'bug' in GetDeviceOpTab - // which ignores names with suffixes and causes names - // like "ntfs" and "ntfs1" to be seen as equals - for (i = 3; i < STD_MAX; i++) { - devoptab = devoptab_list[i]; - if (devoptab && devoptab->name) { - if (strcmp(name, devoptab->name) == 0) { - return (sd_fat_private_t *)devoptab->deviceData; - } - } - } - - return NULL; -} - -static char *sd_fat_real_path (const char *path, sd_fat_private_t *dev) { - // Sanity check - if (!path) - return NULL; - - // Move the path pointer to the start of the actual path - if (strchr(path, ':') != NULL) { - path = strchr(path, ':') + 1; - } - - int mount_len = strlen(dev->mount_path); - - char *new_name = (char*)malloc(mount_len + strlen(path) + 1); - if(new_name) { - strcpy(new_name, dev->mount_path); - strcpy(new_name + mount_len, path); - return new_name; - } - return new_name; -} - -static int sd_fat_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode) { - sd_fat_private_t *dev = sd_fat_get_device_data(path); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fileStruct; - - file->dev = dev; - // Determine which mode the file is opened for - file->flags = flags; - - const char *mode_str; - - if ((flags & 0x03) == O_RDONLY) { - file->read = true; - file->write = false; - file->append = false; - mode_str = "r"; - } else if ((flags & 0x03) == O_WRONLY) { - file->read = false; - file->write = true; - file->append = (flags & O_APPEND); - mode_str = file->append ? "a" : "w"; - } else if ((flags & 0x03) == O_RDWR) { - file->read = true; - file->write = true; - file->append = (flags & O_APPEND); - mode_str = file->append ? "a+" : "r+"; - } else { - r->_errno = EACCES; - return -1; - } - - int32_t fd = -1; - - OSLockMutex(dev->pMutex); - - char *real_path = sd_fat_real_path(path, dev); - if(!path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - int result = FSOpenFile(dev->pClient, dev->pCmd, real_path, mode_str, &fd, -1); - - free(real_path); - - if(result == 0) { - FSStat stats; - result = FSGetStatFile(dev->pClient, dev->pCmd, fd, &stats, -1); - if(result != 0) { - FSCloseFile(dev->pClient, dev->pCmd, fd, -1); - r->_errno = result; - OSUnlockMutex(dev->pMutex); - return -1; - } - file->fd = fd; - file->pos = 0; - file->len = stats.size; - OSUnlockMutex(dev->pMutex); - return (int)file; - } - - r->_errno = result; - OSUnlockMutex(dev->pMutex); - return -1; -} - - -static int sd_fat_close_r (struct _reent *r, void *fd) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(file->dev->pMutex); - - int result = FSCloseFile(file->dev->pClient, file->dev->pCmd, file->fd, -1); - - OSUnlockMutex(file->dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - return 0; -} - -static off_t sd_fat_seek_r (struct _reent *r, void* fd, off_t pos, int dir) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return 0; - } - - OSLockMutex(file->dev->pMutex); - - switch(dir) { - case SEEK_SET: - file->pos = pos; - break; - case SEEK_CUR: - file->pos += pos; - break; - case SEEK_END: - file->pos = file->len + pos; - break; - default: - r->_errno = EINVAL; - return -1; - } - - int result = FSSetPosFile(file->dev->pClient, file->dev->pCmd, file->fd, file->pos, -1); - - OSUnlockMutex(file->dev->pMutex); - - if(result == 0) { - return file->pos; - } - - return result; -} - -static ssize_t sd_fat_write_r (struct _reent *r, void *fd, const char *ptr, size_t len) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return 0; - } - - if(!file->write) { - r->_errno = EACCES; - return 0; - } - - OSLockMutex(file->dev->pMutex); - - size_t len_aligned = FS_ALIGN(len); - if(len_aligned > 0x4000) - len_aligned = 0x4000; - - unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned); - if(!tmpBuf) { - r->_errno = ENOMEM; - OSUnlockMutex(file->dev->pMutex); - return 0; - } - - size_t done = 0; - - while(done < len) { - size_t write_size = (len_aligned < (len - done)) ? len_aligned : (len - done); - memcpy(tmpBuf, ptr + done, write_size); - - int result = FSWriteFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, write_size, file->fd, 0, -1); - if(result < 0) { - r->_errno = result; - break; - } else if(result == 0) { - if(write_size > 0) - done = 0; - break; - } else { - done += result; - file->pos += result; - } - } - - free(tmpBuf); - OSUnlockMutex(file->dev->pMutex); - return done; -} - -static ssize_t sd_fat_read_r (struct _reent *r, void* fd, char *ptr, size_t len) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return 0; - } - - if(!file->read) { - r->_errno = EACCES; - return 0; - } - - OSLockMutex(file->dev->pMutex); - - size_t len_aligned = FS_ALIGN(len); - if(len_aligned > 0x4000) - len_aligned = 0x4000; - - unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned); - if(!tmpBuf) { - r->_errno = ENOMEM; - OSUnlockMutex(file->dev->pMutex); - return 0; - } - - size_t done = 0; - - while(done < len) { - size_t read_size = (len_aligned < (len - done)) ? len_aligned : (len - done); - - int result = FSReadFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, read_size, file->fd, 0, -1); - if(result < 0) { - r->_errno = result; - done = 0; - break; - } else if(result == 0) { - //! TODO: error on read_size > 0 - break; - } else { - memcpy(ptr + done, tmpBuf, read_size); - done += result; - file->pos += result; - } - } - - free(tmpBuf); - OSUnlockMutex(file->dev->pMutex); - return done; -} - - -static int sd_fat_fstat_r (struct _reent *r, void* fd, struct stat *st) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(file->dev->pMutex); - - // Zero out the stat buffer - memset(st, 0, sizeof(struct stat)); - - FSStat stats; - int result = FSGetStatFile(file->dev->pClient, file->dev->pCmd, file->fd, &stats, -1); - if(result != 0) { - r->_errno = result; - OSUnlockMutex(file->dev->pMutex); - return -1; - } - - st->st_mode = S_IFREG; - st->st_size = stats.size; - st->st_blocks = (stats.size + 511) >> 9; - st->st_nlink = 1; - - // Fill in the generic entry stats - st->st_dev = stats.ent_id; - st->st_uid = stats.owner_id; - st->st_gid = stats.group_id; - st->st_ino = stats.ent_id; - st->st_atime = stats.mtime; - st->st_ctime = stats.ctime; - st->st_mtime = stats.mtime; - OSUnlockMutex(file->dev->pMutex); - return 0; -} - -static int sd_fat_ftruncate_r (struct _reent *r, void* fd, off_t len) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(file->dev->pMutex); - - int result = FSTruncateFile(file->dev->pClient, file->dev->pCmd, file->fd, -1); - - OSUnlockMutex(file->dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; -} - -static int sd_fat_fsync_r (struct _reent *r, void* fd) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(file->dev->pMutex); - - int result = FSFlushFile(file->dev->pClient, file->dev->pCmd, file->fd, -1); - - OSUnlockMutex(file->dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; -} - -static int sd_fat_stat_r (struct _reent *r, const char *path, struct stat *st) { - sd_fat_private_t *dev = sd_fat_get_device_data(path); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - // Zero out the stat buffer - memset(st, 0, sizeof(struct stat)); - - char *real_path = sd_fat_real_path(path, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - FSStat stats; - - int result = FSGetStat(dev->pClient, dev->pCmd, real_path, &stats, -1); - - free(real_path); - - if(result < 0) { - r->_errno = result; - OSUnlockMutex(dev->pMutex); - return -1; - } - - // mark root also as directory - st->st_mode = ((stats.flag & 0x80000000) || (strlen(dev->mount_path) + 1 == strlen(real_path)))? S_IFDIR : S_IFREG; - st->st_nlink = 1; - st->st_size = stats.size; - st->st_blocks = (stats.size + 511) >> 9; - // Fill in the generic entry stats - st->st_dev = stats.ent_id; - st->st_uid = stats.owner_id; - st->st_gid = stats.group_id; - st->st_ino = stats.ent_id; - st->st_atime = stats.mtime; - st->st_ctime = stats.ctime; - st->st_mtime = stats.mtime; - - OSUnlockMutex(dev->pMutex); - - return 0; -} - -static int sd_fat_link_r (struct _reent *r, const char *existing, const char *newLink) { - r->_errno = ENOTSUP; - return -1; -} - -static int sd_fat_unlink_r (struct _reent *r, const char *name) { - sd_fat_private_t *dev = sd_fat_get_device_data(name); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_path = sd_fat_real_path(name, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - - int result = FSRemove(dev->pClient, dev->pCmd, real_path, -1); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; -} - -static int sd_fat_chdir_r (struct _reent *r, const char *name) { - sd_fat_private_t *dev = sd_fat_get_device_data(name); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_path = sd_fat_real_path(name, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - int result = FSChangeDir(dev->pClient, dev->pCmd, real_path, -1); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; -} - -static int sd_fat_rename_r (struct _reent *r, const char *oldName, const char *newName) { - sd_fat_private_t *dev = sd_fat_get_device_data(oldName); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_oldpath = sd_fat_real_path(oldName, dev); - if(!real_oldpath) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - char *real_newpath = sd_fat_real_path(newName, dev); - if(!real_newpath) { - r->_errno = ENOMEM; - free(real_oldpath); - OSUnlockMutex(dev->pMutex); - return -1; - } - - int result = FSRename(dev->pClient, dev->pCmd, real_oldpath, real_newpath, -1); - - free(real_oldpath); - free(real_newpath); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; - -} - -static int sd_fat_mkdir_r (struct _reent *r, const char *path, int mode) { - sd_fat_private_t *dev = sd_fat_get_device_data(path); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_path = sd_fat_real_path(path, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - int result = FSMakeDir(dev->pClient, dev->pCmd, real_path, -1); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; -} - -static int sd_fat_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf) { - sd_fat_private_t *dev = sd_fat_get_device_data(path); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - // Zero out the stat buffer - memset(buf, 0, sizeof(struct statvfs)); - - char *real_path = sd_fat_real_path(path, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - uint64_t size; - - int result = FSGetFreeSpaceSize(dev->pClient, dev->pCmd, real_path, &size, -1); - - free(real_path); - - if(result < 0) { - r->_errno = result; - OSUnlockMutex(dev->pMutex); - return -1; - } - - // File system block size - buf->f_bsize = 512; - - // Fundamental file system block size - buf->f_frsize = 512; - - // Total number of blocks on file system in units of f_frsize - buf->f_blocks = size >> 9; // this is unknown - - // Free blocks available for all and for non-privileged processes - buf->f_bfree = buf->f_bavail = size >> 9; - - // Number of inodes at this point in time - buf->f_files = 0xffffffff; - - // Free inodes available for all and for non-privileged processes - buf->f_ffree = 0xffffffff; - - // File system id - buf->f_fsid = (int)dev; - - // Bit mask of f_flag values. - buf->f_flag = 0; - - // Maximum length of filenames - buf->f_namemax = 255; - - OSUnlockMutex(dev->pMutex); - - return 0; -} - -static DIR_ITER *sd_fat_diropen_r (struct _reent *r, DIR_ITER *dirState, const char *path) { - sd_fat_private_t *dev = sd_fat_get_device_data(path); - if(!dev) { - r->_errno = ENODEV; - return NULL; - } - - sd_fat_dir_entry_t *dirIter = (sd_fat_dir_entry_t *)dirState->dirStruct; - - OSLockMutex(dev->pMutex); - - char *real_path = sd_fat_real_path(path, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return NULL; - } - - int32_t dirHandle; - - int result = FSOpenDir(dev->pClient, dev->pCmd, real_path, &dirHandle, -1); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return NULL; - } - - dirIter->dev = dev; - dirIter->dirHandle = dirHandle; - - return dirState; -} - -static int sd_fat_dirclose_r (struct _reent *r, DIR_ITER *dirState) { - sd_fat_dir_entry_t *dirIter = (sd_fat_dir_entry_t *)dirState->dirStruct; - if(!dirIter->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dirIter->dev->pMutex); - - int result = FSCloseDir(dirIter->dev->pClient, dirIter->dev->pCmd, dirIter->dirHandle, -1); - - OSUnlockMutex(dirIter->dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - return 0; -} - -static int sd_fat_dirreset_r (struct _reent *r, DIR_ITER *dirState) { - sd_fat_dir_entry_t *dirIter = (sd_fat_dir_entry_t *)dirState->dirStruct; - if(!dirIter->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dirIter->dev->pMutex); - - int result = FSRewindDir(dirIter->dev->pClient, dirIter->dev->pCmd, dirIter->dirHandle, -1); - - OSUnlockMutex(dirIter->dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - return 0; -} - -static int sd_fat_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *st) { - sd_fat_dir_entry_t *dirIter = (sd_fat_dir_entry_t *)dirState->dirStruct; - if(!dirIter->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dirIter->dev->pMutex); - - FSDirEntry * dir_entry = (FSDirEntry *)mymalloc(sizeof(FSDirEntry)); - - int result = FSReadDir(dirIter->dev->pClient, dirIter->dev->pCmd, dirIter->dirHandle, dir_entry, -1); - if(result < 0) { - myfree(dir_entry); - r->_errno = result; - OSUnlockMutex(dirIter->dev->pMutex); - return -1; - } - - // Fetch the current entry - strcpy(filename, dir_entry->name); - - if(st) { - memset(st, 0, sizeof(struct stat)); - st->st_mode = (dir_entry->stat.flag & 0x80000000) ? S_IFDIR : S_IFREG; - st->st_nlink = 1; - st->st_size = dir_entry->stat.size; - st->st_blocks = (dir_entry->stat.size + 511) >> 9; - st->st_dev = dir_entry->stat.ent_id; - st->st_uid = dir_entry->stat.owner_id; - st->st_gid = dir_entry->stat.group_id; - st->st_ino = dir_entry->stat.ent_id; - st->st_atime = dir_entry->stat.mtime; - st->st_ctime = dir_entry->stat.ctime; - st->st_mtime = dir_entry->stat.mtime; - } - - myfree(dir_entry); - OSUnlockMutex(dirIter->dev->pMutex); - return 0; -} - -// SD device driver devoptab -static const devoptab_t devops_sd_fat = { - NULL, /* Device name */ - sizeof (sd_fat_file_state_t), - sd_fat_open_r, - sd_fat_close_r, - sd_fat_write_r, - sd_fat_read_r, - sd_fat_seek_r, - sd_fat_fstat_r, - sd_fat_stat_r, - sd_fat_link_r, - sd_fat_unlink_r, - sd_fat_chdir_r, - sd_fat_rename_r, - sd_fat_mkdir_r, - sizeof (sd_fat_dir_entry_t), - sd_fat_diropen_r, - sd_fat_dirreset_r, - sd_fat_dirnext_r, - sd_fat_dirclose_r, - sd_fat_statvfs_r, - sd_fat_ftruncate_r, - sd_fat_fsync_r, - NULL, /* Device data */ - NULL, /* sd_fat_chmod_r */ - NULL, /* sd_fat_fchmod_r */ - NULL /* sd_fat_rmdir_r */ -}; - - -static int sd_fat_add_device (const char *name, const char *mount_path, void *pClient, void *pCmd) { - devoptab_t *dev = NULL; - char *devname = NULL; - char *devpath = NULL; - int i; - - - - // Sanity check - if (!name) { - - errno = EINVAL; - return -1; - } - - // Allocate a devoptab for this device - dev = (devoptab_t *) malloc(sizeof(devoptab_t) + strlen(name) + 1); - if (!dev) { - - errno = ENOMEM; - return -1; - } - - // Use the space allocated at the end of the devoptab for storing the device name - devname = (char*)(dev + 1); - - strcpy(devname, name); - - - // create private data - int mount_path_len = 0; - if(mount_path != NULL) { - - mount_path_len = strlen(mount_path); - } - sd_fat_private_t *priv = (sd_fat_private_t *)malloc(sizeof(sd_fat_private_t) + mount_path_len + 1); - if(!priv) { - - free(dev); - errno = ENOMEM; - return -1; - } - - devpath = (char*)(priv+1); - if(mount_path != NULL) { - - strcpy(devpath, mount_path); - } - - // setup private data - priv->mount_path = devpath; - priv->pClient = pClient; - priv->pCmd = pCmd; - priv->pMutex = mymalloc(OS_MUTEX_SIZE); - - if(!priv->pMutex) { - - free(dev); - free(priv); - errno = ENOMEM; - return -1; - } - - - OSInitMutex(priv->pMutex); - - // Setup the devoptab - memcpy(dev, &devops_sd_fat, sizeof(devoptab_t)); - dev->name = devname; - dev->deviceData = priv; - - - // Add the device to the devoptab table (if there is a free slot) - for (i = 3; i < STD_MAX; i++) { - if (devoptab_list[i] == devoptab_list[0]) { - devoptab_list[i] = dev; - return 0; - } - } - - - - // failure, free all memory - free(priv); - free(dev); - - // If we reach here then there are no free slots in the devoptab table for this device - errno = EADDRNOTAVAIL; - return -1; -} - -/* -Because of some weird reason unmounting doesn't work properly. -This fix if mainly when a usb drive is connected. -It resets the devoptab_list, otherwise mounting again would throw an exception (in strlen). -No memory is free'd here. Maybe a problem?!?!? -*/ - -void deleteDevTabsNames() { - const devoptab_t * devoptab = NULL; - uint32_t last_entry = (uint32_t) devoptab_list[STD_MAX-1]; - for (int i = 3; i < STD_MAX; i++) { - devoptab = devoptab_list[i]; - - if (devoptab) { - //log_printf("check devotab %d %08X\n",i,devoptab); - if((uint32_t) devoptab != last_entry) { - devoptab_list[i] = (const devoptab_t *)last_entry; - //log_printf("Removed devotab %d %08X %08X %08X\n",i,devoptab,devoptab->name,devoptab->deviceData); - } - } - } -} - -static int sd_fat_remove_device (const char *path, void **pClient, void **pCmd, char **mountPath) { - const devoptab_t *devoptab = NULL; - char name[128] = {0}; - int i; - - // Get the device name from the path - strncpy(name, path, 127); - strtok(name, ":/"); - - // Find and remove the specified device from the devoptab table - // NOTE: We do this manually due to a 'bug' in RemoveDevice - // which ignores names with suffixes and causes names - // like "ntfs" and "ntfs1" to be seen as equals - for (i = 3; i < STD_MAX; i++) { - devoptab = devoptab_list[i]; - if (devoptab && devoptab->name) { - if (strcmp(name, devoptab->name) == 0) { - devoptab_list[i] = devoptab_list[0]; - - if(devoptab->deviceData) { - sd_fat_private_t *priv = (sd_fat_private_t *)devoptab->deviceData; - if(pClient != NULL) - *pClient = priv->pClient; - if(pCmd != NULL) - *pCmd = priv->pCmd; - if(mountPath != NULL) { - *mountPath = (char*) malloc(strlen(priv->mount_path)+1); - if(*mountPath) - strcpy(*mountPath, priv->mount_path); - } - if(priv->pMutex) - myfree(priv->pMutex); - free(devoptab->deviceData); - } - - free((devoptab_t*)devoptab); - return 0; - } - } - } - - return -1; -} - -int32_t mount_sd_fat(const char *path) { - int result = -1; - - // get command and client - void* pClient = mymalloc(FS_CLIENT_SIZE); - void* pCmd = mymalloc(FS_CMD_BLOCK_SIZE); - - if(!pClient || !pCmd) { - // just in case free if not 0 - if(pClient) - myfree(pClient); - if(pCmd) - myfree(pCmd); - return -2; - } - - - FSInit(); - FSInitCmdBlock(pCmd); - FSAddClientEx(pClient, 0, -1); - - char *mountPath = NULL; - - if(FSOSUtils::MountFS(pClient, pCmd, &mountPath) == 0) { - result = sd_fat_add_device(path, mountPath, pClient, pCmd); - myfree(mountPath); - } - - return result; -} - -int32_t unmount_sd_fat(const char *path) { - void *pClient = 0; - void *pCmd = 0; - char *mountPath = 0; - - int result = sd_fat_remove_device(path, &pClient, &pCmd, &mountPath); - if(result == 0) { - FSOSUtils::UmountFS(pClient, pCmd, mountPath); - FSDelClient(pClient); - myfree(pClient); - myfree(pCmd); - myfree(mountPath); - //FSShutdown(); - } - return result; -} - -int32_t mount_fake() { - return sd_fat_add_device("fake", NULL, NULL, NULL); -} - -int32_t unmount_fake() { - return sd_fat_remove_device ("fake", NULL,NULL,NULL); -} diff --git a/src/fs/sd_fat_devoptab.h b/src/fs/sd_fat_devoptab.h deleted file mode 100644 index 88a1c04..0000000 --- a/src/fs/sd_fat_devoptab.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#ifndef __SD_FAT_DEVOPTAB_H_ -#define __SD_FAT_DEVOPTAB_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -int32_t mount_sd_fat(const char *path); -int32_t unmount_sd_fat(const char *path); -int32_t mount_fake(); -int32_t unmount_fake(); -void deleteDevTabsNames(); -#ifdef __cplusplus -} -#endif - -#endif // __SD_FAT_DEVOPTAB_H_ diff --git a/src/kernel/kernel_utils.c b/src/kernel/kernel_utils.c deleted file mode 100644 index 87abb1b..0000000 --- a/src/kernel/kernel_utils.c +++ /dev/null @@ -1,204 +0,0 @@ -#include "kernel_utils.h" -#include "kernel_defs.h" -#include "dynamic_libs/coreinit.h" - -#define KERN_SYSCALL_TBL1 0xFFE84C70 //Unknown -#define KERN_SYSCALL_TBL2 0xFFE85070 //Games -#define KERN_SYSCALL_TBL3 0xFFE85470 //Loader -#define KERN_SYSCALL_TBL4 0xFFEAAA60 //Home menu -#define KERN_SYSCALL_TBL5 0xFFEAAE60 //Browser - -extern void SCKernelCopyData(uint32_t dst, uint32_t src, uint32_t len); - -static void KernelReadSRs(sr_table_t * table) { - uint32_t i = 0; - - // calculate PT_size ((end-start)*8/4096)*4 or (end-start)/128 - // Minimum page table size is 64Kbytes. - - asm volatile("eieio; isync"); - - asm volatile("mfspr %0, 25" : "=r" (table->sdr1)); - - asm volatile("mfsr %0, 0" : "=r" (table->value[i])); - i++; - asm volatile("mfsr %0, 1" : "=r" (table->value[i])); - i++; - asm volatile("mfsr %0, 2" : "=r" (table->value[i])); - i++; - asm volatile("mfsr %0, 3" : "=r" (table->value[i])); - i++; - asm volatile("mfsr %0, 4" : "=r" (table->value[i])); - i++; - asm volatile("mfsr %0, 5" : "=r" (table->value[i])); - i++; - asm volatile("mfsr %0, 6" : "=r" (table->value[i])); - i++; - asm volatile("mfsr %0, 7" : "=r" (table->value[i])); - i++; - asm volatile("mfsr %0, 8" : "=r" (table->value[i])); - i++; - asm volatile("mfsr %0, 9" : "=r" (table->value[i])); - i++; - asm volatile("mfsr %0, 10" : "=r" (table->value[i])); - i++; - asm volatile("mfsr %0, 11" : "=r" (table->value[i])); - i++; - asm volatile("mfsr %0, 12" : "=r" (table->value[i])); - i++; - asm volatile("mfsr %0, 13" : "=r" (table->value[i])); - i++; - asm volatile("mfsr %0, 14" : "=r" (table->value[i])); - i++; - asm volatile("mfsr %0, 15" : "=r" (table->value[i])); - i++; - - asm volatile("eieio; isync"); -} - -static void KernelWriteSRs(sr_table_t * table) { - uint32_t i = 0; - - asm volatile("eieio; isync"); - - // Writing didn't work for all at once so we only write number 8. - // TODO: fix this and change it if required. - - /*asm volatile("mtsr 0, %0" : : "r" (table->value[i])); i++; - asm volatile("mtsr 1, %0" : : "r" (table->value[i])); i++; - asm volatile("mtsr 2, %0" : : "r" (table->value[i])); i++; - asm volatile("mtsr 3, %0" : : "r" (table->value[i])); i++; - asm volatile("mtsr 4, %0" : : "r" (table->value[i])); i++; - asm volatile("mtsr 5, %0" : : "r" (table->value[i])); i++;*/ - //asm volatile("mtsr 6, %0" : : "r" (table->value[6])); i++; - /*asm volatile("mtsr 7, %0" : : "r" (table->value[i])); i++;*/ - asm volatile("mtsr 8, %0" : : "r" (table->value[8])); - //i++; - /*asm volatile("mtsr 9, %0" : : "r" (table->value[i])); i++; - asm volatile("mtsr 10, %0" : : "r" (table->value[i])); i++; - asm volatile("mtsr 11, %0" : : "r" (table->value[i])); i++; - asm volatile("mtsr 12, %0" : : "r" (table->value[i])); i++; - asm volatile("mtsr 13, %0" : : "r" (table->value[i])); i++; - asm volatile("mtsr 14, %0" : : "r" (table->value[i])); i++; - asm volatile("mtsr 15, %0" : : "r" (table->value[i])); i++;*/ - - - asm volatile("isync"); -} - -void KernelWrite(uint32_t addr, const void *data, uint32_t length) { - uint32_t dst = (uint32_t) OSEffectiveToPhysical(addr); - uint32_t src = (uint32_t) OSEffectiveToPhysical((uint32_t)data); - KernelCopyData(dst, src, length); - DCFlushRange((void *)addr, length); - ICInvalidateRange((void *)addr, length); -} - -void KernelWriteU32(uint32_t addr, uint32_t value) { - uint32_t dst = (uint32_t) OSEffectiveToPhysical(addr); - uint32_t src = (uint32_t) OSEffectiveToPhysical((uint32_t)&value); - KernelCopyData(dst, src, 4); - DCFlushRange((void *)addr, 4); - ICInvalidateRange((void *)addr, 4); -} - -/* Write a 32-bit word with kernel permissions */ -void __attribute__ ((noinline)) kern_write(void * addr, uint32_t value) { - asm volatile ( - "li 3,1\n" - "li 4,0\n" - "mr 5,%1\n" - "li 6,0\n" - "li 7,0\n" - "lis 8,1\n" - "mr 9,%0\n" - "mr %1,1\n" - "li 0,0x3500\n" - "sc\n" - "nop\n" - "mr 1,%1\n" - : - : "r"(addr), "r"(value) - : "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10", - "11", "12" - ); -} - -/* Read a 32-bit word with kernel permissions */ -uint32_t __attribute__ ((noinline)) kern_read(const void *addr) -{ - uint32_t result; - asm volatile ( - "li 3,1\n" - "li 4,0\n" - "li 5,0\n" - "li 6,0\n" - "li 7,0\n" - "lis 8,1\n" - "mr 9,%1\n" - "li 0,0x3400\n" - "mr %0,1\n" - "sc\n" - "nop\n" - "mr 1,%0\n" - "mr %0,3\n" - : "=r"(result) - : "b"(addr) - : "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10", - "11", "12" - ); - - return result; -} - -void PatchSyscall(int index, uint32_t addr) { - //DEBUG_FUNCTION_LINE("Patching Syscall 0x%02X\n",index); - kern_write((void *) (KERN_SYSCALL_TBL1 + index * 4), addr); - kern_write((void *) (KERN_SYSCALL_TBL2 + index * 4), addr); - kern_write((void *) (KERN_SYSCALL_TBL3 + index * 4), addr); - kern_write((void *) (KERN_SYSCALL_TBL4 + index * 4), addr); - kern_write((void *) (KERN_SYSCALL_TBL5 + index * 4), addr); -} - -void KernelReadPTE(uint32_t outputAddr, int32_t length) { - uint32_t dst = (uint32_t) OSEffectiveToPhysical(outputAddr); - uint32_t src = 0xFFE20000; - ICInvalidateRange(&dst, 4); - DCFlushRange(&dst, 4); - DCFlushRange(&src, 4); - KernelCopyData(dst, src, length); - DCFlushRange((void *)outputAddr, length); - ICInvalidateRange((void *)outputAddr, length); -} - -void KernelWritePTE(uint32_t inputAddr, int32_t length) { - uint32_t dst = 0xFFE20000; - uint32_t src = (uint32_t) OSEffectiveToPhysical(inputAddr); - ICInvalidateRange(&src, 4); - DCFlushRange(&src, 4); - KernelCopyData(dst, src, length); -} - -static void NOPAtPhysicalAddress(uint32_t addr) { - uint32_t dst = 0x60000000; - ICInvalidateRange(&dst, 4); - DCFlushRange(&dst, 4); - KernelCopyData(addr,(uint32_t)OSEffectiveToPhysical((uint32_t)&dst),4); -} - -void kernelInitialize() { - static uint8_t ucSyscallsSetupRequired = 1; - if(!ucSyscallsSetupRequired) - return; - - ucSyscallsSetupRequired = 0; - - PatchSyscall(0x25, (uint32_t)SCKernelCopyData); - PatchSyscall(0x36, (uint32_t)KernelReadSRs); - PatchSyscall(0x0A, (uint32_t)KernelWriteSRs); - - // Override all writes to SR8 with nops. - NOPAtPhysicalAddress(0xFFF1D754); - NOPAtPhysicalAddress(0xFFF1D64C); - NOPAtPhysicalAddress(0xFFE00638); -} diff --git a/src/kernel_hooks.S b/src/kernel_hooks.S deleted file mode 100644 index 8940727..0000000 --- a/src/kernel_hooks.S +++ /dev/null @@ -1,29 +0,0 @@ -# This stuff may need a change in different kernel versions -# This is only needed when launched directly through browser and not SD card. - -.section ".kernel_code" - .globl SaveAndResetDataBATs_And_SRs_hook -SaveAndResetDataBATs_And_SRs_hook: - # setup CTR to the position we need to return to - mflr r5 - mtctr r5 - # set link register to its original value - mtlr r7 - # setup us a nice DBAT for our code data with same region as our code - mfspr r5, 560 - mtspr 570, r5 - mfspr r5, 561 - mtspr 571, r5 - # restore the original kernel instructions that we replaced - lwz r5, 0x34(r3) - lwz r6, 0x38(r3) - lwz r7, 0x3C(r3) - lwz r8, 0x40(r3) - lwz r9, 0x44(r3) - lwz r10, 0x48(r3) - lwz r11, 0x4C(r3) - lwz r3, 0x50(r3) - isync - mtsr 7, r5 - # jump back to the position in kernel after our patch (from LR) - bctr \ No newline at end of file diff --git a/src/libelf/_elftc.h b/src/libelf/_elftc.h deleted file mode 100644 index 19a9720..0000000 --- a/src/libelf/_elftc.h +++ /dev/null @@ -1,430 +0,0 @@ -/*- - * Copyright (c) 2009 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: _elftc.h 2495 2012-04-23 05:31:56Z jkoshy $ - */ - -/** - ** Miscellanous definitions needed by multiple components. - **/ - -#ifndef _ELFTC_H -#define _ELFTC_H - -#ifndef NULL -#define NULL ((void *) 0) -#endif - -#ifndef offsetof -#define offsetof(T, M) ((int) &((T*) 0) -> M) -#endif - -/* --QUEUE-MACROS-- [[ */ - -/* - * Supply macros missing from - */ - -/* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef STAILQ_CONCAT -#define STAILQ_CONCAT(head1, head2) do { \ - if (!STAILQ_EMPTY((head2))) { \ - *(head1)->stqh_last = (head2)->stqh_first; \ - (head1)->stqh_last = (head2)->stqh_last; \ - STAILQ_INIT((head2)); \ - } \ -} while (/*CONSTCOND*/0) -#endif - -#ifndef STAILQ_EMPTY -#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) -#endif - -#ifndef STAILQ_ENTRY -#define STAILQ_ENTRY(type) \ -struct { \ - struct type *stqe_next; /* next element */ \ -} -#endif - -#ifndef STAILQ_FIRST -#define STAILQ_FIRST(head) ((head)->stqh_first) -#endif - -#ifndef STAILQ_HEAD -#define STAILQ_HEAD(name, type) \ -struct name { \ - struct type *stqh_first; /* first element */ \ - struct type **stqh_last; /* addr of last next element */ \ -} -#endif - -#ifndef STAILQ_HEAD_INITIALIZER -#define STAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).stqh_first } -#endif - -#ifndef STAILQ_FOREACH -#define STAILQ_FOREACH(var, head, field) \ - for ((var) = ((head)->stqh_first); \ - (var); \ - (var) = ((var)->field.stqe_next)) -#endif - -#ifndef STAILQ_FOREACH_SAFE -#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = STAILQ_FIRST((head)); \ - (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) -#endif - -#ifndef STAILQ_INIT -#define STAILQ_INIT(head) do { \ - (head)->stqh_first = NULL; \ - (head)->stqh_last = &(head)->stqh_first; \ -} while (/*CONSTCOND*/0) -#endif - -#ifndef STAILQ_INSERT_HEAD -#define STAILQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \ - (head)->stqh_last = &(elm)->field.stqe_next; \ - (head)->stqh_first = (elm); \ -} while (/*CONSTCOND*/0) -#endif - -#ifndef STAILQ_INSERT_TAIL -#define STAILQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.stqe_next = NULL; \ - *(head)->stqh_last = (elm); \ - (head)->stqh_last = &(elm)->field.stqe_next; \ -} while (/*CONSTCOND*/0) -#endif - -#ifndef STAILQ_INSERT_AFTER -#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\ - (head)->stqh_last = &(elm)->field.stqe_next; \ - (listelm)->field.stqe_next = (elm); \ -} while (/*CONSTCOND*/0) -#endif - -#ifndef STAILQ_LAST -#define STAILQ_LAST(head, type, field) \ - (STAILQ_EMPTY((head)) ? \ - NULL : ((struct type *)(void *) \ - ((char *)((head)->stqh_last) - offsetof(struct type, field)))) -#endif - -#ifndef STAILQ_NEXT -#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) -#endif - -#ifndef STAILQ_REMOVE -#define STAILQ_REMOVE(head, elm, type, field) do { \ - if ((head)->stqh_first == (elm)) { \ - STAILQ_REMOVE_HEAD((head), field); \ - } else { \ - struct type *curelm = (head)->stqh_first; \ - while (curelm->field.stqe_next != (elm)) \ - curelm = curelm->field.stqe_next; \ - if ((curelm->field.stqe_next = \ - curelm->field.stqe_next->field.stqe_next) == NULL) \ - (head)->stqh_last = &(curelm)->field.stqe_next; \ - } \ -} while (/*CONSTCOND*/0) -#endif - -#ifndef STAILQ_REMOVE_HEAD -#define STAILQ_REMOVE_HEAD(head, field) do { \ - if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == \ - NULL) \ - (head)->stqh_last = &(head)->stqh_first; \ -} while (/*CONSTCOND*/0) -#endif - -#ifndef TAILQ_FOREACH_SAFE -#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = TAILQ_FIRST((head)); \ - (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) -#endif - -/* ]] --QUEUE-MACROS-- */ - -/* - * VCS Ids. - */ - -#ifndef ELFTC_VCSID - -#if defined(GEKKO) -#define ELFTC_VCSID(ID) /**/ -#endif - -#if defined(__WIIU__) -#define ELFTC_VCSID(ID) /**/ -#endif - -#if defined(__DragonFly__) -#define ELFTC_VCSID(ID) __RCSID(ID) -#endif - -#if defined(__FreeBSD__) -#define ELFTC_VCSID(ID) __FBSDID(ID) -#endif - -#if defined(__linux__) || defined(__GNU__) || defined(__GLIBC__) -#if defined(__GNUC__) -#define ELFTC_VCSID(ID) __asm__(".ident\t\"" ID "\"") -#else -#define ELFTC_VCSID(ID) /**/ -#endif -#endif - -#if defined(__minix) -#if defined(__GNUC__) -#define ELFTC_VCSID(ID) __asm__(".ident\t\"" ID "\"") -#else -#define ELFTC_VCSID(ID) /**/ -#endif /* __GNU__ */ -#endif - -#if defined(__NetBSD__) -#define ELFTC_VCSID(ID) __RCSID(ID) -#endif - -#if defined(__OpenBSD__) -#if defined(__GNUC__) -#define ELFTC_VCSID(ID) __asm__(".ident\t\"" ID "\"") -#else -#define ELFTC_VCSID(ID) /**/ -#endif /* __GNUC__ */ -#endif - -#endif /* ELFTC_VCSID */ - -/* - * Provide an equivalent for getprogname(3). - */ - -#ifndef ELFTC_GETPROGNAME - -#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__minix) || \ - defined(__NetBSD__) - -#include - -#define ELFTC_GETPROGNAME() getprogname() - -#endif /* __DragonFly__ || __FreeBSD__ || __minix || __NetBSD__ */ - - -#if defined(__GLIBC__) - -/* - * GLIBC based systems have a global 'char *' pointer referencing - * the executable's name. - */ -extern const char *program_invocation_short_name; - -#define ELFTC_GETPROGNAME() program_invocation_short_name - -#endif /* __GLIBC__ */ - - -#if defined(__OpenBSD__) - -extern const char *__progname; - -#define ELFTC_GETPROGNAME() __progname - -#endif /* __OpenBSD__ */ - -#endif /* ELFTC_GETPROGNAME */ - - -/** - ** Per-OS configuration. - **/ - -#if defined(GEKKO) - -#include - -#define ELFTC_BYTE_ORDER BYTE_ORDER -#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN LITTLE_ENDIAN -#define ELFTC_BYTE_ORDER_BIG_ENDIAN BIG_ENDIAN - -#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) -#define roundup2 roundup - -#define ELFTC_HAVE_MMAP 0 -#define ELFTC_HAVE_STRMODE 0/ -#define ELFTC_NEED_BYTEORDER_EXTENSIONS 1 - -#endif - -#if defined(__WIIU__) - -#include - -#define ELFTC_BYTE_ORDER BYTE_ORDER -#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN LITTLE_ENDIAN -#define ELFTC_BYTE_ORDER_BIG_ENDIAN BIG_ENDIAN - -#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) -#define roundup2 roundup - -#define ELFTC_HAVE_MMAP 0 -#define ELFTC_HAVE_STRMODE 0/ -#define ELFTC_NEED_BYTEORDER_EXTENSIONS 1 - -#endif - - -#if defined(__DragonFly__) - -#include -#include - -#define ELFTC_BYTE_ORDER _BYTE_ORDER -#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN -#define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN - -#define ELFTC_HAVE_MMAP 1 - -#endif - -#if defined(__GLIBC__) - -#include - -#define ELFTC_BYTE_ORDER __BYTE_ORDER -#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN __LITTLE_ENDIAN -#define ELFTC_BYTE_ORDER_BIG_ENDIAN __BIG_ENDIAN - -#define ELFTC_HAVE_MMAP 1 - -/* - * Debian GNU/Linux and Debian GNU/kFreeBSD do not have strmode(3). - */ -#define ELFTC_HAVE_STRMODE 0 - -/* Whether we need to supply {be,le}32dec. */ -#define ELFTC_NEED_BYTEORDER_EXTENSIONS 1 - -#define roundup2 roundup - -#endif /* __GLIBC__ */ - - -#if defined(__FreeBSD__) - -#include -#include - -#define ELFTC_BYTE_ORDER _BYTE_ORDER -#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN -#define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN - -#define ELFTC_HAVE_MMAP 1 -#define ELFTC_HAVE_STRMODE 1 -#if __FreeBSD_version <= 900000 -#define ELFTC_BROKEN_YY_NO_INPUT 1 -#endif -#endif /* __FreeBSD__ */ - - -#if defined(__minix) -#define ELFTC_HAVE_MMAP 0 -#endif /* __minix */ - - -#if defined(__NetBSD__) - -#include -#include - -#define ELFTC_BYTE_ORDER _BYTE_ORDER -#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN -#define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN - -#define ELFTC_HAVE_MMAP 1 -#define ELFTC_HAVE_STRMODE 1 -#if __NetBSD_Version__ <= 599002100 -/* from src/doc/CHANGES: flex(1): Import flex-2.5.35 [christos 20091025] */ -/* and 5.99.21 was from Wed Oct 21 21:28:36 2009 UTC */ -# define ELFTC_BROKEN_YY_NO_INPUT 1 -#endif -#endif /* __NetBSD __ */ - - -#if defined(__OpenBSD__) - -#include -#include - -#define ELFTC_BYTE_ORDER _BYTE_ORDER -#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN -#define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN - -#define ELFTC_HAVE_MMAP 1 -#define ELFTC_HAVE_STRMODE 1 - -#define ELFTC_NEED_BYTEORDER_EXTENSIONS 1 -#define roundup2 roundup - -#endif /* __OpenBSD__ */ - -#endif /* _ELFTC_H */ diff --git a/src/libelf/_libelf.h b/src/libelf/_libelf.h deleted file mode 100644 index f8cfd01..0000000 --- a/src/libelf/_libelf.h +++ /dev/null @@ -1,223 +0,0 @@ -/*- - * Copyright (c) 2006,2008-2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: _libelf.h 2365 2011-12-29 04:36:44Z jkoshy $ - */ - -#ifndef __LIBELF_H_ -#define __LIBELF_H_ - -#include - -#include "_libelf_config.h" - -#include "_elftc.h" - -/* - * Library-private data structures. - */ - -#define LIBELF_MSG_SIZE 256 - -struct _libelf_globals { - int libelf_arch; - unsigned int libelf_byteorder; - int libelf_class; - int libelf_error; - int libelf_fillchar; - unsigned int libelf_version; - char libelf_msg[LIBELF_MSG_SIZE]; -}; - -extern struct _libelf_globals _libelf; - -#define LIBELF_PRIVATE(N) (_libelf.libelf_##N) - -#define LIBELF_ELF_ERROR_MASK 0xFF -#define LIBELF_OS_ERROR_SHIFT 8 - -#define LIBELF_ERROR(E, O) (((E) & LIBELF_ELF_ERROR_MASK) | \ - ((O) << LIBELF_OS_ERROR_SHIFT)) - -#define LIBELF_SET_ERROR(E, O) do { \ - LIBELF_PRIVATE(error) = LIBELF_ERROR(ELF_E_##E, (O)); \ - } while (0) - -#define LIBELF_ADJUST_AR_SIZE(S) (((S) + 1U) & ~1U) - -/* - * Flags for library internal use. These use the upper 16 bits of the - * `e_flags' field. - */ -#define LIBELF_F_API_MASK 0x00FFFF /* Flags defined by the API. */ -#define LIBELF_F_AR_HEADER 0x010000 /* translated header available */ -#define LIBELF_F_AR_VARIANT_SVR4 0x020000 /* BSD style ar(1) archive */ -#define LIBELF_F_DATA_MALLOCED 0x040000 /* whether data was malloc'ed */ -#define LIBELF_F_RAWFILE_MALLOC 0x080000 /* whether e_rawfile was malloc'ed */ -#define LIBELF_F_RAWFILE_MMAP 0x100000 /* whether e_rawfile was mmap'ed */ -#define LIBELF_F_SHDRS_LOADED 0x200000 /* whether all shdrs were read in */ -#define LIBELF_F_SPECIAL_FILE 0x400000 /* non-regular file */ - -struct _Elf { - int e_activations; /* activation count */ - unsigned int e_byteorder; /* ELFDATA* */ - int e_class; /* ELFCLASS* */ - Elf_Cmd e_cmd; /* ELF_C_* used at creation time */ - int e_fd; /* associated file descriptor */ - unsigned int e_flags; /* ELF_F_* & LIBELF_F_* flags */ - Elf_Kind e_kind; /* ELF_K_* */ - Elf *e_parent; /* non-NULL for archive members */ - char *e_rawfile; /* uninterpreted bytes */ - size_t e_rawsize; /* size of uninterpreted bytes */ - unsigned int e_version; /* file version */ - - /* - * Header information for archive members. See the - * LIBELF_F_AR_HEADER flag. - */ - union { - Elf_Arhdr *e_arhdr; /* translated header */ - char *e_rawhdr; /* untranslated header */ - } e_hdr; - - union { - struct { /* ar(1) archives */ - off_t e_next; /* set by elf_rand()/elf_next() */ - int e_nchildren; - char *e_rawstrtab; /* file name strings */ - size_t e_rawstrtabsz; - char *e_rawsymtab; /* symbol table */ - size_t e_rawsymtabsz; - Elf_Arsym *e_symtab; - size_t e_symtabsz; - } e_ar; - struct { /* regular ELF files */ - union { - Elf32_Ehdr *e_ehdr32; - Elf64_Ehdr *e_ehdr64; - } e_ehdr; - union { - Elf32_Phdr *e_phdr32; - Elf64_Phdr *e_phdr64; - } e_phdr; - STAILQ_HEAD(, _Elf_Scn) e_scn; /* section list */ - size_t e_nphdr; /* number of Phdr entries */ - size_t e_nscn; /* number of sections */ - size_t e_strndx; /* string table section index */ - } e_elf; - } e_u; -}; - -/* - * The internal descriptor wrapping the "Elf_Data" type. - */ -struct _Libelf_Data { - Elf_Data d_data; /* The exported descriptor. */ - Elf_Scn *d_scn; /* The containing section */ - unsigned int d_flags; - STAILQ_ENTRY(_Libelf_Data) d_next; -}; - -struct _Elf_Scn { - union { - Elf32_Shdr s_shdr32; - Elf64_Shdr s_shdr64; - } s_shdr; - STAILQ_HEAD(, _Libelf_Data) s_data; /* translated data */ - STAILQ_HEAD(, _Libelf_Data) s_rawdata; /* raw data */ - STAILQ_ENTRY(_Elf_Scn) s_next; - struct _Elf *s_elf; /* parent ELF descriptor */ - unsigned int s_flags; /* flags for the section as a whole */ - size_t s_ndx; /* index# for this section */ - uint64_t s_offset; /* managed by elf_update() */ - uint64_t s_rawoff; /* original offset in the file */ - uint64_t s_size; /* managed by elf_update() */ -}; - - -enum { - ELF_TOFILE, - ELF_TOMEMORY -}; - -#define LIBELF_COPY_U32(DST,SRC,NAME) do { \ - if ((SRC)->NAME > UINT_MAX) { \ - LIBELF_SET_ERROR(RANGE, 0); \ - return (0); \ - } \ - (DST)->NAME = (SRC)->NAME; \ - } while (0) - -#define LIBELF_COPY_S32(DST,SRC,NAME) do { \ - if ((SRC)->NAME > INT_MAX || \ - (SRC)->NAME < INT_MIN) { \ - LIBELF_SET_ERROR(RANGE, 0); \ - return (0); \ - } \ - (DST)->NAME = (SRC)->NAME; \ - } while (0) - - -/* - * Function Prototypes. - */ - -struct _Libelf_Data *_libelf_allocate_data(Elf_Scn *_s); -Elf *_libelf_allocate_elf(void); -Elf_Scn *_libelf_allocate_scn(Elf *_e, size_t _ndx); -Elf_Arhdr *_libelf_ar_gethdr(Elf *_e); -Elf *_libelf_ar_open(Elf *_e, int _reporterror); -Elf *_libelf_ar_open_member(int _fd, Elf_Cmd _c, Elf *_ar); -int _libelf_ar_get_member(char *_s, size_t _sz, int _base, size_t *_ret); -Elf_Arsym *_libelf_ar_process_bsd_symtab(Elf *_ar, size_t *_dst); -Elf_Arsym *_libelf_ar_process_svr4_symtab(Elf *_ar, size_t *_dst); -unsigned long _libelf_checksum(Elf *_e, int _elfclass); -void *_libelf_ehdr(Elf *_e, int _elfclass, int _allocate); -int _libelf_falign(Elf_Type _t, int _elfclass); -size_t _libelf_fsize(Elf_Type _t, int _elfclass, unsigned int _version, - size_t count); -int (*_libelf_get_translator(Elf_Type _t, int _direction, int _elfclass)) - (char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap); -void *_libelf_getphdr(Elf *_e, int _elfclass); -void *_libelf_getshdr(Elf_Scn *_scn, int _elfclass); -void _libelf_init_elf(Elf *_e, Elf_Kind _kind); -int _libelf_load_section_headers(Elf *e, void *ehdr); -int _libelf_malign(Elf_Type _t, int _elfclass); -Elf *_libelf_memory(char *_image, size_t _sz, int _reporterror); -size_t _libelf_msize(Elf_Type _t, int _elfclass, unsigned int _version); -void *_libelf_newphdr(Elf *_e, int _elfclass, size_t _count); -Elf *_libelf_open_object(int _fd, Elf_Cmd _c, int _reporterror); -struct _Libelf_Data *_libelf_release_data(struct _Libelf_Data *_d); -Elf *_libelf_release_elf(Elf *_e); -Elf_Scn *_libelf_release_scn(Elf_Scn *_s); -int _libelf_setphnum(Elf *_e, void *_eh, int _elfclass, size_t _phnum); -int _libelf_setshnum(Elf *_e, void *_eh, int _elfclass, size_t _shnum); -int _libelf_setshstrndx(Elf *_e, void *_eh, int _elfclass, - size_t _shstrndx); -Elf_Data *_libelf_xlate(Elf_Data *_d, const Elf_Data *_s, - unsigned int _encoding, int _elfclass, int _direction); -int _libelf_xlate_shtype(uint32_t _sht); - -#endif /* __LIBELF_H_ */ diff --git a/src/libelf/_libelf_ar.h b/src/libelf/_libelf_ar.h deleted file mode 100644 index d6b15a7..0000000 --- a/src/libelf/_libelf_ar.h +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * Copyright (c) 2010 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: _libelf_ar.h 2032 2011-10-23 09:07:00Z jkoshy $ - */ - -#ifndef __LIBELF_AR_H_ -#define __LIBELF_AR_H_ - -/* - * Prototypes and declarations needed by libelf's ar(1) archive - * handling code. - */ - -#include - -#define LIBELF_AR_BSD_EXTENDED_NAME_PREFIX "#1/" -#define LIBELF_AR_BSD_SYMTAB_NAME "__.SYMDEF" -#define LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE \ - (sizeof(LIBELF_AR_BSD_EXTENDED_NAME_PREFIX) - 1) - -#define IS_EXTENDED_BSD_NAME(NAME) \ - (strncmp((NAME), LIBELF_AR_BSD_EXTENDED_NAME_PREFIX, \ - LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE) == 0) - - -char *_libelf_ar_get_string(const char *_buf, size_t _sz, int _rawname, - int _svr4names); -char *_libelf_ar_get_raw_name(const struct ar_hdr *_arh); -char *_libelf_ar_get_translated_name(const struct ar_hdr *_arh, Elf *_ar); -int _libelf_ar_get_number(const char *_buf, size_t _sz, int _base, - size_t *_ret); - -#endif /* __LIBELF_AR_H_ */ diff --git a/src/libelf/_libelf_config.h b/src/libelf/_libelf_config.h deleted file mode 100644 index b18b30e..0000000 --- a/src/libelf/_libelf_config.h +++ /dev/null @@ -1,193 +0,0 @@ -/*- - * Copyright (c) 2008-2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: _libelf_config.h 2287 2011-12-04 06:45:47Z jkoshy $ - */ - -#ifdef GEKKO - -#define LIBELF_ARCH EM_PPC -#define LIBELF_BYTEORDER ELFDATA2MSB -#define LIBELF_CLASS ELFCLASS32 - -#endif /* GEKKO */ - -#ifdef __WIIU__ - -#define LIBELF_ARCH EM_PPC -#define LIBELF_BYTEORDER ELFDATA2MSB -#define LIBELF_CLASS ELFCLASS32 - -#endif /* __WIIU__ */ - -#ifdef __DragonFly__ - -#if defined(__amd64__) -#define LIBELF_ARCH EM_X86_64 -#define LIBELF_BYTEORDER ELFDATA2LSB -#define LIBELF_CLASS ELFCLASS64 -#elif defined(__i386__) -#define LIBELF_ARCH EM_386 -#define LIBELF_BYTEORDER ELFDATA2LSB -#define LIBELF_CLASS ELFCLASS32 -#endif - -#endif /* __DragonFly__ */ - -#ifdef __FreeBSD__ - -/* - * Define LIBELF_{ARCH,BYTEORDER,CLASS} based on the machine architecture. - * See also: . - */ - -#if defined(__amd64__) - -#define LIBELF_ARCH EM_X86_64 -#define LIBELF_BYTEORDER ELFDATA2LSB -#define LIBELF_CLASS ELFCLASS64 - -#elif defined(__arm__) - -#define LIBELF_ARCH EM_ARM -#if defined(__ARMEB__) /* Big-endian ARM. */ -#define LIBELF_BYTEORDER ELFDATA2MSB -#else -#define LIBELF_BYTEORDER ELFDATA2LSB -#endif -#define LIBELF_CLASS ELFCLASS32 - -#elif defined(__i386__) - -#define LIBELF_ARCH EM_386 -#define LIBELF_BYTEORDER ELFDATA2LSB -#define LIBELF_CLASS ELFCLASS32 - -#elif defined(__ia64__) - -#define LIBELF_ARCH EM_IA_64 -#define LIBELF_BYTEORDER ELFDATA2LSB -#define LIBELF_CLASS ELFCLASS64 - -#elif defined(__mips__) - -#define LIBELF_ARCH EM_MIPS -#if defined(__MIPSEB__) -#define LIBELF_BYTEORDER ELFDATA2MSB -#else -#define LIBELF_BYTEORDER ELFDATA2LSB -#endif -#define LIBELF_CLASS ELFCLASS32 - -#elif defined(__powerpc__) - -#define LIBELF_ARCH EM_PPC -#define LIBELF_BYTEORDER ELFDATA2MSB -#define LIBELF_CLASS ELFCLASS32 - -#elif defined(__sparc__) - -#define LIBELF_ARCH EM_SPARCV9 -#define LIBELF_BYTEORDER ELFDATA2MSB -#define LIBELF_CLASS ELFCLASS64 - -#else -#error Unknown FreeBSD architecture. -#endif -#endif /* __FreeBSD__ */ - -/* - * Definitions for Minix3. - */ -#ifdef __minix - -#define LIBELF_ARCH EM_386 -#define LIBELF_BYTEORDER ELFDATA2LSB -#define LIBELF_CLASS ELFCLASS32 - -#endif /* __minix */ - -#ifdef __NetBSD__ - -#include - -#if !defined(ARCH_ELFSIZE) -#error ARCH_ELFSIZE is not defined. -#endif - -#if ARCH_ELFSIZE == 32 -#define LIBELF_ARCH ELF32_MACHDEP_ID -#define LIBELF_BYTEORDER ELF32_MACHDEP_ENDIANNESS -#define LIBELF_CLASS ELFCLASS32 -#define Elf_Note Elf32_Nhdr -#else -#define LIBELF_ARCH ELF64_MACHDEP_ID -#define LIBELF_BYTEORDER ELF64_MACHDEP_ENDIANNESS -#define LIBELF_CLASS ELFCLASS64 -#define Elf_Note Elf64_Nhdr -#endif - -#endif /* __NetBSD__ */ - -#if defined(__OpenBSD__) - -#include - -#define LIBELF_ARCH ELF_TARG_MACH -#define LIBELF_BYTEORDER ELF_TARG_DATA -#define LIBELF_CLASS ELF_TARG_CLASS - -#endif - -/* - * GNU & Linux compatibility. - * - * `__linux__' is defined in an environment runs the Linux kernel and glibc. - * `__GNU__' is defined in an environment runs a GNU kernel (Hurd) and glibc. - * `__GLIBC__' is defined for an environment that runs glibc over a non-GNU - * kernel such as GNU/kFreeBSD. - */ - -#if defined(__linux__) || defined(__GNU__) || defined(__GLIBC__) - -#if defined(__linux__) - -#include "native-elf-format.h" - -#define LIBELF_CLASS ELFTC_CLASS -#define LIBELF_ARCH ELFTC_ARCH -#define LIBELF_BYTEORDER ELFTC_BYTEORDER - -#endif /* defined(__linux__) */ - -#if LIBELF_CLASS == ELFCLASS32 -#define Elf_Note Elf32_Nhdr -#elif LIBELF_CLASS == ELFCLASS64 -#define Elf_Note Elf64_Nhdr -#else -#error LIBELF_CLASS needs to be one of ELFCLASS32 or ELFCLASS64 -#endif - -#endif /* defined(__linux__) || defined(__GNU__) || defined(__GLIBC__) */ diff --git a/src/libelf/elf.c b/src/libelf/elf.c deleted file mode 100644 index 8f1925e..0000000 --- a/src/libelf/elf.c +++ /dev/null @@ -1,40 +0,0 @@ -/*- - * Copyright (c) 2006,2008,2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -struct _libelf_globals _libelf = { - .libelf_arch = LIBELF_ARCH, - .libelf_byteorder = LIBELF_BYTEORDER, - .libelf_class = LIBELF_CLASS, - .libelf_error = 0, - .libelf_fillchar = 0, - .libelf_version = EV_NONE -}; diff --git a/src/libelf/elf_begin.c b/src/libelf/elf_begin.c deleted file mode 100644 index 9f4f237..0000000 --- a/src/libelf/elf_begin.c +++ /dev/null @@ -1,91 +0,0 @@ -/*- - * Copyright (c) 2006,2008-2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_begin.c 2364 2011-12-28 17:55:25Z jkoshy $"); - -Elf * -elf_begin(int fd, Elf_Cmd c, Elf *a) -{ - Elf *e; - - e = NULL; - - if (LIBELF_PRIVATE(version) == EV_NONE) { - LIBELF_SET_ERROR(SEQUENCE, 0); - return (NULL); - } - - switch (c) { - case ELF_C_NULL: - return (NULL); - - case ELF_C_WRITE: - /* - * The ELF_C_WRITE command is required to ignore the - * descriptor passed in. - */ - a = NULL; - break; - - case ELF_C_RDWR: - if (a != NULL) { /* not allowed for ar(1) archives. */ - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - /*FALLTHROUGH*/ - case ELF_C_READ: - /* - * Descriptor `a' could be for a regular ELF file, or - * for an ar(1) archive. If descriptor `a' was opened - * using a valid file descriptor, we need to check if - * the passed in `fd' value matches the original one. - */ - if (a && - ((a->e_fd != -1 && a->e_fd != fd) || c != a->e_cmd)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - break; - - default: - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - - } - - if (a == NULL) - e = _libelf_open_object(fd, c, 1); - else if (a->e_kind == ELF_K_AR) - e = _libelf_ar_open_member(a->e_fd, c, a); - else - (e = a)->e_activations++; - - return (e); -} diff --git a/src/libelf/elf_cntl.c b/src/libelf/elf_cntl.c deleted file mode 100644 index 0607885..0000000 --- a/src/libelf/elf_cntl.c +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_cntl.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -int -elf_cntl(Elf *e, Elf_Cmd c) -{ - if (e == NULL || - (c != ELF_C_FDDONE && c != ELF_C_FDREAD)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (-1); - } - - if (e->e_parent) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (-1); - } - - if (c == ELF_C_FDREAD) { - if (e->e_cmd == ELF_C_WRITE) { - LIBELF_SET_ERROR(MODE, 0); - return (-1); - } - else - return (0); - } - - e->e_fd = -1; - return 0; -} diff --git a/src/libelf/elf_data.c b/src/libelf/elf_data.c deleted file mode 100644 index 45c5d2c..0000000 --- a/src/libelf/elf_data.c +++ /dev/null @@ -1,254 +0,0 @@ -/*- - * Copyright (c) 2006,2008,2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_data.c 2272 2011-12-03 17:07:31Z jkoshy $"); - -Elf_Data * -elf_getdata(Elf_Scn *s, Elf_Data *ed) -{ - Elf *e; - unsigned int sh_type; - int elfclass, elftype; - size_t fsz, msz, count; - struct _Libelf_Data *d; - uint64_t sh_align, sh_offset, sh_size; - int (*xlate)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); - - d = (struct _Libelf_Data *) ed; - - if (s == NULL || (e = s->s_elf) == NULL || - (d != NULL && s != d->d_scn)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - assert(e->e_kind == ELF_K_ELF); - - if (d == NULL && (d = STAILQ_FIRST(&s->s_data)) != NULL) - return (&d->d_data); - - if (d != NULL) - return (&STAILQ_NEXT(d, d_next)->d_data); - - if (e->e_rawfile == NULL) { - /* - * In the ELF_C_WRITE case, there is no source that - * can provide data for the section. - */ - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - elfclass = e->e_class; - - assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); - - if (elfclass == ELFCLASS32) { - sh_type = s->s_shdr.s_shdr32.sh_type; - sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset; - sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; - sh_align = (uint64_t) s->s_shdr.s_shdr32.sh_addralign; - } else { - sh_type = s->s_shdr.s_shdr64.sh_type; - sh_offset = s->s_shdr.s_shdr64.sh_offset; - sh_size = s->s_shdr.s_shdr64.sh_size; - sh_align = s->s_shdr.s_shdr64.sh_addralign; - } - - if (sh_type == SHT_NULL) { - LIBELF_SET_ERROR(SECTION, 0); - return (NULL); - } - - if ((elftype = _libelf_xlate_shtype(sh_type)) < ELF_T_FIRST || - elftype > ELF_T_LAST || (sh_type != SHT_NOBITS && - sh_offset + sh_size > (uint64_t) e->e_rawsize)) { - LIBELF_SET_ERROR(SECTION, 0); - return (NULL); - } - - if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize) - (elftype, (size_t) 1, e->e_version)) == 0) { - LIBELF_SET_ERROR(UNIMPL, 0); - return (NULL); - } - - if (sh_size % fsz) { - LIBELF_SET_ERROR(SECTION, 0); - return (NULL); - } - - count = sh_size / fsz; - - msz = _libelf_msize(elftype, elfclass, e->e_version); - - assert(msz > 0); - - if ((d = _libelf_allocate_data(s)) == NULL) - return (NULL); - - d->d_data.d_buf = NULL; - d->d_data.d_off = 0; - d->d_data.d_align = sh_align; - d->d_data.d_size = msz * count; - d->d_data.d_type = elftype; - d->d_data.d_version = e->e_version; - - if (sh_type == SHT_NOBITS || sh_size == 0) { - STAILQ_INSERT_TAIL(&s->s_data, d, d_next); - return (&d->d_data); - } - - if ((d->d_data.d_buf = malloc(msz*count)) == NULL) { - (void) _libelf_release_data(d); - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - d->d_flags |= LIBELF_F_DATA_MALLOCED; - - xlate = _libelf_get_translator(elftype, ELF_TOMEMORY, elfclass); - if (!(*xlate)(d->d_data.d_buf, d->d_data.d_size, - e->e_rawfile + sh_offset, count, - e->e_byteorder != LIBELF_PRIVATE(byteorder))) { - _libelf_release_data(d); - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - STAILQ_INSERT_TAIL(&s->s_data, d, d_next); - - return (&d->d_data); -} - -Elf_Data * -elf_newdata(Elf_Scn *s) -{ - Elf *e; - struct _Libelf_Data *d; - - if (s == NULL || (e = s->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - assert(e->e_kind == ELF_K_ELF); - - /* - * elf_newdata() has to append a data descriptor, so - * bring in existing section data if not already present. - */ - if (e->e_rawfile && s->s_size > 0 && STAILQ_EMPTY(&s->s_data)) - if (elf_getdata(s, NULL) == NULL) - return (NULL); - - if ((d = _libelf_allocate_data(s)) == NULL) - return (NULL); - - STAILQ_INSERT_TAIL(&s->s_data, d, d_next); - - d->d_data.d_align = 1; - d->d_data.d_buf = NULL; - d->d_data.d_off = (uint64_t) ~0; - d->d_data.d_size = 0; - d->d_data.d_type = ELF_T_BYTE; - d->d_data.d_version = LIBELF_PRIVATE(version); - - (void) elf_flagscn(s, ELF_C_SET, ELF_F_DIRTY); - - return (&d->d_data); -} - -/* - * Retrieve a data descriptor for raw (untranslated) data for section - * `s'. - */ - -Elf_Data * -elf_rawdata(Elf_Scn *s, Elf_Data *ed) -{ - Elf *e; - int elf_class; - uint32_t sh_type; - struct _Libelf_Data *d; - uint64_t sh_align, sh_offset, sh_size; - - if (s == NULL || (e = s->s_elf) == NULL || e->e_rawfile == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - assert(e->e_kind == ELF_K_ELF); - - d = (struct _Libelf_Data *) ed; - - if (d == NULL && (d = STAILQ_FIRST(&s->s_rawdata)) != NULL) - return (&d->d_data); - - if (d != NULL) - return (&STAILQ_NEXT(d, d_next)->d_data); - - elf_class = e->e_class; - - assert(elf_class == ELFCLASS32 || elf_class == ELFCLASS64); - - if (elf_class == ELFCLASS32) { - sh_type = s->s_shdr.s_shdr32.sh_type; - sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset; - sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; - sh_align = (uint64_t) s->s_shdr.s_shdr32.sh_addralign; - } else { - sh_type = s->s_shdr.s_shdr64.sh_type; - sh_offset = s->s_shdr.s_shdr64.sh_offset; - sh_size = s->s_shdr.s_shdr64.sh_size; - sh_align = s->s_shdr.s_shdr64.sh_addralign; - } - - if (sh_type == SHT_NULL) - return (NULL); - - if ((d = _libelf_allocate_data(s)) == NULL) - return (NULL); - - d->d_data.d_buf = (sh_type == SHT_NOBITS || sh_size == 0) ? NULL : - e->e_rawfile + sh_offset; - d->d_data.d_off = 0; - d->d_data.d_align = sh_align; - d->d_data.d_size = sh_size; - d->d_data.d_type = ELF_T_BYTE; - d->d_data.d_version = e->e_version; - - STAILQ_INSERT_TAIL(&s->s_rawdata, d, d_next); - - return (&d->d_data); -} diff --git a/src/libelf/elf_end.c b/src/libelf/elf_end.c deleted file mode 100644 index 097664c..0000000 --- a/src/libelf/elf_end.c +++ /dev/null @@ -1,97 +0,0 @@ -/*- - * Copyright (c) 2006,2008-2009,2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include - -#include "_libelf.h" - -#if ELFTC_HAVE_MMAP -#include -#endif - -ELFTC_VCSID("$Id: elf_end.c 2240 2011-11-28 06:36:48Z jkoshy $"); - -int -elf_end(Elf *e) -{ - Elf *sv; - Elf_Scn *scn, *tscn; - - if (e == NULL || e->e_activations == 0) - return (0); - - if (--e->e_activations > 0) - return (e->e_activations); - - assert(e->e_activations == 0); - - while (e && e->e_activations == 0) { - switch (e->e_kind) { - case ELF_K_AR: - /* - * If we still have open child descriptors, we - * need to defer reclaiming resources till all - * the child descriptors for the archive are - * closed. - */ - if (e->e_u.e_ar.e_nchildren > 0) - return (0); - break; - case ELF_K_ELF: - /* - * Reclaim all section descriptors. - */ - STAILQ_FOREACH_SAFE(scn, &e->e_u.e_elf.e_scn, s_next, - tscn) - scn = _libelf_release_scn(scn); - break; - case ELF_K_NUM: - assert(0); - default: - break; - } - - if (e->e_rawfile) { - if (e->e_flags & LIBELF_F_RAWFILE_MALLOC) - free(e->e_rawfile); -#if ELFTC_HAVE_MMAP - else if (e->e_flags & LIBELF_F_RAWFILE_MMAP) - (void) munmap(e->e_rawfile, e->e_rawsize); -#endif - } - - sv = e; - if ((e = e->e_parent) != NULL) - e->e_u.e_ar.e_nchildren--; - sv = _libelf_release_elf(sv); - } - - return (0); -} diff --git a/src/libelf/elf_errmsg.c b/src/libelf/elf_errmsg.c deleted file mode 100644 index adcaa74..0000000 --- a/src/libelf/elf_errmsg.c +++ /dev/null @@ -1,85 +0,0 @@ -/*- - * Copyright (c) 2006,2008,2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_errmsg.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -/* - * Retrieve a human readable translation for an error message. - */ - -const char *_libelf_errors[] = { -#define DEFINE_ERROR(N,S) [ELF_E_##N] = S - DEFINE_ERROR(NONE, "No Error"), - DEFINE_ERROR(ARCHIVE, "Malformed ar(1) archive"), - DEFINE_ERROR(ARGUMENT, "Invalid argument"), - DEFINE_ERROR(CLASS, "ELF class mismatch"), - DEFINE_ERROR(DATA, "Invalid data buffer descriptor"), - DEFINE_ERROR(HEADER, "Missing or malformed ELF header"), - DEFINE_ERROR(IO, "I/O error"), - DEFINE_ERROR(LAYOUT, "Layout constraint violation"), - DEFINE_ERROR(MODE, "Incorrect ELF descriptor mode"), - DEFINE_ERROR(RANGE, "Value out of range of target"), - DEFINE_ERROR(RESOURCE, "Resource exhaustion"), - DEFINE_ERROR(SECTION, "Invalid section descriptor"), - DEFINE_ERROR(SEQUENCE, "API calls out of sequence"), - DEFINE_ERROR(UNIMPL, "Unimplemented feature"), - DEFINE_ERROR(VERSION, "Unknown ELF API version"), - DEFINE_ERROR(NUM, "Unknown error") -#undef DEFINE_ERROR -}; - -const char * -elf_errmsg(int error) -{ - int oserr; - - if (error == ELF_E_NONE && - (error = LIBELF_PRIVATE(error)) == 0) - return NULL; - else if (error == -1) - error = LIBELF_PRIVATE(error); - - oserr = error >> LIBELF_OS_ERROR_SHIFT; - error &= LIBELF_ELF_ERROR_MASK; - - if (error < ELF_E_NONE || error >= ELF_E_NUM) - return _libelf_errors[ELF_E_NUM]; - if (oserr) { - (void) snprintf(LIBELF_PRIVATE(msg), - sizeof(LIBELF_PRIVATE(msg)), "%s: %s", - _libelf_errors[error], strerror(oserr)); - return (const char *)&LIBELF_PRIVATE(msg); - } - return _libelf_errors[error]; -} diff --git a/src/libelf/elf_errno.c b/src/libelf/elf_errno.c deleted file mode 100644 index c78d4c7..0000000 --- a/src/libelf/elf_errno.c +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * Copyright (c) 2006,2008,2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_errno.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -int -elf_errno(void) -{ - int old; - - old = LIBELF_PRIVATE(error); - LIBELF_PRIVATE(error) = 0; - return (old & LIBELF_ELF_ERROR_MASK); -} diff --git a/src/libelf/elf_fill.c b/src/libelf/elf_fill.c deleted file mode 100644 index 4c9facc..0000000 --- a/src/libelf/elf_fill.c +++ /dev/null @@ -1,39 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_fill.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -void -elf_fill(int fill) -{ - LIBELF_PRIVATE(fillchar) = fill; -} diff --git a/src/libelf/elf_flag.c b/src/libelf/elf_flag.c deleted file mode 100644 index ab9d24a..0000000 --- a/src/libelf/elf_flag.c +++ /dev/null @@ -1,198 +0,0 @@ -/*- - * Copyright (c) 2006,2008-2009,2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_flag.c 2272 2011-12-03 17:07:31Z jkoshy $"); - -unsigned int -elf_flagarhdr(Elf_Arhdr *a, Elf_Cmd c, unsigned int flags) -{ - unsigned int r; - - if (a == NULL) - return (0); - - if ((c != ELF_C_SET && c != ELF_C_CLR) || - (flags & ~ELF_F_DIRTY) != 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (c == ELF_C_SET) - r = a->ar_flags |= flags; - else - r = a->ar_flags &= ~flags; - - return (r & LIBELF_F_API_MASK); -} - -unsigned int -elf_flagdata(Elf_Data *d, Elf_Cmd c, unsigned int flags) -{ - unsigned int r; - struct _Libelf_Data *ld; - - if (d == NULL) - return (0); - - if ((c != ELF_C_SET && c != ELF_C_CLR) || - (flags & ~ELF_F_DIRTY) != 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ld = (struct _Libelf_Data *) d; - - if (c == ELF_C_SET) - r = ld->d_flags |= flags; - else - r = ld->d_flags &= ~flags; - - return (r & LIBELF_F_API_MASK); -} - -unsigned int -elf_flagehdr(Elf *e, Elf_Cmd c, unsigned int flags) -{ - int ec; - void *ehdr; - - if (e == NULL) - return (0); - - if ((c != ELF_C_SET && c != ELF_C_CLR) || - (e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) - ehdr = e->e_u.e_elf.e_ehdr.e_ehdr32; - else - ehdr = e->e_u.e_elf.e_ehdr.e_ehdr64; - - if (ehdr == NULL) { - LIBELF_SET_ERROR(SEQUENCE, 0); - return (0); - } - - return (elf_flagelf(e, c, flags)); -} - -unsigned int -elf_flagelf(Elf *e, Elf_Cmd c, unsigned int flags) -{ - int r; - - if (e == NULL) - return (0); - - if ((c != ELF_C_SET && c != ELF_C_CLR) || - (e->e_kind != ELF_K_ELF) || - (flags & ~(ELF_F_ARCHIVE | ELF_F_ARCHIVE_SYSV | - ELF_F_DIRTY | ELF_F_LAYOUT)) != 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if ((flags & ELF_F_ARCHIVE_SYSV) && (flags & ELF_F_ARCHIVE) == 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if ((flags & ELF_F_ARCHIVE) && e->e_cmd != ELF_C_WRITE) { - LIBELF_SET_ERROR(MODE, 0); - return (0); - } - - if (c == ELF_C_SET) - r = e->e_flags |= flags; - else - r = e->e_flags &= ~flags; - return (r & LIBELF_F_API_MASK); -} - -unsigned int -elf_flagphdr(Elf *e, Elf_Cmd c, unsigned int flags) -{ - int ec; - void *phdr; - - if (e == NULL) - return (0); - - if ((c != ELF_C_SET && c != ELF_C_CLR) || - (e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) - phdr = e->e_u.e_elf.e_phdr.e_phdr32; - else - phdr = e->e_u.e_elf.e_phdr.e_phdr64; - - if (phdr == NULL) { - LIBELF_SET_ERROR(SEQUENCE, 0); - return (0); - } - - return (elf_flagelf(e, c, flags)); -} - -unsigned int -elf_flagscn(Elf_Scn *s, Elf_Cmd c, unsigned int flags) -{ - int r; - - if (s == NULL) - return (0); - - if ((c != ELF_C_SET && c != ELF_C_CLR) || - (flags & ~ELF_F_DIRTY) != 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (c == ELF_C_SET) - r = s->s_flags |= flags; - else - r = s->s_flags &= ~flags; - return (r & LIBELF_F_API_MASK); -} - -unsigned int -elf_flagshdr(Elf_Scn *s, Elf_Cmd c, unsigned int flags) -{ - return (elf_flagscn(s, c, flags)); -} diff --git a/src/libelf/elf_getarhdr.c b/src/libelf/elf_getarhdr.c deleted file mode 100644 index 07f6888..0000000 --- a/src/libelf/elf_getarhdr.c +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * Copyright (c) 2006,2008,2010 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_getarhdr.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -Elf_Arhdr * -elf_getarhdr(Elf *e) -{ - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (e->e_flags & LIBELF_F_AR_HEADER) - return (e->e_hdr.e_arhdr); - - return (_libelf_ar_gethdr(e)); -} diff --git a/src/libelf/elf_getarsym.c b/src/libelf/elf_getarsym.c deleted file mode 100644 index eeb8513..0000000 --- a/src/libelf/elf_getarsym.c +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_getarsym.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -Elf_Arsym * -elf_getarsym(Elf *ar, size_t *ptr) -{ - size_t n; - Elf_Arsym *symtab; - - n = 0; - symtab = NULL; - - if (ar == NULL || ar->e_kind != ELF_K_AR) - LIBELF_SET_ERROR(ARGUMENT, 0); - else if ((symtab = ar->e_u.e_ar.e_symtab) != NULL) - n = ar->e_u.e_ar.e_symtabsz; - else if (ar->e_u.e_ar.e_rawsymtab) - symtab = (ar->e_flags & LIBELF_F_AR_VARIANT_SVR4) ? - _libelf_ar_process_svr4_symtab(ar, &n) : - _libelf_ar_process_bsd_symtab(ar, &n); - else - LIBELF_SET_ERROR(ARCHIVE, 0); - - if (ptr) - *ptr = n; - return (symtab); -} diff --git a/src/libelf/elf_getbase.c b/src/libelf/elf_getbase.c deleted file mode 100644 index 417808d..0000000 --- a/src/libelf/elf_getbase.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_getbase.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -off_t -elf_getbase(Elf *e) -{ - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return ((off_t) -1); - } - - if (e->e_parent == NULL) - return ((off_t) 0); - - return ((off_t) ((uintptr_t) e->e_rawfile - - (uintptr_t) e->e_parent->e_rawfile)); -} diff --git a/src/libelf/elf_getident.c b/src/libelf/elf_getident.c deleted file mode 100644 index aeea996..0000000 --- a/src/libelf/elf_getident.c +++ /dev/null @@ -1,68 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_getident.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -char * -elf_getident(Elf *e, size_t *sz) -{ - - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - goto error; - } - - if (e->e_cmd == ELF_C_WRITE && e->e_rawfile == NULL) { - LIBELF_SET_ERROR(SEQUENCE, 0); - goto error; - } - - assert(e->e_kind != ELF_K_AR || e->e_cmd == ELF_C_READ); - - if (sz) { - if (e->e_kind == ELF_K_AR) - *sz = SARMAG; - else if (e->e_kind == ELF_K_ELF) - *sz = EI_NIDENT; - else - *sz = e->e_rawsize; - } - - return ((char *) e->e_rawfile); - - error: - if (sz) - *sz = 0; - return (NULL); -} diff --git a/src/libelf/elf_hash.c b/src/libelf/elf_hash.c deleted file mode 100644 index 3735237..0000000 --- a/src/libelf/elf_hash.c +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_hash.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -/* - * This elf_hash function is defined by the System V ABI. - */ - -unsigned long -elf_hash(const char *name) -{ - unsigned long h, t; - const unsigned char *s; - - s = (const unsigned char *) name; - h = t = 0; - - for (; *s != '\0'; h = h & ~t) { - h = (h << 4) + *s++; - t = h & 0xF0000000UL; - if (t) - h ^= t >> 24; - } - - return (h); -} diff --git a/src/libelf/elf_kind.c b/src/libelf/elf_kind.c deleted file mode 100644 index ba83adc..0000000 --- a/src/libelf/elf_kind.c +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_kind.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -Elf_Kind -elf_kind(Elf *e) -{ - if (e == NULL) - return (ELF_K_NONE); - if (e->e_kind == ELF_K_AR || - e->e_kind == ELF_K_ELF) - return (e->e_kind); - return (ELF_K_NONE); -} diff --git a/src/libelf/elf_memory.c b/src/libelf/elf_memory.c deleted file mode 100644 index 9c4755d..0000000 --- a/src/libelf/elf_memory.c +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_memory.c 2368 2011-12-29 06:34:28Z jkoshy $"); - -Elf * -elf_memory(char *image, size_t sz) -{ - if (LIBELF_PRIVATE(version) == EV_NONE) { - LIBELF_SET_ERROR(SEQUENCE, 0); - return (NULL); - } - - if (image == NULL || sz == 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - return (_libelf_memory(image, sz, 1)); -} diff --git a/src/libelf/elf_next.c b/src/libelf/elf_next.c deleted file mode 100644 index 605a593..0000000 --- a/src/libelf/elf_next.c +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_next.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -Elf_Cmd -elf_next(Elf *e) -{ - off_t next; - Elf *parent; - - if (e == NULL) - return (ELF_C_NULL); - - if ((parent = e->e_parent) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (ELF_C_NULL); - } - - assert (parent->e_kind == ELF_K_AR); - assert (parent->e_cmd == ELF_C_READ); - assert(e->e_rawfile > parent->e_rawfile); - - next = e->e_rawfile - parent->e_rawfile + e->e_rawsize; - next = (next + 1) & ~1; /* round up to an even boundary */ - - parent->e_u.e_ar.e_next = (next >= (off_t) parent->e_rawsize) ? - (off_t) 0 : next; - - return (ELF_C_READ); -} diff --git a/src/libelf/elf_open.c b/src/libelf/elf_open.c deleted file mode 100644 index b039431..0000000 --- a/src/libelf/elf_open.c +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * Copyright (c) 2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id$"); - -/* - * Extension API: open a file for reading, ignoring parse errors. - */ - -Elf * -elf_open(int fd) -{ - if (LIBELF_PRIVATE(version) == EV_NONE) { - LIBELF_SET_ERROR(SEQUENCE, 0); - return (NULL); - } - - return (_libelf_open_object(fd, ELF_C_READ, 0)); -} - -/* - * Extension API: create an ELF descriptor for an in-memory object, - * ignoring parse errors. - */ - -Elf * -elf_openmemory(char *image, size_t sz) -{ - if (LIBELF_PRIVATE(version) == EV_NONE) { - LIBELF_SET_ERROR(SEQUENCE, 0); - return (NULL); - } - - if (image == NULL || sz == 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - return (_libelf_memory(image, sz, 0)); -} diff --git a/src/libelf/elf_phnum.c b/src/libelf/elf_phnum.c deleted file mode 100644 index 5994806..0000000 --- a/src/libelf/elf_phnum.c +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_phnum.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -static int -_libelf_getphdrnum(Elf *e, size_t *phnum) -{ - void *eh; - int ec; - - if (e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (-1); - } - - if ((eh = _libelf_ehdr(e, ec, 0)) == NULL) - return (-1); - - *phnum = e->e_u.e_elf.e_nphdr; - - return (0); -} - -int -elf_getphdrnum(Elf *e, size_t *phnum) -{ - return (_libelf_getphdrnum(e, phnum)); -} - -/* Deprecated API */ -int -elf_getphnum(Elf *e, size_t *phnum) -{ - return (_libelf_getphdrnum(e, phnum) >= 0); -} diff --git a/src/libelf/elf_rand.c b/src/libelf/elf_rand.c deleted file mode 100644 index f48f017..0000000 --- a/src/libelf/elf_rand.c +++ /dev/null @@ -1,59 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_rand.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -off_t -elf_rand(Elf *ar, off_t offset) -{ - struct ar_hdr *arh; - - if (ar == NULL || ar->e_kind != ELF_K_AR || - (offset & 1) || offset < SARMAG || - offset + sizeof(struct ar_hdr) >= ar->e_rawsize) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return 0; - } - - arh = (struct ar_hdr *) (ar->e_rawfile + offset); - - /* a too simple sanity check */ - if (arh->ar_fmag[0] != '`' || arh->ar_fmag[1] != '\n') { - LIBELF_SET_ERROR(ARCHIVE, 0); - return 0; - } - - ar->e_u.e_ar.e_next = offset; - - return (offset); -} diff --git a/src/libelf/elf_rawfile.c b/src/libelf/elf_rawfile.c deleted file mode 100644 index 76cfd7f..0000000 --- a/src/libelf/elf_rawfile.c +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_rawfile.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -char * -elf_rawfile(Elf *e, size_t *sz) -{ - char *ptr; - size_t size; - - size = e ? e->e_rawsize : 0; - ptr = NULL; - - if (e == NULL) - LIBELF_SET_ERROR(ARGUMENT, 0); - else if ((ptr = e->e_rawfile) == NULL && e->e_cmd == ELF_C_WRITE) - LIBELF_SET_ERROR(SEQUENCE, 0); - - if (sz) - *sz = size; - - return (ptr); -} diff --git a/src/libelf/elf_scn.c b/src/libelf/elf_scn.c deleted file mode 100644 index 01a1f8f..0000000 --- a/src/libelf/elf_scn.c +++ /dev/null @@ -1,233 +0,0 @@ -/*- - * Copyright (c) 2006,2008-2010 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include - -#include -#include -#include "gelf.h" -#include -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_scn.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -/* - * Load an ELF section table and create a list of Elf_Scn structures. - */ -int -_libelf_load_section_headers(Elf *e, void *ehdr) -{ - int ec, swapbytes; - size_t fsz, i, shnum; - uint64_t shoff; - char *src; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - Elf_Scn *scn; - int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); - - assert(e != NULL); - assert(ehdr != NULL); - assert((e->e_flags & LIBELF_F_SHDRS_LOADED) == 0); - -#define CHECK_EHDR(E,EH) do { \ - if (fsz != (EH)->e_shentsize || \ - shoff + fsz * shnum > e->e_rawsize) { \ - LIBELF_SET_ERROR(HEADER, 0); \ - return (0); \ - } \ - } while (0) - - ec = e->e_class; - fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1); - assert(fsz > 0); - - shnum = e->e_u.e_elf.e_nscn; - - if (ec == ELFCLASS32) { - eh32 = (Elf32_Ehdr *) ehdr; - shoff = (uint64_t) eh32->e_shoff; - CHECK_EHDR(e, eh32); - } else { - eh64 = (Elf64_Ehdr *) ehdr; - shoff = eh64->e_shoff; - CHECK_EHDR(e, eh64); - } - - xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec); - - swapbytes = e->e_byteorder != LIBELF_PRIVATE(byteorder); - src = e->e_rawfile + shoff; - - /* - * If the file is using extended numbering then section #0 - * would have already been read in. - */ - - i = 0; - if (!STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) { - /* commented out to prevent build error - assert(STAILQ_FIRST(&e->e_u.e_elf.e_scn) == - STAILQ_LAST(&e->e_u.e_elf.e_scn, _Elf_Scn, s_next));*/ - - i = 1; - src += fsz; - } - - for (; i < shnum; i++, src += fsz) { - if ((scn = _libelf_allocate_scn(e, i)) == NULL) - return (0); - - (*xlator)((char *) &scn->s_shdr, sizeof(scn->s_shdr), src, - (size_t) 1, swapbytes); - - if (ec == ELFCLASS32) { - scn->s_offset = scn->s_rawoff = - scn->s_shdr.s_shdr32.sh_offset; - scn->s_size = scn->s_shdr.s_shdr32.sh_size; - } else { - scn->s_offset = scn->s_rawoff = - scn->s_shdr.s_shdr64.sh_offset; - scn->s_size = scn->s_shdr.s_shdr64.sh_size; - } - } - - e->e_flags |= LIBELF_F_SHDRS_LOADED; - - return (1); -} - - -Elf_Scn * -elf_getscn(Elf *e, size_t index) -{ - int ec; - void *ehdr; - Elf_Scn *s; - - if (e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) - return (NULL); - - if (e->e_cmd != ELF_C_WRITE && - (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && - _libelf_load_section_headers(e, ehdr) == 0) - return (NULL); - - STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) - if (s->s_ndx == index) - return (s); - - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); -} - -size_t -elf_ndxscn(Elf_Scn *s) -{ - if (s == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (SHN_UNDEF); - } - return (s->s_ndx); -} - -Elf_Scn * -elf_newscn(Elf *e) -{ - int ec; - void *ehdr; - Elf_Scn *scn; - - if (e == NULL || e->e_kind != ELF_K_ELF) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) { - LIBELF_SET_ERROR(CLASS, 0); - return (NULL); - } - - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) - return (NULL); - - /* - * The application may be asking for a new section descriptor - * on an ELF object opened with ELF_C_RDWR or ELF_C_READ. We - * need to bring in the existing section information before - * appending a new one to the list. - * - * Per the ELF(3) API, an application is allowed to open a - * file using ELF_C_READ, mess with its internal structure and - * use elf_update(...,ELF_C_NULL) to compute its new layout. - */ - if (e->e_cmd != ELF_C_WRITE && - (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && - _libelf_load_section_headers(e, ehdr) == 0) - return (NULL); - - if (STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) { - assert(e->e_u.e_elf.e_nscn == 0); - if ((scn = _libelf_allocate_scn(e, (size_t) SHN_UNDEF)) == - NULL) - return (NULL); - e->e_u.e_elf.e_nscn++; - } - - assert(e->e_u.e_elf.e_nscn > 0); - - if ((scn = _libelf_allocate_scn(e, e->e_u.e_elf.e_nscn)) == NULL) - return (NULL); - - e->e_u.e_elf.e_nscn++; - - (void) elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY); - - return (scn); -} - -Elf_Scn * -elf_nextscn(Elf *e, Elf_Scn *s) -{ - if (e == NULL || (e->e_kind != ELF_K_ELF) || - (s && s->s_elf != e)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - return (s == NULL ? elf_getscn(e, (size_t) 1) : - STAILQ_NEXT(s, s_next)); -} diff --git a/src/libelf/elf_shnum.c b/src/libelf/elf_shnum.c deleted file mode 100644 index a06a9e4..0000000 --- a/src/libelf/elf_shnum.c +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_shnum.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -static int -_libelf_getshdrnum(Elf *e, size_t *shnum) -{ - void *eh; - int ec; - - if (e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (-1); - } - - if ((eh = _libelf_ehdr(e, ec, 0)) == NULL) - return (-1); - - *shnum = e->e_u.e_elf.e_nscn; - - return (0); -} - -int -elf_getshdrnum(Elf *e, size_t *shnum) -{ - return (_libelf_getshdrnum(e, shnum)); -} - -/* Deprecated API. */ -int -elf_getshnum(Elf *e, size_t *shnum) -{ - return (_libelf_getshdrnum(e, shnum) >= 0); -} diff --git a/src/libelf/elf_shstrndx.c b/src/libelf/elf_shstrndx.c deleted file mode 100644 index 0a7bab9..0000000 --- a/src/libelf/elf_shstrndx.c +++ /dev/null @@ -1,82 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_shstrndx.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -static int -_libelf_getshdrstrndx(Elf *e, size_t *strndx) -{ - void *eh; - int ec; - - if (e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (-1); - } - - if ((eh = _libelf_ehdr(e, ec, 0)) == NULL) - return (-1); - - *strndx = e->e_u.e_elf.e_strndx; - - return (0); -} - -int -elf_getshdrstrndx(Elf *e, size_t *strndx) -{ - return (_libelf_getshdrstrndx(e, strndx)); -} - -int -elf_getshstrndx(Elf *e, size_t *strndx) /* Deprecated API. */ -{ - return (_libelf_getshdrstrndx(e, strndx) >= 0); -} - -int -elf_setshstrndx(Elf *e, size_t strndx) -{ - void *eh; - int ec; - - if (e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) || - ((eh = _libelf_ehdr(e, ec, 0)) == NULL)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - return (_libelf_setshstrndx(e, eh, ec, strndx)); -} diff --git a/src/libelf/elf_strptr.c b/src/libelf/elf_strptr.c deleted file mode 100644 index e282df7..0000000 --- a/src/libelf/elf_strptr.c +++ /dev/null @@ -1,132 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include "gelf.h" - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_strptr.c 2271 2011-12-03 17:06:35Z jkoshy $"); - -/* - * Convert an ELF section#,offset pair to a string pointer. - */ - -char * -elf_strptr(Elf *e, size_t scndx, size_t offset) -{ - Elf_Scn *s; - Elf_Data *d; - size_t alignment, count; - GElf_Shdr shdr; - - if (e == NULL || e->e_kind != ELF_K_ELF) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((s = elf_getscn(e, scndx)) == NULL || - gelf_getshdr(s, &shdr) == NULL) - return (NULL); - - if (shdr.sh_type != SHT_STRTAB || - offset >= shdr.sh_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - d = NULL; - if (e->e_flags & ELF_F_LAYOUT) { - - /* - * The application is taking responsibility for the - * ELF object's layout, so we can directly translate - * an offset to a `char *' address using the `d_off' - * members of Elf_Data descriptors. - */ - while ((d = elf_getdata(s, d)) != NULL) { - - if (d->d_buf == 0 || d->d_size == 0) - continue; - - if (d->d_type != ELF_T_BYTE) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - if (offset >= d->d_off && - offset < d->d_off + d->d_size) - return ((char *) d->d_buf + offset - d->d_off); - } - } else { - /* - * Otherwise, the `d_off' members are not useable and - * we need to compute offsets ourselves, taking into - * account 'holes' in coverage of the section introduced - * by alignment requirements. - */ - count = (size_t) 0; /* cumulative count of bytes seen */ - while ((d = elf_getdata(s, d)) != NULL && count <= offset) { - - if (d->d_buf == NULL || d->d_size == 0) - continue; - - if (d->d_type != ELF_T_BYTE) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - if ((alignment = d->d_align) > 1) { - if ((alignment & (alignment - 1)) != 0) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - count = roundup2(count, alignment); - } - - if (offset < count) { - /* offset starts in the 'hole' */ - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (offset < count + d->d_size) { - if (d->d_buf != NULL) - return ((char *) d->d_buf + - offset - count); - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - count += d->d_size; - } - } - - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); -} diff --git a/src/libelf/elf_update.c b/src/libelf/elf_update.c deleted file mode 100644 index 4bf0577..0000000 --- a/src/libelf/elf_update.c +++ /dev/null @@ -1,1204 +0,0 @@ -/*- - * Copyright (c) 2006-2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include - -#include -#include -#include "gelf.h" -#include -#include -#include -#include - -#include "_libelf.h" - -#if ELFTC_HAVE_MMAP -#include -#endif - -ELFTC_VCSID("$Id: elf_update.c 2348 2011-12-19 02:22:45Z jkoshy $"); - -/* - * Layout strategy: - * - * - Case 1: ELF_F_LAYOUT is asserted - * In this case the application has full control over where the - * section header table, program header table, and section data - * will reside. The library only perform error checks. - * - * - Case 2: ELF_F_LAYOUT is not asserted - * - * The library will do the object layout using the following - * ordering: - * - The executable header is placed first, are required by the - * ELF specification. - * - The program header table is placed immediately following the - * executable header. - * - Section data, if any, is placed after the program header - * table, aligned appropriately. - * - The section header table, if needed, is placed last. - * - * There are two sub-cases to be taken care of: - * - * - Case 2a: e->e_cmd == ELF_C_READ or ELF_C_RDWR - * - * In this sub-case, the underlying ELF object may already have - * content in it, which the application may have modified. The - * library will retrieve content from the existing object as - * needed. - * - * - Case 2b: e->e_cmd == ELF_C_WRITE - * - * The ELF object is being created afresh in this sub-case; - * there is no pre-existing content in the underlying ELF - * object. - */ - -/* - * The types of extents in an ELF object. - */ -enum elf_extent { - ELF_EXTENT_EHDR, - ELF_EXTENT_PHDR, - ELF_EXTENT_SECTION, - ELF_EXTENT_SHDR -}; - -/* - * A extent descriptor, used when laying out an ELF object. - */ -struct _Elf_Extent { - SLIST_ENTRY(_Elf_Extent) ex_next; - uint64_t ex_start; /* Start of the region. */ - uint64_t ex_size; /* The size of the region. */ - enum elf_extent ex_type; /* Type of region. */ - void *ex_desc; /* Associated descriptor. */ -}; - -SLIST_HEAD(_Elf_Extent_List, _Elf_Extent); - -/* - * Compute the extents of a section, by looking at the data - * descriptors associated with it. The function returns 1 - * if successful, or zero if an error was detected. - */ -static int -_libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc) -{ - int ec; - Elf_Data *d; - size_t fsz, msz; - uint32_t sh_type; - uint64_t d_align; - Elf32_Shdr *shdr32; - Elf64_Shdr *shdr64; - unsigned int elftype; - struct _Libelf_Data *ld; - uint64_t scn_size, scn_alignment; - uint64_t sh_align, sh_entsize, sh_offset, sh_size; - - ec = e->e_class; - - shdr32 = &s->s_shdr.s_shdr32; - shdr64 = &s->s_shdr.s_shdr64; - if (ec == ELFCLASS32) { - sh_type = shdr32->sh_type; - sh_align = (uint64_t) shdr32->sh_addralign; - sh_entsize = (uint64_t) shdr32->sh_entsize; - sh_offset = (uint64_t) shdr32->sh_offset; - sh_size = (uint64_t) shdr32->sh_size; - } else { - sh_type = shdr64->sh_type; - sh_align = shdr64->sh_addralign; - sh_entsize = shdr64->sh_entsize; - sh_offset = shdr64->sh_offset; - sh_size = shdr64->sh_size; - } - - assert(sh_type != SHT_NULL && sh_type != SHT_NOBITS); - - elftype = _libelf_xlate_shtype(sh_type); - if (elftype > ELF_T_LAST) { - LIBELF_SET_ERROR(SECTION, 0); - return (0); - } - - if (sh_align == 0) - sh_align = _libelf_falign(elftype, ec); - - /* - * Compute the section's size and alignment using the data - * descriptors associated with the section. - */ - if (STAILQ_EMPTY(&s->s_data)) { - /* - * The section's content (if any) has not been read in - * yet. If section is not dirty marked dirty, we can - * reuse the values in the 'sh_size' and 'sh_offset' - * fields of the section header. - */ - if ((s->s_flags & ELF_F_DIRTY) == 0) { - /* - * If the library is doing the layout, then we - * compute the new start offset for the - * section based on the current offset and the - * section's alignment needs. - * - * If the application is doing the layout, we - * can use the value in the 'sh_offset' field - * in the section header directly. - */ - if (e->e_flags & ELF_F_LAYOUT) - goto updatedescriptor; - else - goto computeoffset; - } - - /* - * Otherwise, we need to bring in the section's data - * from the underlying ELF object. - */ - if (e->e_cmd != ELF_C_WRITE && elf_getdata(s, NULL) == NULL) - return (0); - } - - /* - * Loop through the section's data descriptors. - */ - scn_size = 0L; - scn_alignment = 0; - STAILQ_FOREACH(ld, &s->s_data, d_next) { - - d = &ld->d_data; - - /* - * The data buffer's type is known. - */ - if (d->d_type >= ELF_T_NUM) { - LIBELF_SET_ERROR(DATA, 0); - return (0); - } - - /* - * The data buffer's version is supported. - */ - if (d->d_version != e->e_version) { - LIBELF_SET_ERROR(VERSION, 0); - return (0); - } - - /* - * The buffer's alignment is non-zero and a power of - * two. - */ - if ((d_align = d->d_align) == 0 || - (d_align & (d_align - 1))) { - LIBELF_SET_ERROR(DATA, 0); - return (0); - } - - /* - * The buffer's size should be a multiple of the - * memory size of the underlying type. - */ - msz = _libelf_msize(d->d_type, ec, e->e_version); - if (d->d_size % msz) { - LIBELF_SET_ERROR(DATA, 0); - return (0); - } - - /* - * If the application is controlling layout, then the - * d_offset field should be compatible with the - * buffer's specified alignment. - */ - if ((e->e_flags & ELF_F_LAYOUT) && - (d->d_off & (d_align - 1))) { - LIBELF_SET_ERROR(LAYOUT, 0); - return (0); - } - - /* - * Compute the section's size. - */ - if (e->e_flags & ELF_F_LAYOUT) { - if ((uint64_t) d->d_off + d->d_size > scn_size) - scn_size = d->d_off + d->d_size; - } else { - scn_size = roundup2(scn_size, d->d_align); - d->d_off = scn_size; - fsz = _libelf_fsize(d->d_type, ec, d->d_version, - d->d_size / msz); - scn_size += fsz; - } - - /* - * The section's alignment is the maximum alignment - * needed for its data buffers. - */ - if (d_align > scn_alignment) - scn_alignment = d_align; - } - - - /* - * If the application is requesting full control over the - * layout of the section, check the section's specified size, - * offsets and alignment for sanity. - */ - if (e->e_flags & ELF_F_LAYOUT) { - if (scn_alignment > sh_align || sh_offset % sh_align || - sh_size < scn_size) { - LIBELF_SET_ERROR(LAYOUT, 0); - return (0); - } - goto updatedescriptor; - } - - /* - * Otherwise, compute the values in the section header. - * - * The section alignment is the maximum alignment for any of - * its contained data descriptors. - */ - if (scn_alignment > sh_align) - sh_align = scn_alignment; - - /* - * If the section entry size is zero, try and fill in an - * appropriate entry size. Per the elf(5) manual page - * sections without fixed-size entries should have their - * 'sh_entsize' field set to zero. - */ - if (sh_entsize == 0 && - (sh_entsize = _libelf_fsize(elftype, ec, e->e_version, - (size_t) 1)) == 1) - sh_entsize = 0; - - sh_size = scn_size; - -computeoffset: - /* - * Compute the new offset for the section based on - * the section's alignment needs. - */ - sh_offset = roundup(rc, sh_align); - - /* - * Update the section header. - */ - if (ec == ELFCLASS32) { - shdr32->sh_addralign = (uint32_t) sh_align; - shdr32->sh_entsize = (uint32_t) sh_entsize; - shdr32->sh_offset = (uint32_t) sh_offset; - shdr32->sh_size = (uint32_t) sh_size; - } else { - shdr64->sh_addralign = sh_align; - shdr64->sh_entsize = sh_entsize; - shdr64->sh_offset = sh_offset; - shdr64->sh_size = sh_size; - } - -updatedescriptor: - /* - * Update the section descriptor. - */ - s->s_size = sh_size; - s->s_offset = sh_offset; - - return (1); -} - -/* - * Free a list of extent descriptors. - */ - -static void -_libelf_release_extents(struct _Elf_Extent_List *extents) -{ - struct _Elf_Extent *ex; - - while ((ex = SLIST_FIRST(extents)) != NULL) { - SLIST_REMOVE_HEAD(extents, ex_next); - free(ex); - } -} - -/* - * Check if an extent 's' defined by [start..start+size) is free. - * This routine assumes that the given extent list is sorted in order - * of ascending extent offsets. - */ - -static int -_libelf_extent_is_unused(struct _Elf_Extent_List *extents, - const uint64_t start, const uint64_t size, struct _Elf_Extent **prevt) -{ - uint64_t tmax, tmin; - struct _Elf_Extent *t, *pt; - const uint64_t smax = start + size; - - /* First, look for overlaps with existing extents. */ - pt = NULL; - SLIST_FOREACH(t, extents, ex_next) { - tmin = t->ex_start; - tmax = tmin + t->ex_size; - - if (tmax <= start) { - /* - * 't' lies entirely before 's': ...| t |...| s |... - */ - pt = t; - continue; - } else if (smax <= tmin) { - /* - * 's' lies entirely before 't', and after 'pt': - * ...| pt |...| s |...| t |... - */ - assert(pt == NULL || - pt->ex_start + pt->ex_size <= start); - break; - } else - /* 's' and 't' overlap. */ - return (0); - } - - if (prevt) - *prevt = pt; - return (1); -} - -/* - * Insert an extent into the list of extents. - */ - -static int -_libelf_insert_extent(struct _Elf_Extent_List *extents, int type, - uint64_t start, uint64_t size, void *desc) -{ - struct _Elf_Extent *ex, *prevt; - - assert(type >= ELF_EXTENT_EHDR && type <= ELF_EXTENT_SHDR); - - prevt = NULL; - - /* - * If the requested range overlaps with an existing extent, - * signal an error. - */ - if (!_libelf_extent_is_unused(extents, start, size, &prevt)) { - LIBELF_SET_ERROR(LAYOUT, 0); - return (0); - } - - /* Allocate and fill in a new extent descriptor. */ - if ((ex = malloc(sizeof(struct _Elf_Extent))) == NULL) { - LIBELF_SET_ERROR(RESOURCE, errno); - return (0); - } - ex->ex_start = start; - ex->ex_size = size; - ex->ex_desc = desc; - ex->ex_type = type; - - /* Insert the region descriptor into the list. */ - if (prevt) - SLIST_INSERT_AFTER(prevt, ex, ex_next); - else - SLIST_INSERT_HEAD(extents, ex, ex_next); - return (1); -} - -/* - * Recompute section layout. - */ - -static off_t -_libelf_resync_sections(Elf *e, off_t rc, struct _Elf_Extent_List *extents) -{ - int ec; - Elf_Scn *s; - size_t sh_type; - - ec = e->e_class; - - /* - * Make a pass through sections, computing the extent of each - * section. - */ - STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) { - if (ec == ELFCLASS32) - sh_type = s->s_shdr.s_shdr32.sh_type; - else - sh_type = s->s_shdr.s_shdr64.sh_type; - - if (sh_type == SHT_NOBITS || sh_type == SHT_NULL) - continue; - - if (_libelf_compute_section_extents(e, s, rc) == 0) - return ((off_t) -1); - - if (s->s_size == 0) - continue; - - if (!_libelf_insert_extent(extents, ELF_EXTENT_SECTION, - s->s_offset, s->s_size, s)) - return ((off_t) -1); - - if ((size_t) rc < s->s_offset + s->s_size) - rc = s->s_offset + s->s_size; - } - - return (rc); -} - -/* - * Recompute the layout of the ELF object and update the internal data - * structures associated with the ELF descriptor. - * - * Returns the size in bytes the ELF object would occupy in its file - * representation. - * - * After a successful call to this function, the following structures - * are updated: - * - * - The ELF header is updated. - * - All extents in the ELF object are sorted in order of ascending - * addresses. Sections have their section header table entries - * updated. An error is signalled if an overlap was detected among - * extents. - * - Data descriptors associated with sections are checked for valid - * types, offsets and alignment. - * - * After a resync_elf() successfully returns, the ELF descriptor is - * ready for being handed over to _libelf_write_elf(). - */ - -static off_t -_libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents) -{ - int ec, eh_class, eh_type; - unsigned int eh_byteorder, eh_version; - size_t align, fsz; - size_t phnum, shnum; - off_t rc, phoff, shoff; - void *ehdr, *phdr; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - - rc = 0; - - ec = e->e_class; - - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - /* - * Prepare the EHDR. - */ - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) - return ((off_t) -1); - - eh32 = ehdr; - eh64 = ehdr; - - if (ec == ELFCLASS32) { - eh_byteorder = eh32->e_ident[EI_DATA]; - eh_class = eh32->e_ident[EI_CLASS]; - phoff = (uint64_t) eh32->e_phoff; - shoff = (uint64_t) eh32->e_shoff; - eh_type = eh32->e_type; - eh_version = eh32->e_version; - } else { - eh_byteorder = eh64->e_ident[EI_DATA]; - eh_class = eh64->e_ident[EI_CLASS]; - phoff = eh64->e_phoff; - shoff = eh64->e_shoff; - eh_type = eh64->e_type; - eh_version = eh64->e_version; - } - - if (eh_version == EV_NONE) - eh_version = EV_CURRENT; - - if (eh_version != e->e_version) { /* always EV_CURRENT */ - LIBELF_SET_ERROR(VERSION, 0); - return ((off_t) -1); - } - - if (eh_class != e->e_class) { - LIBELF_SET_ERROR(CLASS, 0); - return ((off_t) -1); - } - - if (e->e_cmd != ELF_C_WRITE && eh_byteorder != e->e_byteorder) { - LIBELF_SET_ERROR(HEADER, 0); - return ((off_t) -1); - } - - shnum = e->e_u.e_elf.e_nscn; - phnum = e->e_u.e_elf.e_nphdr; - - e->e_byteorder = eh_byteorder; - -#define INITIALIZE_EHDR(E,EC,V) do { \ - (E)->e_ident[EI_MAG0] = ELFMAG0; \ - (E)->e_ident[EI_MAG1] = ELFMAG1; \ - (E)->e_ident[EI_MAG2] = ELFMAG2; \ - (E)->e_ident[EI_MAG3] = ELFMAG3; \ - (E)->e_ident[EI_CLASS] = (EC); \ - (E)->e_ident[EI_VERSION] = (V); \ - (E)->e_ehsize = _libelf_fsize(ELF_T_EHDR, (EC), (V), \ - (size_t) 1); \ - (E)->e_phentsize = (phnum == 0) ? 0 : _libelf_fsize( \ - ELF_T_PHDR, (EC), (V), (size_t) 1); \ - (E)->e_shentsize = _libelf_fsize(ELF_T_SHDR, (EC), (V), \ - (size_t) 1); \ - } while (0) - - if (ec == ELFCLASS32) - INITIALIZE_EHDR(eh32, ec, eh_version); - else - INITIALIZE_EHDR(eh64, ec, eh_version); - - (void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY); - - rc += _libelf_fsize(ELF_T_EHDR, ec, eh_version, (size_t) 1); - - if (!_libelf_insert_extent(extents, ELF_EXTENT_EHDR, 0, rc, ehdr)) - return ((off_t) -1); - - /* - * Compute the layout the program header table, if one is - * present. The program header table needs to be aligned to a - * `natural' boundary. - */ - if (phnum) { - fsz = _libelf_fsize(ELF_T_PHDR, ec, eh_version, phnum); - align = _libelf_falign(ELF_T_PHDR, ec); - - if (e->e_flags & ELF_F_LAYOUT) { - /* - * Check offsets for sanity. - */ - if (rc > phoff) { - LIBELF_SET_ERROR(LAYOUT, 0); - return ((off_t) -1); - } - - if (phoff % align) { - LIBELF_SET_ERROR(LAYOUT, 0); - return ((off_t) -1); - } - - } else - phoff = roundup(rc, align); - - rc = phoff + fsz; - - phdr = _libelf_getphdr(e, ec); - - if (!_libelf_insert_extent(extents, ELF_EXTENT_PHDR, phoff, - fsz, phdr)) - return ((off_t) -1); - } else - phoff = 0; - - /* - * Compute the layout of the sections associated with the - * file. - */ - - if (e->e_cmd != ELF_C_WRITE && - (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && - _libelf_load_section_headers(e, ehdr) == 0) - return ((off_t) -1); - - if ((rc = _libelf_resync_sections(e, rc, extents)) < 0) - return ((off_t) -1); - - /* - * Compute the space taken up by the section header table, if - * one is needed. - * - * If ELF_F_LAYOUT has been asserted, the application may have - * placed the section header table in between existing - * sections, so the net size of the file need not increase due - * to the presence of the section header table. - * - * If the library is responsible for laying out the object, - * the section header table is placed after section data. - */ - if (shnum) { - fsz = _libelf_fsize(ELF_T_SHDR, ec, eh_version, shnum); - align = _libelf_falign(ELF_T_SHDR, ec); - - if (e->e_flags & ELF_F_LAYOUT) { - if (shoff % align) { - LIBELF_SET_ERROR(LAYOUT, 0); - return ((off_t) -1); - } - } else - shoff = roundup(rc, align); - - if (shoff + fsz > (size_t) rc) - rc = shoff + fsz; - - if (!_libelf_insert_extent(extents, ELF_EXTENT_SHDR, shoff, - fsz, NULL)) - return ((off_t) -1); - } else - shoff = 0; - - /* - * Set the fields of the Executable Header that could potentially use - * extended numbering. - */ - _libelf_setphnum(e, ehdr, ec, phnum); - _libelf_setshnum(e, ehdr, ec, shnum); - - /* - * Update the `e_phoff' and `e_shoff' fields if the library is - * doing the layout. - */ - if ((e->e_flags & ELF_F_LAYOUT) == 0) { - if (ec == ELFCLASS32) { - eh32->e_phoff = (uint32_t) phoff; - eh32->e_shoff = (uint32_t) shoff; - } else { - eh64->e_phoff = (uint64_t) phoff; - eh64->e_shoff = (uint64_t) shoff; - } - } - - return (rc); -} - -/* - * Write out the contents of an ELF section. - */ - -static size_t -_libelf_write_scn(Elf *e, char *nf, struct _Elf_Extent *ex) -{ - int ec; - Elf_Scn *s; - int elftype; - Elf_Data *d, dst; - uint32_t sh_type; - struct _Libelf_Data *ld; - uint64_t sh_off, sh_size; - size_t fsz, msz, nobjects, rc; - - assert(ex->ex_type == ELF_EXTENT_SECTION); - - s = ex->ex_desc; - rc = ex->ex_start; - - if ((ec = e->e_class) == ELFCLASS32) { - sh_type = s->s_shdr.s_shdr32.sh_type; - sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; - } else { - sh_type = s->s_shdr.s_shdr64.sh_type; - sh_size = s->s_shdr.s_shdr64.sh_size; - } - - /* - * Ignore sections that do not allocate space in the file. - */ - if (sh_type == SHT_NOBITS || sh_type == SHT_NULL || sh_size == 0) - return (rc); - - elftype = _libelf_xlate_shtype(sh_type); - assert(elftype >= ELF_T_FIRST && elftype <= ELF_T_LAST); - - sh_off = s->s_offset; - assert(sh_off % _libelf_falign(elftype, ec) == 0); - - /* - * If the section has a `rawdata' descriptor, and the section - * contents have not been modified, use its contents directly. - * The `s_rawoff' member contains the offset into the original - * file, while `s_offset' contains its new location in the - * destination. - */ - - if (STAILQ_EMPTY(&s->s_data)) { - - if ((d = elf_rawdata(s, NULL)) == NULL) - return ((off_t) -1); - - STAILQ_FOREACH(ld, &s->s_rawdata, d_next) { - - d = &ld->d_data; - - if ((uint64_t) rc < sh_off + d->d_off) - (void) memset(nf + rc, - LIBELF_PRIVATE(fillchar), sh_off + - d->d_off - rc); - rc = sh_off + d->d_off; - - assert(d->d_buf != NULL); - assert(d->d_type == ELF_T_BYTE); - assert(d->d_version == e->e_version); - - (void) memcpy(nf + rc, - e->e_rawfile + s->s_rawoff + d->d_off, d->d_size); - - rc += d->d_size; - } - - return (rc); - } - - /* - * Iterate over the set of data descriptors for this section. - * The prior call to _libelf_resync_elf() would have setup the - * descriptors for this step. - */ - - dst.d_version = e->e_version; - - STAILQ_FOREACH(ld, &s->s_data, d_next) { - - d = &ld->d_data; - - msz = _libelf_msize(d->d_type, ec, e->e_version); - - if ((uint64_t) rc < sh_off + d->d_off) - (void) memset(nf + rc, - LIBELF_PRIVATE(fillchar), sh_off + d->d_off - rc); - - rc = sh_off + d->d_off; - - assert(d->d_buf != NULL); - assert(d->d_version == e->e_version); - assert(d->d_size % msz == 0); - - nobjects = d->d_size / msz; - - fsz = _libelf_fsize(d->d_type, ec, e->e_version, nobjects); - - dst.d_buf = nf + rc; - dst.d_size = fsz; - - if (_libelf_xlate(&dst, d, e->e_byteorder, ec, ELF_TOFILE) == - NULL) - return ((off_t) -1); - - rc += fsz; - } - - return ((off_t) rc); -} - -/* - * Write out an ELF Executable Header. - */ - -static off_t -_libelf_write_ehdr(Elf *e, char *nf, struct _Elf_Extent *ex) -{ - int ec; - void *ehdr; - size_t fsz, msz; - Elf_Data dst, src; - - assert(ex->ex_type == ELF_EXTENT_EHDR); - assert(ex->ex_start == 0); /* Ehdr always comes first. */ - - ec = e->e_class; - - ehdr = _libelf_ehdr(e, ec, 0); - assert(ehdr != NULL); - - fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1); - msz = _libelf_msize(ELF_T_EHDR, ec, e->e_version); - - (void) memset(&dst, 0, sizeof(dst)); - (void) memset(&src, 0, sizeof(src)); - - src.d_buf = ehdr; - src.d_size = msz; - src.d_type = ELF_T_EHDR; - src.d_version = dst.d_version = e->e_version; - - dst.d_buf = nf; - dst.d_size = fsz; - - if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, ELF_TOFILE) == - NULL) - return ((off_t) -1); - - return ((off_t) fsz); -} - -/* - * Write out an ELF program header table. - */ - -static off_t -_libelf_write_phdr(Elf *e, char *nf, struct _Elf_Extent *ex) -{ - int ec; - void *ehdr; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - Elf_Data dst, src; - size_t fsz, phnum; - uint64_t phoff; - - assert(ex->ex_type == ELF_EXTENT_PHDR); - - ec = e->e_class; - ehdr = _libelf_ehdr(e, ec, 0); - phnum = e->e_u.e_elf.e_nphdr; - - assert(phnum > 0); - - if (ec == ELFCLASS32) { - eh32 = (Elf32_Ehdr *) ehdr; - phoff = (uint64_t) eh32->e_phoff; - } else { - eh64 = (Elf64_Ehdr *) ehdr; - phoff = eh64->e_phoff; - } - - assert(phoff > 0); - assert(ex->ex_start == phoff); - assert(phoff % _libelf_falign(ELF_T_PHDR, ec) == 0); - - (void) memset(&dst, 0, sizeof(dst)); - (void) memset(&src, 0, sizeof(src)); - - fsz = _libelf_fsize(ELF_T_PHDR, ec, e->e_version, phnum); - assert(fsz > 0); - - src.d_buf = _libelf_getphdr(e, ec); - src.d_version = dst.d_version = e->e_version; - src.d_type = ELF_T_PHDR; - src.d_size = phnum * _libelf_msize(ELF_T_PHDR, ec, - e->e_version); - - dst.d_size = fsz; - dst.d_buf = nf + ex->ex_start; - - if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, ELF_TOFILE) == - NULL) - return ((off_t) -1); - - return (phoff + fsz); -} - -/* - * Write out an ELF section header table. - */ - -static off_t -_libelf_write_shdr(Elf *e, char *nf, struct _Elf_Extent *ex) -{ - int ec; - void *ehdr; - Elf_Scn *scn; - uint64_t shoff; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - size_t fsz, nscn; - Elf_Data dst, src; - - assert(ex->ex_type == ELF_EXTENT_SHDR); - - ec = e->e_class; - ehdr = _libelf_ehdr(e, ec, 0); - nscn = e->e_u.e_elf.e_nscn; - - if (ec == ELFCLASS32) { - eh32 = (Elf32_Ehdr *) ehdr; - shoff = (uint64_t) eh32->e_shoff; - } else { - eh64 = (Elf64_Ehdr *) ehdr; - shoff = eh64->e_shoff; - } - - assert(nscn > 0); - assert(shoff % _libelf_falign(ELF_T_SHDR, ec) == 0); - assert(ex->ex_start == shoff); - - (void) memset(&dst, 0, sizeof(dst)); - (void) memset(&src, 0, sizeof(src)); - - src.d_type = ELF_T_SHDR; - src.d_size = _libelf_msize(ELF_T_SHDR, ec, e->e_version); - src.d_version = dst.d_version = e->e_version; - - fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1); - - STAILQ_FOREACH(scn, &e->e_u.e_elf.e_scn, s_next) { - if (ec == ELFCLASS32) - src.d_buf = &scn->s_shdr.s_shdr32; - else - src.d_buf = &scn->s_shdr.s_shdr64; - - dst.d_size = fsz; - dst.d_buf = nf + ex->ex_start + scn->s_ndx * fsz; - - if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, - ELF_TOFILE) == NULL) - return ((off_t) -1); - } - - return (ex->ex_start + nscn * fsz); -} - -/* - * Write out the file image. - * - * The original file could have been mapped in with an ELF_C_RDWR - * command and the application could have added new content or - * re-arranged its sections before calling elf_update(). Consequently - * its not safe to work `in place' on the original file. So we - * malloc() the required space for the updated ELF object and build - * the object there and write it out to the underlying file at the - * end. Note that the application may have opened the underlying file - * in ELF_C_RDWR and only retrieved/modified a few sections. We take - * care to avoid translating file sections unnecessarily. - * - * Gaps in the coverage of the file by the file's sections will be - * filled with the fill character set by elf_fill(3). - */ - -static off_t -_libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents) -{ - off_t nrc, rc; - char *newfile; - Elf_Scn *scn, *tscn; - struct _Elf_Extent *ex; - - assert(e->e_kind == ELF_K_ELF); - assert(e->e_cmd == ELF_C_RDWR || e->e_cmd == ELF_C_WRITE); - assert(e->e_fd >= 0); - - if ((newfile = malloc((size_t) newsize)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, errno); - return ((off_t) -1); - } - - nrc = rc = 0; - SLIST_FOREACH(ex, extents, ex_next) { - - /* Fill inter-extent gaps. */ - if (ex->ex_start > (size_t) rc) - (void) memset(newfile + rc, LIBELF_PRIVATE(fillchar), - ex->ex_start - rc); - - switch (ex->ex_type) { - case ELF_EXTENT_EHDR: - if ((nrc = _libelf_write_ehdr(e, newfile, ex)) < 0) - goto error; - break; - - case ELF_EXTENT_PHDR: - if ((nrc = _libelf_write_phdr(e, newfile, ex)) < 0) - goto error; - break; - - case ELF_EXTENT_SECTION: - if ((nrc = _libelf_write_scn(e, newfile, ex)) < 0) - goto error; - break; - - case ELF_EXTENT_SHDR: - if ((nrc = _libelf_write_shdr(e, newfile, ex)) < 0) - goto error; - break; - - default: - assert(0); - break; - } - - assert(ex->ex_start + ex->ex_size == (size_t) nrc); - assert(rc < nrc); - - rc = nrc; - } - - assert(rc == newsize); - - /* - * For regular files, throw away existing file content and - * unmap any existing mappings. - */ - if ((e->e_flags & LIBELF_F_SPECIAL_FILE) == 0) { - if (ftruncate(e->e_fd, (off_t) 0) < 0 || - lseek(e->e_fd, (off_t) 0, SEEK_SET)) { - LIBELF_SET_ERROR(IO, errno); - goto error; - } -#if ELFTC_HAVE_MMAP - if (e->e_flags & LIBELF_F_RAWFILE_MMAP) { - assert(e->e_rawfile != NULL); - assert(e->e_cmd == ELF_C_RDWR); - if (munmap(e->e_rawfile, e->e_rawsize) < 0) { - LIBELF_SET_ERROR(IO, errno); - goto error; - } - } -#endif - } - - /* - * Write out the new contents. - */ - if (write(e->e_fd, newfile, (size_t) newsize) != newsize) { - LIBELF_SET_ERROR(IO, errno); - goto error; - } - - /* - * For files opened in ELF_C_RDWR mode, set up the new 'raw' - * contents. - */ - if (e->e_cmd == ELF_C_RDWR) { - assert(e->e_rawfile != NULL); - assert((e->e_flags & LIBELF_F_RAWFILE_MALLOC) || - (e->e_flags & LIBELF_F_RAWFILE_MMAP)); - if (e->e_flags & LIBELF_F_RAWFILE_MALLOC) { - free(e->e_rawfile); - e->e_rawfile = newfile; - newfile = NULL; - } -#if ELFTC_HAVE_MMAP - else if (e->e_flags & LIBELF_F_RAWFILE_MMAP) { - if ((e->e_rawfile = mmap(NULL, (size_t) newsize, - PROT_READ, MAP_PRIVATE, e->e_fd, (off_t) 0)) == - MAP_FAILED) { - LIBELF_SET_ERROR(IO, errno); - goto error; - } - } -#endif /* ELFTC_HAVE_MMAP */ - - /* Record the new size of the file. */ - e->e_rawsize = newsize; - } else { - /* File opened in ELF_C_WRITE mode. */ - assert(e->e_rawfile == NULL); - } - - /* - * Reset flags, remove existing section descriptors and - * {E,P}HDR pointers so that a subsequent elf_get{e,p}hdr() - * and elf_getscn() will function correctly. - */ - - e->e_flags &= ~ELF_F_DIRTY; - - STAILQ_FOREACH_SAFE(scn, &e->e_u.e_elf.e_scn, s_next, tscn) - _libelf_release_scn(scn); - - if (e->e_class == ELFCLASS32) { - free(e->e_u.e_elf.e_ehdr.e_ehdr32); - if (e->e_u.e_elf.e_phdr.e_phdr32) - free(e->e_u.e_elf.e_phdr.e_phdr32); - - e->e_u.e_elf.e_ehdr.e_ehdr32 = NULL; - e->e_u.e_elf.e_phdr.e_phdr32 = NULL; - } else { - free(e->e_u.e_elf.e_ehdr.e_ehdr64); - if (e->e_u.e_elf.e_phdr.e_phdr64) - free(e->e_u.e_elf.e_phdr.e_phdr64); - - e->e_u.e_elf.e_ehdr.e_ehdr64 = NULL; - e->e_u.e_elf.e_phdr.e_phdr64 = NULL; - } - - /* Free the temporary buffer. */ - if (newfile) - free(newfile); - - return (rc); - - error: - free(newfile); - - return ((off_t) -1); -} - -/* - * Update an ELF object. - */ - -off_t -elf_update(Elf *e, Elf_Cmd c) -{ - int ec; - off_t rc; - struct _Elf_Extent_List extents; - - rc = (off_t) -1; - - if (e == NULL || e->e_kind != ELF_K_ELF || - (c != ELF_C_NULL && c != ELF_C_WRITE)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (rc); - } - - if ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) { - LIBELF_SET_ERROR(CLASS, 0); - return (rc); - } - - if (e->e_version == EV_NONE) - e->e_version = EV_CURRENT; - - if (c == ELF_C_WRITE && e->e_cmd == ELF_C_READ) { - LIBELF_SET_ERROR(MODE, 0); - return (rc); - } - - SLIST_INIT(&extents); - - if ((rc = _libelf_resync_elf(e, &extents)) < 0) - goto done; - - if (c == ELF_C_NULL) - goto done; - - if (e->e_fd < 0) { - rc = (off_t) -1; - LIBELF_SET_ERROR(SEQUENCE, 0); - goto done; - } - - rc = _libelf_write_elf(e, rc, &extents); - -done: - _libelf_release_extents(&extents); - return (rc); -} diff --git a/src/libelf/elf_version.c b/src/libelf/elf_version.c deleted file mode 100644 index 3aa466a..0000000 --- a/src/libelf/elf_version.c +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: elf_version.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -unsigned int -elf_version(unsigned int v) -{ - unsigned int old; - - if ((old = LIBELF_PRIVATE(version)) == EV_NONE) - old = EV_CURRENT; - - if (v == EV_NONE) - return old; - if (v > EV_CURRENT) { - LIBELF_SET_ERROR(VERSION, 0); - return EV_NONE; - } - - LIBELF_PRIVATE(version) = v; - return (old); -} diff --git a/src/libelf/elfdefinitions.h b/src/libelf/elfdefinitions.h deleted file mode 100644 index 79b6e7f..0000000 --- a/src/libelf/elfdefinitions.h +++ /dev/null @@ -1,2560 +0,0 @@ -/*- - * Copyright (c) 2010 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: elfdefinitions.h 2132 2011-11-10 08:27:41Z jkoshy $ - */ - -/* - * These definitions are based on: - * - The public specification of the ELF format as defined in the - * October 2009 draft of System V ABI. - * See: http://www.sco.com/developers/gabi/latest/ch4.intro.html - * - The May 1998 (version 1.5) draft of "The ELF-64 object format". - * - Processor-specific ELF ABI definitions for sparc, i386, amd64, mips, - * ia64, and powerpc processors. - * - The "Linkers and Libraries Guide", from Sun Microsystems. - */ - -#ifndef _ELFDEFINITIONS_H_ -#define _ELFDEFINITIONS_H_ - -#include - -/* - * Types of capabilities. - */ - -#define _ELF_DEFINE_CAPABILITIES() \ -_ELF_DEFINE_CA(CA_SUNW_NULL, 0, "ignored") \ -_ELF_DEFINE_CA(CA_SUNW_HW_1, 1, "hardware capability") \ -_ELF_DEFINE_CA(CA_SUNW_SW_1, 2, "software capability") - -#undef _ELF_DEFINE_CA -#define _ELF_DEFINE_CA(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_CAPABILITIES() - CA__LAST__ -}; - -/* - * Flags used with dynamic linking entries. - */ - -#define _ELF_DEFINE_DYN_FLAGS() \ -_ELF_DEFINE_DF(DF_ORIGIN, 0x1, \ - "object being loaded may refer to $ORIGIN") \ -_ELF_DEFINE_DF(DF_SYMBOLIC, 0x2, \ - "search library for references before executable") \ -_ELF_DEFINE_DF(DF_TEXTREL, 0x4, \ - "relocation entries may modify text segment") \ -_ELF_DEFINE_DF(DF_BIND_NOW, 0x8, \ - "process relocation entries at load time") \ -_ELF_DEFINE_DF(DF_STATIC_TLS, 0x10, \ - "uses static thread-local storage") -#undef _ELF_DEFINE_DF -#define _ELF_DEFINE_DF(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_DYN_FLAGS() - DF__LAST__ -}; - - -/* - * Dynamic linking entry types. - */ - -#define _ELF_DEFINE_DYN_TYPES() \ -_ELF_DEFINE_DT(DT_NULL, 0, "end of array") \ -_ELF_DEFINE_DT(DT_NEEDED, 1, "names a needed library") \ -_ELF_DEFINE_DT(DT_PLTRELSZ, 2, \ - "size in bytes of associated relocation entries") \ -_ELF_DEFINE_DT(DT_PLTGOT, 3, \ - "address associated with the procedure linkage table") \ -_ELF_DEFINE_DT(DT_HASH, 4, \ - "address of the symbol hash table") \ -_ELF_DEFINE_DT(DT_STRTAB, 5, \ - "address of the string table") \ -_ELF_DEFINE_DT(DT_SYMTAB, 6, \ - "address of the symbol table") \ -_ELF_DEFINE_DT(DT_RELA, 7, \ - "address of the relocation table") \ -_ELF_DEFINE_DT(DT_RELASZ, 8, "size of the DT_RELA table") \ -_ELF_DEFINE_DT(DT_RELAENT, 9, "size of each DT_RELA entry") \ -_ELF_DEFINE_DT(DT_STRSZ, 10, "size of the string table") \ -_ELF_DEFINE_DT(DT_SYMENT, 11, \ - "size of a symbol table entry") \ -_ELF_DEFINE_DT(DT_INIT, 12, \ - "address of the initialization function") \ -_ELF_DEFINE_DT(DT_FINI, 13, \ - "address of the finalization function") \ -_ELF_DEFINE_DT(DT_SONAME, 14, "names the shared object") \ -_ELF_DEFINE_DT(DT_RPATH, 15, \ - "runtime library search path") \ -_ELF_DEFINE_DT(DT_SYMBOLIC, 16, \ - "alter symbol resolution algorithm") \ -_ELF_DEFINE_DT(DT_REL, 17, \ - "address of the DT_REL table") \ -_ELF_DEFINE_DT(DT_RELSZ, 18, "size of the DT_REL table") \ -_ELF_DEFINE_DT(DT_RELENT, 19, "size of each DT_REL entry") \ -_ELF_DEFINE_DT(DT_PLTREL, 20, \ - "type of relocation entry in the procedure linkage table") \ -_ELF_DEFINE_DT(DT_DEBUG, 21, "used for debugging") \ -_ELF_DEFINE_DT(DT_TEXTREL, 22, \ - "text segment may be written to during relocation") \ -_ELF_DEFINE_DT(DT_JMPREL, 23, \ - "address of relocation entries associated with the procedure linkage table") \ -_ELF_DEFINE_DT(DT_BIND_NOW, 24, \ - "bind symbols at loading time") \ -_ELF_DEFINE_DT(DT_INIT_ARRAY, 25, \ - "pointers to initialization functions") \ -_ELF_DEFINE_DT(DT_FINI_ARRAY, 26, \ - "pointers to termination functions") \ -_ELF_DEFINE_DT(DT_INIT_ARRAYSZ, 27, "size of the DT_INIT_ARRAY") \ -_ELF_DEFINE_DT(DT_FINI_ARRAYSZ, 28, "size of the DT_FINI_ARRAY") \ -_ELF_DEFINE_DT(DT_RUNPATH, 29, \ - "index of library search path string") \ -_ELF_DEFINE_DT(DT_FLAGS, 30, \ - "flags specific to the object being loaded") \ -_ELF_DEFINE_DT(DT_ENCODING, 32, "standard semantics") \ -_ELF_DEFINE_DT(DT_PREINIT_ARRAY, 32, \ - "pointers to pre-initialization functions") \ -_ELF_DEFINE_DT(DT_PREINIT_ARRAYSZ, 33, \ - "size of pre-initialization array") \ -_ELF_DEFINE_DT(DT_MAXPOSTAGS, 34, \ - "the number of positive tags") \ -_ELF_DEFINE_DT(DT_LOOS, 0x6000000DUL, \ - "start of OS-specific types") \ -_ELF_DEFINE_DT(DT_SUNW_AUXILIARY, 0x6000000DUL, \ - "offset of string naming auxiliary filtees") \ -_ELF_DEFINE_DT(DT_SUNW_RTLDINF, 0x6000000EUL, "rtld internal use") \ -_ELF_DEFINE_DT(DT_SUNW_FILTER, 0x6000000FUL, \ - "offset of string naming standard filtees") \ -_ELF_DEFINE_DT(DT_SUNW_CAP, 0x60000010UL, \ - "address of hardware capabilities section") \ -_ELF_DEFINE_DT(DT_HIOS, 0x6FFFF000UL, \ - "end of OS-specific types") \ -_ELF_DEFINE_DT(DT_VALRNGLO, 0x6FFFFD00UL, \ - "start of range using the d_val field") \ -_ELF_DEFINE_DT(DT_GNU_PRELINKED, 0x6FFFFDF5UL, \ - "prelinking timestamp") \ -_ELF_DEFINE_DT(DT_GNU_CONFLICTSZ, 0x6FFFFDF6UL, \ - "size of conflict section") \ -_ELF_DEFINE_DT(DT_GNU_LIBLISTSZ, 0x6FFFFDF7UL, \ - "size of library list") \ -_ELF_DEFINE_DT(DT_CHECKSUM, 0x6FFFFDF8UL, \ - "checksum for the object") \ -_ELF_DEFINE_DT(DT_PLTPADSZ, 0x6FFFFDF9UL, \ - "size of PLT padding") \ -_ELF_DEFINE_DT(DT_MOVEENT, 0x6FFFFDFAUL, \ - "size of DT_MOVETAB entries") \ -_ELF_DEFINE_DT(DT_MOVESZ, 0x6FFFFDFBUL, \ - "total size of the MOVETAB table") \ -_ELF_DEFINE_DT(DT_FEATURE_1, 0x6FFFFDFCUL, "feature values") \ -_ELF_DEFINE_DT(DT_POSFLAG_1, 0x6FFFFDFDUL, \ - "dynamic position flags") \ -_ELF_DEFINE_DT(DT_SYMINSZ, 0x6FFFFDFEUL, \ - "size of the DT_SYMINFO table") \ -_ELF_DEFINE_DT(DT_SYMINENT, 0x6FFFFDFFUL, \ - "size of a DT_SYMINFO entry") \ -_ELF_DEFINE_DT(DT_VALRNGHI, 0x6FFFFDFFUL, \ - "end of range using the d_val field") \ -_ELF_DEFINE_DT(DT_ADDRRNGLO, 0x6FFFFE00UL, \ - "start of range using the d_ptr field") \ -_ELF_DEFINE_DT(DT_GNU_HASH, 0x6FFFFEF5UL, \ - "GNU style hash tables") \ -_ELF_DEFINE_DT(DT_GNU_CONFLICT, 0x6FFFFEF8UL, \ - "address of conflict section") \ -_ELF_DEFINE_DT(DT_GNU_LIBLIST, 0x6FFFFEF9UL, \ - "address of conflict section") \ -_ELF_DEFINE_DT(DT_CONFIG, 0x6FFFFEFAUL, \ - "configuration file") \ -_ELF_DEFINE_DT(DT_DEPAUDIT, 0x6FFFFEFBUL, \ - "string defining audit libraries") \ -_ELF_DEFINE_DT(DT_AUDIT, 0x6FFFFEFCUL, \ - "string defining audit libraries") \ -_ELF_DEFINE_DT(DT_PLTPAD, 0x6FFFFEFDUL, "PLT padding") \ -_ELF_DEFINE_DT(DT_MOVETAB, 0x6FFFFEFEUL, \ - "address of a move table") \ -_ELF_DEFINE_DT(DT_SYMINFO, 0x6FFFFEFFUL, \ - "address of the symbol information table") \ -_ELF_DEFINE_DT(DT_ADDRRNGHI, 0x6FFFFEFFUL, \ - "end of range using the d_ptr field") \ -_ELF_DEFINE_DT(DT_VERSYM, 0x6FFFFFF0UL, \ - "address of the version section") \ -_ELF_DEFINE_DT(DT_RELACOUNT, 0x6FFFFFF9UL, \ - "count of RELA relocations") \ -_ELF_DEFINE_DT(DT_RELCOUNT, 0x6FFFFFFAUL, \ - "count of REL relocations") \ -_ELF_DEFINE_DT(DT_FLAGS_1, 0x6FFFFFFBUL, "flag values") \ -_ELF_DEFINE_DT(DT_VERDEF, 0x6FFFFFFCUL, \ - "address of the version definition segment") \ -_ELF_DEFINE_DT(DT_VERDEFNUM, 0x6FFFFFFDUL, \ - "the number of version definition entries") \ -_ELF_DEFINE_DT(DT_VERNEED, 0x6FFFFFFEUL, \ - "address of section with needed versions") \ -_ELF_DEFINE_DT(DT_VERNEEDNUM, 0x6FFFFFFFUL, \ - "the number of version needed entries") \ -_ELF_DEFINE_DT(DT_LOPROC, 0x70000000UL, \ - "start of processor-specific types") \ -_ELF_DEFINE_DT(DT_ARM_SYMTABSZ, 0x70000001UL, \ - "number of entries in the dynamic symbol table") \ -_ELF_DEFINE_DT(DT_SPARC_REGISTER, 0x70000001UL, \ - "index of an STT_SPARC_REGISTER symbol") \ -_ELF_DEFINE_DT(DT_ARM_PREEMPTMAP, 0x70000002UL, \ - "address of the preemption map") \ -_ELF_DEFINE_DT(DT_MIPS_RLD_VERSION, 0x70000001UL, \ - "version ID for runtime linker interface") \ -_ELF_DEFINE_DT(DT_MIPS_TIME_STAMP, 0x70000002UL, \ - "timestamp") \ -_ELF_DEFINE_DT(DT_MIPS_ICHECKSUM, 0x70000003UL, \ - "checksum of all external strings and common sizes") \ -_ELF_DEFINE_DT(DT_MIPS_IVERSION, 0x70000004UL, \ - "string table index of a version string") \ -_ELF_DEFINE_DT(DT_MIPS_FLAGS, 0x70000005UL, \ - "MIPS-specific flags") \ -_ELF_DEFINE_DT(DT_MIPS_BASE_ADDRESS, 0x70000006UL, \ - "base address for the executable/DSO") \ -_ELF_DEFINE_DT(DT_MIPS_CONFLICT, 0x70000008UL, \ - "address of .conflict section") \ -_ELF_DEFINE_DT(DT_MIPS_LIBLIST, 0x70000009UL, \ - "address of .liblist section") \ -_ELF_DEFINE_DT(DT_MIPS_LOCAL_GOTNO, 0x7000000AUL, \ - "number of local GOT entries") \ -_ELF_DEFINE_DT(DT_MIPS_CONFLICTNO, 0x7000000BUL, \ - "number of entries in the .conflict section") \ -_ELF_DEFINE_DT(DT_MIPS_LIBLISTNO, 0x70000010UL, \ - "number of entries in the .liblist section") \ -_ELF_DEFINE_DT(DT_MIPS_SYMTABNO, 0x70000011UL, \ - "number of entries in the .dynsym section") \ -_ELF_DEFINE_DT(DT_MIPS_UNREFEXTNO, 0x70000012UL, \ - "index of first external dynamic symbol not ref'ed locally") \ -_ELF_DEFINE_DT(DT_MIPS_GOTSYM, 0x70000013UL, \ - "index of first dynamic symbol corresponds to a GOT entry") \ -_ELF_DEFINE_DT(DT_MIPS_HIPAGENO, 0x70000014UL, \ - "number of page table entries in GOT") \ -_ELF_DEFINE_DT(DT_MIPS_RLD_MAP, 0x70000016UL, \ - "address of runtime linker map") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_CLASS, 0x70000017UL, \ - "Delta C++ class definition") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_CLASS_NO, 0x70000018UL, \ - "number of entries in DT_MIPS_DELTA_CLASS") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_INSTANCE, 0x70000019UL, \ - "Delta C++ class instances") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_INSTANCE_NO, 0x7000001AUL, \ - "number of entries in DT_MIPS_DELTA_INSTANCE") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_RELOC, 0x7000001BUL, \ - "Delta relocations") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_RELOC_NO, 0x7000001CUL, \ - "number of entries in DT_MIPS_DELTA_RELOC") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_SYM, 0x7000001DUL, \ - "Delta symbols refered by Delta relocations") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_SYM_NO, 0x7000001EUL, \ - "number of entries in DT_MIPS_DELTA_SYM") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_CLASSSYM, 0x70000020UL, \ - "Delta symbols for class declarations") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_CLASSSYM_NO, 0x70000021UL, \ - "number of entries in DT_MIPS_DELTA_CLASSSYM") \ -_ELF_DEFINE_DT(DT_MIPS_CXX_FLAGS, 0x70000022UL, \ - "C++ flavor flags") \ -_ELF_DEFINE_DT(DT_MIPS_PIXIE_INIT, 0x70000023UL, \ - "address of an initialization routine created by pixie") \ -_ELF_DEFINE_DT(DT_MIPS_SYMBOL_LIB, 0x70000024UL, \ - "address of .MIPS.symlib section") \ -_ELF_DEFINE_DT(DT_MIPS_LOCALPAGE_GOTIDX, 0x70000025UL, \ - "GOT index of first page table entry for a segment") \ -_ELF_DEFINE_DT(DT_MIPS_LOCAL_GOTIDX, 0x70000026UL, \ - "GOT index of first page table entry for a local symbol") \ -_ELF_DEFINE_DT(DT_MIPS_HIDDEN_GOTIDX, 0x70000027UL, \ - "GOT index of first page table entry for a hidden symbol") \ -_ELF_DEFINE_DT(DT_MIPS_PROTECTED_GOTIDX, 0x70000028UL, \ - "GOT index of first page table entry for a protected symbol") \ -_ELF_DEFINE_DT(DT_MIPS_OPTIONS, 0x70000029UL, \ - "address of .MIPS.options section") \ -_ELF_DEFINE_DT(DT_MIPS_INTERFACE, 0x7000002AUL, \ - "address of .MIPS.interface section") \ -_ELF_DEFINE_DT(DT_MIPS_DYNSTR_ALIGN, 0x7000002BUL, "???") \ -_ELF_DEFINE_DT(DT_MIPS_INTERFACE_SIZE, 0x7000002CUL, \ - "size of .MIPS.interface section") \ -_ELF_DEFINE_DT(DT_MIPS_RLD_TEXT_RESOLVE_ADDR, 0x7000002DUL, \ - "address of _rld_text_resolve in GOT") \ -_ELF_DEFINE_DT(DT_MIPS_PERF_SUFFIX, 0x7000002EUL, \ - "default suffix of DSO to be appended by dlopen") \ -_ELF_DEFINE_DT(DT_MIPS_COMPACT_SIZE, 0x7000002FUL, \ - "size of a ucode compact relocation record (o32)") \ -_ELF_DEFINE_DT(DT_MIPS_GP_VALUE, 0x70000030UL, \ - "GP value of a specified GP relative range") \ -_ELF_DEFINE_DT(DT_MIPS_AUX_DYNAMIC, 0x70000031UL, \ - "address of an auxiliary dynamic table") \ -_ELF_DEFINE_DT(DT_MIPS_PLTGOT, 0x70000032UL, \ - "address of the PLTGOT") \ -_ELF_DEFINE_DT(DT_MIPS_RLD_OBJ_UPDATE, 0x70000033UL, \ - "object list update callback") \ -_ELF_DEFINE_DT(DT_MIPS_RWPLT, 0x70000034UL, \ - "address of a writable PLT") \ -_ELF_DEFINE_DT(DT_PPC_GOT, 0x70000000UL, \ - "value of _GLOBAL_OFFSET_TABLE_") \ -_ELF_DEFINE_DT(DT_PPC_TLSOPT, 0x70000001UL, \ - "TLS descriptor should be optimized") \ -_ELF_DEFINE_DT(DT_PPC64_GLINK, 0x70000000UL, \ - "address of .glink section") \ -_ELF_DEFINE_DT(DT_PPC64_OPD, 0x70000001UL, \ - "address of .opd section") \ -_ELF_DEFINE_DT(DT_PPC64_OPDSZ, 0x70000002UL, \ - "size of .opd section") \ -_ELF_DEFINE_DT(DT_PPC64_TLSOPT, 0x70000003UL, \ - "TLS descriptor should be optimized") \ -_ELF_DEFINE_DT(DT_AUXILIARY, 0x7FFFFFFDUL, \ - "offset of string naming auxiliary filtees") \ -_ELF_DEFINE_DT(DT_USED, 0x7FFFFFFEUL, "ignored") \ -_ELF_DEFINE_DT(DT_FILTER, 0x7FFFFFFFUL, \ - "index of string naming filtees") \ -_ELF_DEFINE_DT(DT_HIPROC, 0x7FFFFFFFUL, \ - "end of processor-specific types") - -#undef _ELF_DEFINE_DT -#define _ELF_DEFINE_DT(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_DYN_TYPES() - DT__LAST__ = DT_HIPROC -}; - -#define DT_DEPRECATED_SPARC_REGISTER DT_SPARC_REGISTER - -/* - * Flags used in the executable header (field: e_flags). - */ -#define _ELF_DEFINE_EHDR_FLAGS() \ -_ELF_DEFINE_EF(EF_ARM_RELEXEC, 0x00000001UL, \ - "dynamic segment describes only how to relocate segments") \ -_ELF_DEFINE_EF(EF_ARM_HASENTRY, 0x00000002UL, \ - "e_entry contains a program entry point") \ -_ELF_DEFINE_EF(EF_ARM_SYMSARESORTED, 0x00000004UL, \ - "subsection of symbol table is sorted by symbol value") \ -_ELF_DEFINE_EF(EF_ARM_DYNSYMSUSESEGIDX, 0x00000008UL, \ - "dynamic symbol st_shndx = containing segment index + 1") \ -_ELF_DEFINE_EF(EF_ARM_MAPSYMSFIRST, 0x00000010UL, \ - "mapping symbols precede other local symbols in symtab") \ -_ELF_DEFINE_EF(EF_ARM_BE8, 0x00800000UL, \ - "file contains BE-8 code") \ -_ELF_DEFINE_EF(EF_ARM_LE8, 0x00400000UL, \ - "file contains LE-8 code") \ -_ELF_DEFINE_EF(EF_ARM_EABIMASK, 0xFF000000UL, \ - "mask for ARM EABI version number (0 denotes GNU or unknown)") \ -_ELF_DEFINE_EF(EF_ARM_INTERWORK, 0x00000004UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_ARM_APCS_26, 0x00000008UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_ARM_APCS_FLOAT, 0x00000010UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_ARM_PIC, 0x00000020UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_ARM_ALIGN8, 0x00000040UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_ARM_NEW_ABI, 0x00000080UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_ARM_OLD_ABI, 0x00000100UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_ARM_SOFT_FLOAT, 0x00000200UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_ARM_VFP_FLOAT, 0x00000400UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_ARM_MAVERICK_FLOAT, 0x00000800UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_MIPS_NOREORDER, 0x00000001UL, \ - "at least one .noreorder directive appeared in the source") \ -_ELF_DEFINE_EF(EF_MIPS_PIC, 0x00000002UL, \ - "file contains position independent code") \ -_ELF_DEFINE_EF(EF_MIPS_CPIC, 0x00000004UL, \ - "file's code uses standard conventions for calling PIC") \ -_ELF_DEFINE_EF(EF_MIPS_UCODE, 0x00000010UL, \ - "file contains UCODE (obsolete)") \ -_ELF_DEFINE_EF(EF_MIPS_ABI2, 0x00000020UL, \ - "file follows MIPS III 32-bit ABI") \ -_ELF_DEFINE_EF(EF_MIPS_OPTIONS_FIRST, 0x00000080UL, \ - "ld(1) should process .MIPS.options section first") \ -_ELF_DEFINE_EF(EF_MIPS_ARCH_ASE, 0x0F000000UL, \ - "file uses application-specific architectural extensions") \ -_ELF_DEFINE_EF(EF_MIPS_ARCH_ASE_MDMX, 0x08000000UL, \ - "file uses MDMX multimedia extensions") \ -_ELF_DEFINE_EF(EF_MIPS_ARCH_ASE_M16, 0x04000000UL, \ - "file uses MIPS-16 ISA extensions") \ -_ELF_DEFINE_EF(EF_MIPS_ARCH, 0xF0000000UL, \ - "4-bit MIPS architecture field") \ -_ELF_DEFINE_EF(EF_PPC_EMB, 0x80000000UL, \ - "Embedded PowerPC flag") \ -_ELF_DEFINE_EF(EF_PPC_RELOCATABLE, 0x00010000UL, \ - "-mrelocatable flag") \ -_ELF_DEFINE_EF(EF_PPC_RELOCATABLE_LIB, 0x00008000UL, \ - "-mrelocatable-lib flag") \ -_ELF_DEFINE_EF(EF_SPARC_EXT_MASK, 0x00ffff00UL, \ - "Vendor Extension mask") \ -_ELF_DEFINE_EF(EF_SPARC_32PLUS, 0x00000100UL, \ - "Generic V8+ features") \ -_ELF_DEFINE_EF(EF_SPARC_SUN_US1, 0x00000200UL, \ - "Sun UltraSPARCTM 1 Extensions") \ -_ELF_DEFINE_EF(EF_SPARC_HAL_R1, 0x00000400UL, "HAL R1 Extensions") \ -_ELF_DEFINE_EF(EF_SPARC_SUN_US3, 0x00000800UL, \ - "Sun UltraSPARC 3 Extensions") \ -_ELF_DEFINE_EF(EF_SPARCV9_MM, 0x00000003UL, \ - "Mask for Memory Model") \ -_ELF_DEFINE_EF(EF_SPARCV9_TSO, 0x00000000UL, \ - "Total Store Ordering") \ -_ELF_DEFINE_EF(EF_SPARCV9_PSO, 0x00000001UL, \ - "Partial Store Ordering") \ -_ELF_DEFINE_EF(EF_SPARCV9_RMO, 0x00000002UL, \ - "Relaxed Memory Ordering") - -#undef _ELF_DEFINE_EF -#define _ELF_DEFINE_EF(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_EHDR_FLAGS() - EF__LAST__ -}; - -/* - * Offsets in the `ei_ident[]` field of an ELF executable header. - */ -#define _ELF_DEFINE_EI_OFFSETS() \ -_ELF_DEFINE_EI(EI_MAG0, 0, "magic number") \ -_ELF_DEFINE_EI(EI_MAG1, 1, "magic number") \ -_ELF_DEFINE_EI(EI_MAG2, 2, "magic number") \ -_ELF_DEFINE_EI(EI_MAG3, 3, "magic number") \ -_ELF_DEFINE_EI(EI_CLASS, 4, "file class") \ -_ELF_DEFINE_EI(EI_DATA, 5, "data encoding") \ -_ELF_DEFINE_EI(EI_VERSION, 6, "file version") \ -_ELF_DEFINE_EI(EI_OSABI, 7, "OS ABI kind") \ -_ELF_DEFINE_EI(EI_ABIVERSION, 8, "OS ABI version") \ -_ELF_DEFINE_EI(EI_PAD, 9, "padding start") \ -_ELF_DEFINE_EI(EI_NIDENT, 16, "total size") - -#undef _ELF_DEFINE_EI -#define _ELF_DEFINE_EI(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_EI_OFFSETS() - EI__LAST__ -}; - -/* - * The ELF class of an object. - */ -#define _ELF_DEFINE_ELFCLASS() \ -_ELF_DEFINE_EC(ELFCLASSNONE, 0, "Unknown ELF class") \ -_ELF_DEFINE_EC(ELFCLASS32, 1, "32 bit objects") \ -_ELF_DEFINE_EC(ELFCLASS64, 2, "64 bit objects") - -#undef _ELF_DEFINE_EC -#define _ELF_DEFINE_EC(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_ELFCLASS() - EC__LAST__ -}; - -/* - * Endianness of data in an ELF object. - */ - -#define _ELF_DEFINE_ELF_DATA_ENDIANNESS() \ -_ELF_DEFINE_ED(ELFDATANONE, 0, "Unknown data endianness") \ -_ELF_DEFINE_ED(ELFDATA2LSB, 1, "little endian") \ -_ELF_DEFINE_ED(ELFDATA2MSB, 2, "big endian") - -#undef _ELF_DEFINE_ED -#define _ELF_DEFINE_ED(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_ELF_DATA_ENDIANNESS() - ED__LAST__ -}; - -/* - * Values of the magic numbers used in identification array. - */ -#define _ELF_DEFINE_ELF_MAGIC() \ -_ELF_DEFINE_EMAG(ELFMAG0, 0x7FU) \ -_ELF_DEFINE_EMAG(ELFMAG1, 'E') \ -_ELF_DEFINE_EMAG(ELFMAG2, 'L') \ -_ELF_DEFINE_EMAG(ELFMAG3, 'F') - -#undef _ELF_DEFINE_EMAG -#define _ELF_DEFINE_EMAG(N, V) N = V , -enum { - _ELF_DEFINE_ELF_MAGIC() - ELFMAG__LAST__ -}; - -/* - * ELF OS ABI field. - */ -#define _ELF_DEFINE_ELF_OSABI() \ -_ELF_DEFINE_EABI(ELFOSABI_NONE, 0, \ - "No extensions or unspecified") \ -_ELF_DEFINE_EABI(ELFOSABI_SYSV, 0, "SYSV") \ -_ELF_DEFINE_EABI(ELFOSABI_HPUX, 1, "Hewlett-Packard HP-UX") \ -_ELF_DEFINE_EABI(ELFOSABI_NETBSD, 2, "NetBSD") \ -_ELF_DEFINE_EABI(ELFOSABI_GNU, 3, "GNU") \ -_ELF_DEFINE_EABI(ELFOSABI_HURD, 4, "GNU/HURD") \ -_ELF_DEFINE_EABI(ELFOSABI_86OPEN, 5, "86Open Common ABI") \ -_ELF_DEFINE_EABI(ELFOSABI_SOLARIS, 6, "Sun Solaris") \ -_ELF_DEFINE_EABI(ELFOSABI_AIX, 7, "AIX") \ -_ELF_DEFINE_EABI(ELFOSABI_IRIX, 8, "IRIX") \ -_ELF_DEFINE_EABI(ELFOSABI_FREEBSD, 9, "FreeBSD") \ -_ELF_DEFINE_EABI(ELFOSABI_TRU64, 10, "Compaq TRU64 UNIX") \ -_ELF_DEFINE_EABI(ELFOSABI_MODESTO, 11, "Novell Modesto") \ -_ELF_DEFINE_EABI(ELFOSABI_OPENBSD, 12, "Open BSD") \ -_ELF_DEFINE_EABI(ELFOSABI_OPENVMS, 13, "Open VMS") \ -_ELF_DEFINE_EABI(ELFOSABI_NSK, 14, \ - "Hewlett-Packard Non-Stop Kernel") \ -_ELF_DEFINE_EABI(ELFOSABI_AROS, 15, "Amiga Research OS") \ -_ELF_DEFINE_EABI(ELFOSABI_FENIXOS, 16, \ - "The FenixOS highly scalable multi-core OS") \ -_ELF_DEFINE_EABI(ELFOSABI_ARM_AEABI, 64, \ - "ARM specific symbol versioning extensions") \ -_ELF_DEFINE_EABI(ELFOSABI_ARM, 97, "ARM ABI") \ -_ELF_DEFINE_EABI(ELFOSABI_STANDALONE, 255, \ - "Standalone (embedded) application") - -#undef _ELF_DEFINE_EABI -#define _ELF_DEFINE_EABI(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_ELF_OSABI() - ELFOSABI__LAST__ -}; - -#define ELFOSABI_LINUX ELFOSABI_GNU - -/* - * ELF Machine types: (EM_*). - */ -#define _ELF_DEFINE_ELF_MACHINES() \ -_ELF_DEFINE_EM(EM_NONE, 0, "No machine") \ -_ELF_DEFINE_EM(EM_M32, 1, "AT&T WE 32100") \ -_ELF_DEFINE_EM(EM_SPARC, 2, "SPARC") \ -_ELF_DEFINE_EM(EM_386, 3, "Intel 80386") \ -_ELF_DEFINE_EM(EM_68K, 4, "Motorola 68000") \ -_ELF_DEFINE_EM(EM_88K, 5, "Motorola 88000") \ -_ELF_DEFINE_EM(EM_860, 7, "Intel 80860") \ -_ELF_DEFINE_EM(EM_MIPS, 8, "MIPS I Architecture") \ -_ELF_DEFINE_EM(EM_S370, 9, "IBM System/370 Processor") \ -_ELF_DEFINE_EM(EM_MIPS_RS3_LE, 10, "MIPS RS3000 Little-endian") \ -_ELF_DEFINE_EM(EM_PARISC, 15, "Hewlett-Packard PA-RISC") \ -_ELF_DEFINE_EM(EM_VPP500, 17, "Fujitsu VPP500") \ -_ELF_DEFINE_EM(EM_SPARC32PLUS, 18, \ - "Enhanced instruction set SPARC") \ -_ELF_DEFINE_EM(EM_960, 19, "Intel 80960") \ -_ELF_DEFINE_EM(EM_PPC, 20, "PowerPC") \ -_ELF_DEFINE_EM(EM_PPC64, 21, "64-bit PowerPC") \ -_ELF_DEFINE_EM(EM_S390, 22, "IBM System/390 Processor") \ -_ELF_DEFINE_EM(EM_SPU, 23, "IBM SPU/SPC") \ -_ELF_DEFINE_EM(EM_V800, 36, "NEC V800") \ -_ELF_DEFINE_EM(EM_FR20, 37, "Fujitsu FR20") \ -_ELF_DEFINE_EM(EM_RH32, 38, "TRW RH-32") \ -_ELF_DEFINE_EM(EM_RCE, 39, "Motorola RCE") \ -_ELF_DEFINE_EM(EM_ARM, 40, "Advanced RISC Machines ARM") \ -_ELF_DEFINE_EM(EM_ALPHA, 41, "Digital Alpha") \ -_ELF_DEFINE_EM(EM_SH, 42, "Hitachi SH") \ -_ELF_DEFINE_EM(EM_SPARCV9, 43, "SPARC Version 9") \ -_ELF_DEFINE_EM(EM_TRICORE, 44, \ - "Siemens TriCore embedded processor") \ -_ELF_DEFINE_EM(EM_ARC, 45, \ - "Argonaut RISC Core, Argonaut Technologies Inc.") \ -_ELF_DEFINE_EM(EM_H8_300, 46, "Hitachi H8/300") \ -_ELF_DEFINE_EM(EM_H8_300H, 47, "Hitachi H8/300H") \ -_ELF_DEFINE_EM(EM_H8S, 48, "Hitachi H8S") \ -_ELF_DEFINE_EM(EM_H8_500, 49, "Hitachi H8/500") \ -_ELF_DEFINE_EM(EM_IA_64, 50, \ - "Intel IA-64 processor architecture") \ -_ELF_DEFINE_EM(EM_MIPS_X, 51, "Stanford MIPS-X") \ -_ELF_DEFINE_EM(EM_COLDFIRE, 52, "Motorola ColdFire") \ -_ELF_DEFINE_EM(EM_68HC12, 53, "Motorola M68HC12") \ -_ELF_DEFINE_EM(EM_MMA, 54, \ - "Fujitsu MMA Multimedia Accelerator") \ -_ELF_DEFINE_EM(EM_PCP, 55, "Siemens PCP") \ -_ELF_DEFINE_EM(EM_NCPU, 56, \ - "Sony nCPU embedded RISC processor") \ -_ELF_DEFINE_EM(EM_NDR1, 57, "Denso NDR1 microprocessor") \ -_ELF_DEFINE_EM(EM_STARCORE, 58, "Motorola Star*Core processor") \ -_ELF_DEFINE_EM(EM_ME16, 59, "Toyota ME16 processor") \ -_ELF_DEFINE_EM(EM_ST100, 60, \ - "STMicroelectronics ST100 processor") \ -_ELF_DEFINE_EM(EM_TINYJ, 61, \ - "Advanced Logic Corp. TinyJ embedded processor family") \ -_ELF_DEFINE_EM(EM_X86_64, 62, "AMD x86-64 architecture") \ -_ELF_DEFINE_EM(EM_PDSP, 63, "Sony DSP Processor") \ -_ELF_DEFINE_EM(EM_PDP10, 64, \ - "Digital Equipment Corp. PDP-10") \ -_ELF_DEFINE_EM(EM_PDP11, 65, \ - "Digital Equipment Corp. PDP-11") \ -_ELF_DEFINE_EM(EM_FX66, 66, "Siemens FX66 microcontroller") \ -_ELF_DEFINE_EM(EM_ST9PLUS, 67, \ - "STMicroelectronics ST9+ 8/16 bit microcontroller") \ -_ELF_DEFINE_EM(EM_ST7, 68, \ - "STMicroelectronics ST7 8-bit microcontroller") \ -_ELF_DEFINE_EM(EM_68HC16, 69, \ - "Motorola MC68HC16 Microcontroller") \ -_ELF_DEFINE_EM(EM_68HC11, 70, \ - "Motorola MC68HC11 Microcontroller") \ -_ELF_DEFINE_EM(EM_68HC08, 71, \ - "Motorola MC68HC08 Microcontroller") \ -_ELF_DEFINE_EM(EM_68HC05, 72, \ - "Motorola MC68HC05 Microcontroller") \ -_ELF_DEFINE_EM(EM_SVX, 73, "Silicon Graphics SVx") \ -_ELF_DEFINE_EM(EM_ST19, 74, \ - "STMicroelectronics ST19 8-bit microcontroller") \ -_ELF_DEFINE_EM(EM_VAX, 75, "Digital VAX") \ -_ELF_DEFINE_EM(EM_CRIS, 76, \ - "Axis Communications 32-bit embedded processor") \ -_ELF_DEFINE_EM(EM_JAVELIN, 77, \ - "Infineon Technologies 32-bit embedded processor") \ -_ELF_DEFINE_EM(EM_FIREPATH, 78, \ - "Element 14 64-bit DSP Processor") \ -_ELF_DEFINE_EM(EM_ZSP, 79, \ - "LSI Logic 16-bit DSP Processor") \ -_ELF_DEFINE_EM(EM_MMIX, 80, \ - "Donald Knuth's educational 64-bit processor") \ -_ELF_DEFINE_EM(EM_HUANY, 81, \ - "Harvard University machine-independent object files") \ -_ELF_DEFINE_EM(EM_PRISM, 82, "SiTera Prism") \ -_ELF_DEFINE_EM(EM_AVR, 83, \ - "Atmel AVR 8-bit microcontroller") \ -_ELF_DEFINE_EM(EM_FR30, 84, "Fujitsu FR30") \ -_ELF_DEFINE_EM(EM_D10V, 85, "Mitsubishi D10V") \ -_ELF_DEFINE_EM(EM_D30V, 86, "Mitsubishi D30V") \ -_ELF_DEFINE_EM(EM_V850, 87, "NEC v850") \ -_ELF_DEFINE_EM(EM_M32R, 88, "Mitsubishi M32R") \ -_ELF_DEFINE_EM(EM_MN10300, 89, "Matsushita MN10300") \ -_ELF_DEFINE_EM(EM_MN10200, 90, "Matsushita MN10200") \ -_ELF_DEFINE_EM(EM_PJ, 91, "picoJava") \ -_ELF_DEFINE_EM(EM_OPENRISC, 92, \ - "OpenRISC 32-bit embedded processor") \ -_ELF_DEFINE_EM(EM_ARC_COMPACT, 93, \ - "ARC International ARCompact processor") \ -_ELF_DEFINE_EM(EM_XTENSA, 94, \ - "Tensilica Xtensa Architecture") \ -_ELF_DEFINE_EM(EM_VIDEOCORE, 95, \ - "Alphamosaic VideoCore processor") \ -_ELF_DEFINE_EM(EM_TMM_GPP, 96, \ - "Thompson Multimedia General Purpose Processor") \ -_ELF_DEFINE_EM(EM_NS32K, 97, \ - "National Semiconductor 32000 series") \ -_ELF_DEFINE_EM(EM_TPC, 98, "Tenor Network TPC processor") \ -_ELF_DEFINE_EM(EM_SNP1K, 99, "Trebia SNP 1000 processor") \ -_ELF_DEFINE_EM(EM_ST200, 100, \ - "STMicroelectronics (www.st.com) ST200 microcontroller") \ -_ELF_DEFINE_EM(EM_IP2K, 101, \ - "Ubicom IP2xxx microcontroller family") \ -_ELF_DEFINE_EM(EM_MAX, 102, "MAX Processor") \ -_ELF_DEFINE_EM(EM_CR, 103, \ - "National Semiconductor CompactRISC microprocessor") \ -_ELF_DEFINE_EM(EM_F2MC16, 104, "Fujitsu F2MC16") \ -_ELF_DEFINE_EM(EM_MSP430, 105, \ - "Texas Instruments embedded microcontroller msp430") \ -_ELF_DEFINE_EM(EM_BLACKFIN, 106, \ - "Analog Devices Blackfin (DSP) processor") \ -_ELF_DEFINE_EM(EM_SE_C33, 107, \ - "S1C33 Family of Seiko Epson processors") \ -_ELF_DEFINE_EM(EM_SEP, 108, \ - "Sharp embedded microprocessor") \ -_ELF_DEFINE_EM(EM_ARCA, 109, "Arca RISC Microprocessor") \ -_ELF_DEFINE_EM(EM_UNICORE, 110, \ - "Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University") \ -_ELF_DEFINE_EM(EM_EXCESS, 111, \ - "eXcess: 16/32/64-bit configurable embedded CPU") \ -_ELF_DEFINE_EM(EM_DXP, 112, \ - "Icera Semiconductor Inc. Deep Execution Processor") \ -_ELF_DEFINE_EM(EM_ALTERA_NIOS2, 113, \ - "Altera Nios II soft-core processor") \ -_ELF_DEFINE_EM(EM_CRX, 114, \ - "National Semiconductor CompactRISC CRX microprocessor") \ -_ELF_DEFINE_EM(EM_XGATE, 115, \ - "Motorola XGATE embedded processor") \ -_ELF_DEFINE_EM(EM_C166, 116, \ - "Infineon C16x/XC16x processor") \ -_ELF_DEFINE_EM(EM_M16C, 117, \ - "Renesas M16C series microprocessors") \ -_ELF_DEFINE_EM(EM_DSPIC30F, 118, \ - "Microchip Technology dsPIC30F Digital Signal Controller") \ -_ELF_DEFINE_EM(EM_CE, 119, \ - "Freescale Communication Engine RISC core") \ -_ELF_DEFINE_EM(EM_M32C, 120, \ - "Renesas M32C series microprocessors") \ -_ELF_DEFINE_EM(EM_TSK3000, 131, "Altium TSK3000 core") \ -_ELF_DEFINE_EM(EM_RS08, 132, \ - "Freescale RS08 embedded processor") \ -_ELF_DEFINE_EM(EM_SHARC, 133, \ - "Analog Devices SHARC family of 32-bit DSP processors") \ -_ELF_DEFINE_EM(EM_ECOG2, 134, \ - "Cyan Technology eCOG2 microprocessor") \ -_ELF_DEFINE_EM(EM_SCORE7, 135, \ - "Sunplus S+core7 RISC processor") \ -_ELF_DEFINE_EM(EM_DSP24, 136, \ - "New Japan Radio (NJR) 24-bit DSP Processor") \ -_ELF_DEFINE_EM(EM_VIDEOCORE3, 137, \ - "Broadcom VideoCore III processor") \ -_ELF_DEFINE_EM(EM_LATTICEMICO32, 138, \ - "RISC processor for Lattice FPGA architecture") \ -_ELF_DEFINE_EM(EM_SE_C17, 139, "Seiko Epson C17 family") \ -_ELF_DEFINE_EM(EM_TI_C6000, 140, \ - "The Texas Instruments TMS320C6000 DSP family") \ -_ELF_DEFINE_EM(EM_TI_C2000, 141, \ - "The Texas Instruments TMS320C2000 DSP family") \ -_ELF_DEFINE_EM(EM_TI_C5500, 142, \ - "The Texas Instruments TMS320C55x DSP family") \ -_ELF_DEFINE_EM(EM_MMDSP_PLUS, 160, \ - "STMicroelectronics 64bit VLIW Data Signal Processor") \ -_ELF_DEFINE_EM(EM_CYPRESS_M8C, 161, "Cypress M8C microprocessor") \ -_ELF_DEFINE_EM(EM_R32C, 162, \ - "Renesas R32C series microprocessors") \ -_ELF_DEFINE_EM(EM_TRIMEDIA, 163, \ - "NXP Semiconductors TriMedia architecture family") \ -_ELF_DEFINE_EM(EM_QDSP6, 164, "QUALCOMM DSP6 Processor") \ -_ELF_DEFINE_EM(EM_8051, 165, "Intel 8051 and variants") \ -_ELF_DEFINE_EM(EM_STXP7X, 166, \ - "STMicroelectronics STxP7x family of configurable and extensible RISC processors") \ -_ELF_DEFINE_EM(EM_NDS32, 167, \ - "Andes Technology compact code size embedded RISC processor family") \ -_ELF_DEFINE_EM(EM_ECOG1, 168, \ - "Cyan Technology eCOG1X family") \ -_ELF_DEFINE_EM(EM_ECOG1X, 168, \ - "Cyan Technology eCOG1X family") \ -_ELF_DEFINE_EM(EM_MAXQ30, 169, \ - "Dallas Semiconductor MAXQ30 Core Micro-controllers") \ -_ELF_DEFINE_EM(EM_XIMO16, 170, \ - "New Japan Radio (NJR) 16-bit DSP Processor") \ -_ELF_DEFINE_EM(EM_MANIK, 171, \ - "M2000 Reconfigurable RISC Microprocessor") \ -_ELF_DEFINE_EM(EM_CRAYNV2, 172, \ - "Cray Inc. NV2 vector architecture") \ -_ELF_DEFINE_EM(EM_RX, 173, "Renesas RX family") \ -_ELF_DEFINE_EM(EM_METAG, 174, \ - "Imagination Technologies META processor architecture") \ -_ELF_DEFINE_EM(EM_MCST_ELBRUS, 175, \ - "MCST Elbrus general purpose hardware architecture") \ -_ELF_DEFINE_EM(EM_ECOG16, 176, \ - "Cyan Technology eCOG16 family") \ -_ELF_DEFINE_EM(EM_CR16, 177, \ - "National Semiconductor CompactRISC CR16 16-bit microprocessor") \ -_ELF_DEFINE_EM(EM_ETPU, 178, \ - "Freescale Extended Time Processing Unit") \ -_ELF_DEFINE_EM(EM_SLE9X, 179, \ - "Infineon Technologies SLE9X core") \ -_ELF_DEFINE_EM(EM_AVR32, 185, \ - "Atmel Corporation 32-bit microprocessor family") \ -_ELF_DEFINE_EM(EM_STM8, 186, \ - "STMicroeletronics STM8 8-bit microcontroller") \ -_ELF_DEFINE_EM(EM_TILE64, 187, \ - "Tilera TILE64 multicore architecture family") \ -_ELF_DEFINE_EM(EM_TILEPRO, 188, \ - "Tilera TILEPro multicore architecture family") \ -_ELF_DEFINE_EM(EM_MICROBLAZE, 189, \ - "Xilinx MicroBlaze 32-bit RISC soft processor core") \ -_ELF_DEFINE_EM(EM_CUDA, 190, "NVIDIA CUDA architecture") \ -_ELF_DEFINE_EM(EM_TILEGX, 191, \ - "Tilera TILE-Gx multicore architecture family") \ -_ELF_DEFINE_EM(EM_CLOUDSHIELD, 192, \ - "CloudShield architecture family") \ -_ELF_DEFINE_EM(EM_COREA_1ST, 193, \ - "KIPO-KAIST Core-A 1st generation processor family") \ -_ELF_DEFINE_EM(EM_COREA_2ND, 194, \ - "KIPO-KAIST Core-A 2nd generation processor family") \ -_ELF_DEFINE_EM(EM_ARC_COMPACT2, 195, "Synopsys ARCompact V2") \ -_ELF_DEFINE_EM(EM_OPEN8, 196, \ - "Open8 8-bit RISC soft processor core") \ -_ELF_DEFINE_EM(EM_RL78, 197, "Renesas RL78 family") \ -_ELF_DEFINE_EM(EM_VIDEOCORE5, 198, "Broadcom VideoCore V processor") \ -_ELF_DEFINE_EM(EM_78KOR, 199, "Renesas 78KOR family") - -#undef _ELF_DEFINE_EM -#define _ELF_DEFINE_EM(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_ELF_MACHINES() - EM__LAST__ -}; - -/* Older synonyms. */ -#define EM_ARC_A5 EM_ARC_COMPACT - -/* - * ELF file types: (ET_*). - */ -#define _ELF_DEFINE_ELF_TYPES() \ -_ELF_DEFINE_ET(ET_NONE, 0, "No file type") \ -_ELF_DEFINE_ET(ET_REL, 1, "Relocatable object") \ -_ELF_DEFINE_ET(ET_EXEC, 2, "Executable") \ -_ELF_DEFINE_ET(ET_DYN, 3, "Shared object") \ -_ELF_DEFINE_ET(ET_CORE, 4, "Core file") \ -_ELF_DEFINE_ET(ET_LOOS, 0xFE00U, "Begin OS-specific range") \ -_ELF_DEFINE_ET(ET_HIOS, 0xFEFFU, "End OS-specific range") \ -_ELF_DEFINE_ET(ET_LOPROC, 0xFF00U, "Begin processor-specific range") \ -_ELF_DEFINE_ET(ET_HIPROC, 0xFFFFU, "End processor-specific range") - -#undef _ELF_DEFINE_ET -#define _ELF_DEFINE_ET(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_ELF_TYPES() - ET__LAST__ -}; - -/* ELF file format version numbers. */ -#define EV_NONE 0 -#define EV_CURRENT 1 - -/* - * Flags for section groups. - */ -#define GRP_COMDAT 0x1 /* COMDAT semantics */ -#define GRP_MASKOS 0x0ff00000 /* OS-specific flags */ -#define GRP_MASKPROC 0xf0000000 /* processor-specific flags */ - -/* - * Flags used by program header table entries. - */ - -#define _ELF_DEFINE_PHDR_FLAGS() \ -_ELF_DEFINE_PF(PF_X, 0x1, "Execute") \ -_ELF_DEFINE_PF(PF_W, 0x2, "Write") \ -_ELF_DEFINE_PF(PF_R, 0x4, "Read") \ -_ELF_DEFINE_PF(PF_MASKOS, 0x0ff00000, "OS-specific flags") \ -_ELF_DEFINE_PF(PF_MASKPROC, 0xf0000000, "Processor-specific flags") \ -_ELF_DEFINE_PF(PF_ARM_SB, 0x10000000, \ - "segment contains the location addressed by the static base") \ -_ELF_DEFINE_PF(PF_ARM_PI, 0x20000000, \ - "segment is position-independent") \ -_ELF_DEFINE_PF(PF_ARM_ABS, 0x40000000, \ - "segment must be loaded at its base address") - -#undef _ELF_DEFINE_PF -#define _ELF_DEFINE_PF(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_PHDR_FLAGS() - PF__LAST__ -}; - -/* - * Types of program header table entries. - */ - -#define _ELF_DEFINE_PHDR_TYPES() \ -_ELF_DEFINE_PT(PT_NULL, 0, "ignored entry") \ -_ELF_DEFINE_PT(PT_LOAD, 1, "loadable segment") \ -_ELF_DEFINE_PT(PT_DYNAMIC, 2, \ - "contains dynamic linking information") \ -_ELF_DEFINE_PT(PT_INTERP, 3, "names an interpreter") \ -_ELF_DEFINE_PT(PT_NOTE, 4, "auxiliary information") \ -_ELF_DEFINE_PT(PT_SHLIB, 5, "reserved") \ -_ELF_DEFINE_PT(PT_PHDR, 6, \ - "describes the program header itself") \ -_ELF_DEFINE_PT(PT_TLS, 7, "thread local storage") \ -_ELF_DEFINE_PT(PT_LOOS, 0x60000000UL, \ - "start of OS-specific range") \ -_ELF_DEFINE_PT(PT_SUNW_UNWIND, 0x6464E550UL, \ - "Solaris/amd64 stack unwind tables") \ -_ELF_DEFINE_PT(PT_GNU_EH_FRAME, 0x6474E550UL, \ - "GCC generated .eh_frame_hdr segment") \ -_ELF_DEFINE_PT(PT_GNU_STACK, 0x6474E551UL, \ - "Stack flags") \ -_ELF_DEFINE_PT(PT_GNU_RELRO, 0x6474E552UL, \ - "Segment becomes read-only after relocation") \ -_ELF_DEFINE_PT(PT_SUNWBSS, 0x6FFFFFFAUL, \ - "A Solaris .SUNW_bss section") \ -_ELF_DEFINE_PT(PT_SUNWSTACK, 0x6FFFFFFBUL, \ - "A Solaris process stack") \ -_ELF_DEFINE_PT(PT_SUNWDTRACE, 0x6FFFFFFCUL, \ - "Used by dtrace(1)") \ -_ELF_DEFINE_PT(PT_SUNWCAP, 0x6FFFFFFDUL, \ - "Special hardware capability requirements") \ -_ELF_DEFINE_PT(PT_HIOS, 0x6FFFFFFFUL, \ - "end of OS-specific range") \ -_ELF_DEFINE_PT(PT_LOPROC, 0x70000000UL, \ - "start of processor-specific range") \ -_ELF_DEFINE_PT(PT_ARM_ARCHEXT, 0x70000000UL, \ - "platform architecture compatibility information") \ -_ELF_DEFINE_PT(PT_ARM_EXIDX, 0x70000001UL, \ - "exception unwind tables") \ -_ELF_DEFINE_PT(PT_MIPS_REGINFO, 0x70000000UL, \ - "register usage information") \ -_ELF_DEFINE_PT(PT_MIPS_RTPROC, 0x70000001UL, \ - "runtime procedure table") \ -_ELF_DEFINE_PT(PT_MIPS_OPTIONS, 0x70000002UL, \ - "options segment") \ -_ELF_DEFINE_PT(PT_HIPROC, 0x7FFFFFFFUL, \ - "end of processor-specific range") - -#undef _ELF_DEFINE_PT -#define _ELF_DEFINE_PT(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_PHDR_TYPES() - PT__LAST__ = PT_HIPROC -}; - -/* synonyms. */ -#define PT_ARM_UNWIND PT_ARM_EXIDX -#define PT_HISUNW PT_HIOS -#define PT_LOSUNW PT_SUNWBSS - -/* - * Section flags. - */ - -#define _ELF_DEFINE_SECTION_FLAGS() \ -_ELF_DEFINE_SHF(SHF_WRITE, 0x1, \ - "writable during program execution") \ -_ELF_DEFINE_SHF(SHF_ALLOC, 0x2, \ - "occupies memory during program execution") \ -_ELF_DEFINE_SHF(SHF_EXECINSTR, 0x4, "executable instructions") \ -_ELF_DEFINE_SHF(SHF_MERGE, 0x10, \ - "may be merged to prevent duplication") \ -_ELF_DEFINE_SHF(SHF_STRINGS, 0x20, \ - "NUL-terminated character strings") \ -_ELF_DEFINE_SHF(SHF_INFO_LINK, 0x40, \ - "the sh_info field holds a link") \ -_ELF_DEFINE_SHF(SHF_LINK_ORDER, 0x80, \ - "special ordering requirements during linking") \ -_ELF_DEFINE_SHF(SHF_OS_NONCONFORMING, 0x100, \ - "requires OS-specific processing during linking") \ -_ELF_DEFINE_SHF(SHF_GROUP, 0x200, \ - "member of a section group") \ -_ELF_DEFINE_SHF(SHF_TLS, 0x400, \ - "holds thread-local storage") \ -_ELF_DEFINE_SHF(SHF_MASKOS, 0x0FF00000UL, \ - "bits reserved for OS-specific semantics") \ -_ELF_DEFINE_SHF(SHF_AMD64_LARGE, 0x10000000UL, \ - "section uses large code model") \ -_ELF_DEFINE_SHF(SHF_ENTRYSECT, 0x10000000UL, \ - "section contains an entry point (ARM)") \ -_ELF_DEFINE_SHF(SHF_COMDEF, 0x80000000UL, \ - "section may be multiply defined in input to link step (ARM)") \ -_ELF_DEFINE_SHF(SHF_MIPS_GPREL, 0x10000000UL, \ - "section must be part of global data area") \ -_ELF_DEFINE_SHF(SHF_MIPS_MERGE, 0x20000000UL, \ - "section data should be merged to eliminate duplication") \ -_ELF_DEFINE_SHF(SHF_MIPS_ADDR, 0x40000000UL, \ - "section data is addressed by default") \ -_ELF_DEFINE_SHF(SHF_MIPS_STRING, 0x80000000UL, \ - "section data is string data by default") \ -_ELF_DEFINE_SHF(SHF_MIPS_NOSTRIP, 0x08000000UL, \ - "section data may not be stripped") \ -_ELF_DEFINE_SHF(SHF_MIPS_LOCAL, 0x04000000UL, \ - "section data local to process") \ -_ELF_DEFINE_SHF(SHF_MIPS_NAMES, 0x02000000UL, \ - "linker must generate implicit hidden weak names") \ -_ELF_DEFINE_SHF(SHF_MIPS_NODUPE, 0x01000000UL, \ - "linker must retain only one copy") \ -_ELF_DEFINE_SHF(SHF_ORDERED, 0x40000000UL, \ - "section is ordered with respect to other sections") \ -_ELF_DEFINE_SHF(SHF_EXCLUDE, 0x80000000UL, \ - "section is excluded from executables and shared objects") \ -_ELF_DEFINE_SHF(SHF_MASKPROC, 0xF0000000UL, \ - "bits reserved for processor-specific semantics") - -#undef _ELF_DEFINE_SHF -#define _ELF_DEFINE_SHF(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_SECTION_FLAGS() - SHF__LAST__ -}; - -/* - * Special section indices. - */ -#define _ELF_DEFINE_SECTION_INDICES() \ -_ELF_DEFINE_SHN(SHN_UNDEF, 0, "undefined section") \ -_ELF_DEFINE_SHN(SHN_LORESERVE, 0xFF00U, "start of reserved area") \ -_ELF_DEFINE_SHN(SHN_LOPROC, 0xFF00U, \ - "start of processor-specific range") \ -_ELF_DEFINE_SHN(SHN_BEFORE, 0xFF00U, "used for section ordering") \ -_ELF_DEFINE_SHN(SHN_AFTER, 0xFF01U, "used for section ordering") \ -_ELF_DEFINE_SHN(SHN_AMD64_LCOMMON, 0xFF02U, "large common block label") \ -_ELF_DEFINE_SHN(SHN_MIPS_ACOMMON, 0xFF00U, \ - "allocated common symbols in a DSO") \ -_ELF_DEFINE_SHN(SHN_MIPS_TEXT, 0xFF01U, "Reserved (obsolete)") \ -_ELF_DEFINE_SHN(SHN_MIPS_DATA, 0xFF02U, "Reserved (obsolete)") \ -_ELF_DEFINE_SHN(SHN_MIPS_SCOMMON, 0xFF03U, \ - "gp-addressable common symbols") \ -_ELF_DEFINE_SHN(SHN_MIPS_SUNDEFINED, 0xFF04U, \ - "gp-addressable undefined symbols") \ -_ELF_DEFINE_SHN(SHN_MIPS_LCOMMON, 0xFF05U, "local common symbols") \ -_ELF_DEFINE_SHN(SHN_MIPS_LUNDEFINED, 0xFF06U, \ - "local undefined symbols") \ -_ELF_DEFINE_SHN(SHN_HIPROC, 0xFF1FU, \ - "end of processor-specific range") \ -_ELF_DEFINE_SHN(SHN_LOOS, 0xFF20U, \ - "start of OS-specific range") \ -_ELF_DEFINE_SHN(SHN_SUNW_IGNORE, 0xFF3FU, "used by dtrace") \ -_ELF_DEFINE_SHN(SHN_HIOS, 0xFF3FU, \ - "end of OS-specific range") \ -_ELF_DEFINE_SHN(SHN_ABS, 0xFFF1U, "absolute references") \ -_ELF_DEFINE_SHN(SHN_COMMON, 0xFFF2U, "references to COMMON areas") \ -_ELF_DEFINE_SHN(SHN_XINDEX, 0xFFFFU, "extended index") \ -_ELF_DEFINE_SHN(SHN_HIRESERVE, 0xFFFFU, "end of reserved area") - -#undef _ELF_DEFINE_SHN -#define _ELF_DEFINE_SHN(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_SECTION_INDICES() - SHN__LAST__ -}; - -/* - * Section types. - */ - -#define _ELF_DEFINE_SECTION_TYPES() \ -_ELF_DEFINE_SHT(SHT_NULL, 0, "inactive header") \ -_ELF_DEFINE_SHT(SHT_PROGBITS, 1, "program defined information") \ -_ELF_DEFINE_SHT(SHT_SYMTAB, 2, "symbol table") \ -_ELF_DEFINE_SHT(SHT_STRTAB, 3, "string table") \ -_ELF_DEFINE_SHT(SHT_RELA, 4, \ - "relocation entries with addends") \ -_ELF_DEFINE_SHT(SHT_HASH, 5, "symbol hash table") \ -_ELF_DEFINE_SHT(SHT_DYNAMIC, 6, \ - "information for dynamic linking") \ -_ELF_DEFINE_SHT(SHT_NOTE, 7, "additional notes") \ -_ELF_DEFINE_SHT(SHT_NOBITS, 8, "section occupying no space") \ -_ELF_DEFINE_SHT(SHT_REL, 9, \ - "relocation entries without addends") \ -_ELF_DEFINE_SHT(SHT_SHLIB, 10, "reserved") \ -_ELF_DEFINE_SHT(SHT_DYNSYM, 11, "symbol table") \ -_ELF_DEFINE_SHT(SHT_INIT_ARRAY, 14, \ - "pointers to initialization functions") \ -_ELF_DEFINE_SHT(SHT_FINI_ARRAY, 15, \ - "pointers to termination functions") \ -_ELF_DEFINE_SHT(SHT_PREINIT_ARRAY, 16, \ - "pointers to functions called before initialization") \ -_ELF_DEFINE_SHT(SHT_GROUP, 17, "defines a section group") \ -_ELF_DEFINE_SHT(SHT_SYMTAB_SHNDX, 18, \ - "used for extended section numbering") \ -_ELF_DEFINE_SHT(SHT_LOOS, 0x60000000UL, \ - "start of OS-specific range") \ -_ELF_DEFINE_SHT(SHT_SUNW_dof, 0x6FFFFFF4UL, \ - "used by dtrace") \ -_ELF_DEFINE_SHT(SHT_SUNW_cap, 0x6FFFFFF5UL, \ - "capability requirements") \ -_ELF_DEFINE_SHT(SHT_GNU_ATTRIBUTES, 0x6FFFFFF5UL, \ - "object attributes") \ -_ELF_DEFINE_SHT(SHT_SUNW_SIGNATURE, 0x6FFFFFF6UL, \ - "module verification signature") \ -_ELF_DEFINE_SHT(SHT_GNU_HASH, 0x6FFFFFF6UL, \ - "GNU Hash sections") \ -_ELF_DEFINE_SHT(SHT_GNU_LIBLIST, 0x6FFFFFF7UL, \ - "List of libraries to be prelinked") \ -_ELF_DEFINE_SHT(SHT_SUNW_ANNOTATE, 0x6FFFFFF7UL, \ - "special section where unresolved references are allowed") \ -_ELF_DEFINE_SHT(SHT_SUNW_DEBUGSTR, 0x6FFFFFF8UL, \ - "debugging information") \ -_ELF_DEFINE_SHT(SHT_CHECKSUM, 0x6FFFFFF8UL, \ - "checksum for dynamic shared objects") \ -_ELF_DEFINE_SHT(SHT_SUNW_DEBUG, 0x6FFFFFF9UL, \ - "debugging information") \ -_ELF_DEFINE_SHT(SHT_SUNW_move, 0x6FFFFFFAUL, \ - "information to handle partially initialized symbols") \ -_ELF_DEFINE_SHT(SHT_SUNW_COMDAT, 0x6FFFFFFBUL, \ - "section supporting merging of multiple copies of data") \ -_ELF_DEFINE_SHT(SHT_SUNW_syminfo, 0x6FFFFFFCUL, \ - "additional symbol information") \ -_ELF_DEFINE_SHT(SHT_SUNW_verdef, 0x6FFFFFFDUL, \ - "symbol versioning information") \ -_ELF_DEFINE_SHT(SHT_SUNW_verneed, 0x6FFFFFFEUL, \ - "symbol versioning requirements") \ -_ELF_DEFINE_SHT(SHT_SUNW_versym, 0x6FFFFFFFUL, \ - "symbol versioning table") \ -_ELF_DEFINE_SHT(SHT_HIOS, 0x6FFFFFFFUL, \ - "end of OS-specific range") \ -_ELF_DEFINE_SHT(SHT_LOPROC, 0x70000000UL, \ - "start of processor-specific range") \ -_ELF_DEFINE_SHT(SHT_ARM_EXIDX, 0x70000001UL, \ - "exception index table") \ -_ELF_DEFINE_SHT(SHT_ARM_PREEMPTMAP, 0x70000002UL, \ - "BPABI DLL dynamic linking preemption map") \ -_ELF_DEFINE_SHT(SHT_ARM_ATTRIBUTES, 0x70000003UL, \ - "object file compatibility attributes") \ -_ELF_DEFINE_SHT(SHT_ARM_DEBUGOVERLAY, 0x70000004UL, \ - "overlay debug information") \ -_ELF_DEFINE_SHT(SHT_ARM_OVERLAYSECTION, 0x70000005UL, \ - "overlay debug information") \ -_ELF_DEFINE_SHT(SHT_MIPS_LIBLIST, 0x70000000UL, \ - "DSO library information used in link") \ -_ELF_DEFINE_SHT(SHT_MIPS_MSYM, 0x70000001UL, \ - "MIPS symbol table extension") \ -_ELF_DEFINE_SHT(SHT_MIPS_CONFLICT, 0x70000002UL, \ - "symbol conflicting with DSO-defined symbols ") \ -_ELF_DEFINE_SHT(SHT_MIPS_GPTAB, 0x70000003UL, \ - "global pointer table") \ -_ELF_DEFINE_SHT(SHT_MIPS_UCODE, 0x70000004UL, \ - "reserved") \ -_ELF_DEFINE_SHT(SHT_MIPS_DEBUG, 0x70000005UL, \ - "reserved (obsolete debug information)") \ -_ELF_DEFINE_SHT(SHT_MIPS_REGINFO, 0x70000006UL, \ - "register usage information") \ -_ELF_DEFINE_SHT(SHT_MIPS_PACKAGE, 0x70000007UL, \ - "OSF reserved") \ -_ELF_DEFINE_SHT(SHT_MIPS_PACKSYM, 0x70000008UL, \ - "OSF reserved") \ -_ELF_DEFINE_SHT(SHT_MIPS_RELD, 0x70000009UL, \ - "dynamic relocation") \ -_ELF_DEFINE_SHT(SHT_MIPS_IFACE, 0x7000000BUL, \ - "subprogram interface information") \ -_ELF_DEFINE_SHT(SHT_MIPS_CONTENT, 0x7000000CUL, \ - "section content classification") \ -_ELF_DEFINE_SHT(SHT_MIPS_OPTIONS, 0x7000000DUL, \ - "general options") \ -_ELF_DEFINE_SHT(SHT_MIPS_DELTASYM, 0x7000001BUL, \ - "Delta C++: symbol table") \ -_ELF_DEFINE_SHT(SHT_MIPS_DELTAINST, 0x7000001CUL, \ - "Delta C++: instance table") \ -_ELF_DEFINE_SHT(SHT_MIPS_DELTACLASS, 0x7000001DUL, \ - "Delta C++: class table") \ -_ELF_DEFINE_SHT(SHT_MIPS_DWARF, 0x7000001EUL, \ - "DWARF debug information") \ -_ELF_DEFINE_SHT(SHT_MIPS_DELTADECL, 0x7000001FUL, \ - "Delta C++: declarations") \ -_ELF_DEFINE_SHT(SHT_MIPS_SYMBOL_LIB, 0x70000020UL, \ - "symbol-to-library mapping") \ -_ELF_DEFINE_SHT(SHT_MIPS_EVENTS, 0x70000021UL, \ - "event locations") \ -_ELF_DEFINE_SHT(SHT_MIPS_TRANSLATE, 0x70000022UL, \ - "???") \ -_ELF_DEFINE_SHT(SHT_MIPS_PIXIE, 0x70000023UL, \ - "special pixie sections") \ -_ELF_DEFINE_SHT(SHT_MIPS_XLATE, 0x70000024UL, \ - "address translation table") \ -_ELF_DEFINE_SHT(SHT_MIPS_XLATE_DEBUG, 0x70000025UL, \ - "SGI internal address translation table") \ -_ELF_DEFINE_SHT(SHT_MIPS_WHIRL, 0x70000026UL, \ - "intermediate code") \ -_ELF_DEFINE_SHT(SHT_MIPS_EH_REGION, 0x70000027UL, \ - "C++ exception handling region info") \ -_ELF_DEFINE_SHT(SHT_MIPS_XLATE_OLD, 0x70000028UL, \ - "obsolete") \ -_ELF_DEFINE_SHT(SHT_MIPS_PDR_EXCEPTION, 0x70000029UL, \ - "runtime procedure descriptor table exception information") \ -_ELF_DEFINE_SHT(SHT_SPARC_GOTDATA, 0x70000000UL, \ - "SPARC-specific data") \ -_ELF_DEFINE_SHT(SHT_AMD64_UNWIND, 0x70000001UL, \ - "unwind tables for the AMD64") \ -_ELF_DEFINE_SHT(SHT_ORDERED, 0x7FFFFFFFUL, \ - "sort entries in the section") \ -_ELF_DEFINE_SHT(SHT_HIPROC, 0x7FFFFFFFUL, \ - "end of processor-specific range") \ -_ELF_DEFINE_SHT(SHT_LOUSER, 0x80000000UL, \ - "start of application-specific range") \ -_ELF_DEFINE_SHT(SHT_HIUSER, 0xFFFFFFFFUL, \ - "end of application-specific range") - -#undef _ELF_DEFINE_SHT -#define _ELF_DEFINE_SHT(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_SECTION_TYPES() - SHT__LAST__ = SHT_HIUSER -}; - -/* Aliases for section types. */ -#define SHT_GNU_verdef SHT_SUNW_verdef -#define SHT_GNU_verneed SHT_SUNW_verneed -#define SHT_GNU_versym SHT_SUNW_versym - -/* - * Symbol binding information. - */ - -#define _ELF_DEFINE_SYMBOL_BINDING() \ -_ELF_DEFINE_STB(STB_LOCAL, 0, \ - "not visible outside defining object file") \ -_ELF_DEFINE_STB(STB_GLOBAL, 1, \ - "visible across all object files being combined") \ -_ELF_DEFINE_STB(STB_WEAK, 2, \ - "visible across all object files but with low precedence") \ -_ELF_DEFINE_STB(STB_LOOS, 10, "start of OS-specific range") \ -_ELF_DEFINE_STB(STB_HIOS, 12, "end of OS-specific range") \ -_ELF_DEFINE_STB(STB_LOPROC, 13, \ - "start of processor-specific range") \ -_ELF_DEFINE_STB(STB_HIPROC, 15, \ - "end of processor-specific range") - -#undef _ELF_DEFINE_STB -#define _ELF_DEFINE_STB(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_SYMBOL_BINDING() - STB__LAST__ -}; - -/* - * Symbol types - */ - -#define _ELF_DEFINE_SYMBOL_TYPES() \ -_ELF_DEFINE_STT(STT_NOTYPE, 0, "unspecified type") \ -_ELF_DEFINE_STT(STT_OBJECT, 1, "data object") \ -_ELF_DEFINE_STT(STT_FUNC, 2, "executable code") \ -_ELF_DEFINE_STT(STT_SECTION, 3, "section") \ -_ELF_DEFINE_STT(STT_FILE, 4, "source file") \ -_ELF_DEFINE_STT(STT_COMMON, 5, "uninitialized common block") \ -_ELF_DEFINE_STT(STT_TLS, 6, "thread local storage") \ -_ELF_DEFINE_STT(STT_LOOS, 10, "start of OS-specific types") \ -_ELF_DEFINE_STT(STT_HIOS, 12, "end of OS-specific types") \ -_ELF_DEFINE_STT(STT_LOPROC, 13, \ - "start of processor-specific types") \ -_ELF_DEFINE_STT(STT_ARM_TFUNC, 13, "Thumb function (GNU)") \ -_ELF_DEFINE_STT(STT_ARM_16BIT, 15, "Thumb label (GNU)") \ -_ELF_DEFINE_STT(STT_HIPROC, 15, \ - "end of processor-specific types") - -#undef _ELF_DEFINE_STT -#define _ELF_DEFINE_STT(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_SYMBOL_TYPES() - STT__LAST__ -}; - -/* - * Symbol binding. - */ - -#define _ELF_DEFINE_SYMBOL_BINDING_KINDS() \ -_ELF_DEFINE_SYB(SYMINFO_BT_SELF, 0xFFFFU, \ - "bound to self") \ -_ELF_DEFINE_SYB(SYMINFO_BT_PARENT, 0xFFFEU, \ - "bound to parent") \ -_ELF_DEFINE_SYB(SYMINFO_BT_NONE, 0xFFFDU, \ - "no special binding") - -#undef _ELF_DEFINE_SYB -#define _ELF_DEFINE_SYB(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_SYMBOL_BINDING_KINDS() - SYMINFO__LAST__ -}; - -/* - * Symbol visibility. - */ - -#define _ELF_DEFINE_SYMBOL_VISIBILITY() \ -_ELF_DEFINE_STV(STV_DEFAULT, 0, \ - "as specified by symbol type") \ -_ELF_DEFINE_STV(STV_INTERNAL, 1, \ - "as defined by processor semantics") \ -_ELF_DEFINE_STV(STV_HIDDEN, 2, \ - "hidden from other components") \ -_ELF_DEFINE_STV(STV_PROTECTED, 3, \ - "local references are not preemptable") - -#undef _ELF_DEFINE_STV -#define _ELF_DEFINE_STV(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_SYMBOL_VISIBILITY() - STV__LAST__ -}; - -/* - * Symbol flags. - */ -#define _ELF_DEFINE_SYMBOL_FLAGS() \ -_ELF_DEFINE_SYF(SYMINFO_FLG_DIRECT, 0x01, \ - "directly assocated reference") \ -_ELF_DEFINE_SYF(SYMINFO_FLG_COPY, 0x04, \ - "definition by copy-relocation") \ -_ELF_DEFINE_SYF(SYMINFO_FLG_LAZYLOAD, 0x08, \ - "object should be lazily loaded") \ -_ELF_DEFINE_SYF(SYMINFO_FLG_DIRECTBIND, 0x10, \ - "reference should be directly bound") \ -_ELF_DEFINE_SYF(SYMINFO_FLG_NOEXTDIRECT, 0x20, \ - "external references not allowed to bind to definition") - -#undef _ELF_DEFINE_SYF -#define _ELF_DEFINE_SYF(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_SYMBOL_FLAGS() - SYMINFO_FLG__LAST__ -}; - -/* - * Version dependencies. - */ -#define _ELF_DEFINE_VERSIONING_DEPENDENCIES() \ -_ELF_DEFINE_VERD(VER_NDX_LOCAL, 0, "local scope") \ -_ELF_DEFINE_VERD(VER_NDX_GLOBAL, 1, "global scope") -#undef _ELF_DEFINE_VERD -#define _ELF_DEFINE_VERD(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_VERSIONING_DEPENDENCIES() - VER_NDX__LAST__ -}; - -/* - * Version flags. - */ -#define _ELF_DEFINE_VERSIONING_FLAGS() \ -_ELF_DEFINE_VERF(VER_FLG_BASE, 0x1, "file version") \ -_ELF_DEFINE_VERF(VER_FLG_WEAK, 0x2, "weak version") -#undef _ELF_DEFINE_VERF -#define _ELF_DEFINE_VERF(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_VERSIONING_FLAGS() - VER_FLG__LAST__ -}; - -/* - * Version needs - */ -#define _ELF_DEFINE_VERSIONING_NEEDS() \ -_ELF_DEFINE_VRN(VER_NEED_NONE, 0, "invalid version") \ -_ELF_DEFINE_VRN(VER_NEED_CURRENT, 1, "current version") -#undef _ELF_DEFINE_VRN -#define _ELF_DEFINE_VRN(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_VERSIONING_NEEDS() - VER_NEED__LAST__ -}; - -/* - * Version numbers. - */ -#define _ELF_DEFINE_VERSIONING_NUMBERS() \ -_ELF_DEFINE_VRNU(VER_DEF_NONE, 0, "invalid version") \ -_ELF_DEFINE_VRNU(VER_DEF_CURRENT, 1, "current version") -#undef _ELF_DEFINE_VRNU -#define _ELF_DEFINE_VRNU(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_VERSIONING_NUMBERS() - VER_DEF__LAST__ -}; - -/** - ** Relocation types. - **/ - -#define _ELF_DEFINE_386_RELOCATIONS() \ -_ELF_DEFINE_RELOC(R_386_NONE, 0) \ -_ELF_DEFINE_RELOC(R_386_32, 1) \ -_ELF_DEFINE_RELOC(R_386_PC32, 2) \ -_ELF_DEFINE_RELOC(R_386_GOT32, 3) \ -_ELF_DEFINE_RELOC(R_386_PLT32, 4) \ -_ELF_DEFINE_RELOC(R_386_COPY, 5) \ -_ELF_DEFINE_RELOC(R_386_GLOB_DAT, 6) \ -_ELF_DEFINE_RELOC(R_386_JMP_SLOT, 7) \ -_ELF_DEFINE_RELOC(R_386_RELATIVE, 8) \ -_ELF_DEFINE_RELOC(R_386_GOTOFF, 9) \ -_ELF_DEFINE_RELOC(R_386_GOTPC, 10) \ -_ELF_DEFINE_RELOC(R_386_32PLT, 11) \ -_ELF_DEFINE_RELOC(R_386_16, 20) \ -_ELF_DEFINE_RELOC(R_386_PC16, 21) \ -_ELF_DEFINE_RELOC(R_386_8, 22) \ -_ELF_DEFINE_RELOC(R_386_PC8, 23) - -/* - * These are the symbols used in the Sun ``Linkers and Loaders - * Guide'', Document No: 817-1984-17. See the X86_64 relocations list - * below for the spellings used in the ELF specification. - */ -#define _ELF_DEFINE_AMD64_RELOCATIONS() \ -_ELF_DEFINE_RELOC(R_AMD64_NONE, 0) \ -_ELF_DEFINE_RELOC(R_AMD64_64, 1) \ -_ELF_DEFINE_RELOC(R_AMD64_PC32, 2) \ -_ELF_DEFINE_RELOC(R_AMD64_GOT32, 3) \ -_ELF_DEFINE_RELOC(R_AMD64_PLT32, 4) \ -_ELF_DEFINE_RELOC(R_AMD64_COPY, 5) \ -_ELF_DEFINE_RELOC(R_AMD64_GLOB_DAT, 6) \ -_ELF_DEFINE_RELOC(R_AMD64_JUMP_SLOT, 7) \ -_ELF_DEFINE_RELOC(R_AMD64_RELATIVE, 8) \ -_ELF_DEFINE_RELOC(R_AMD64_GOTPCREL, 9) \ -_ELF_DEFINE_RELOC(R_AMD64_32, 10) \ -_ELF_DEFINE_RELOC(R_AMD64_32S, 11) \ -_ELF_DEFINE_RELOC(R_AMD64_16, 12) \ -_ELF_DEFINE_RELOC(R_AMD64_PC16, 13) \ -_ELF_DEFINE_RELOC(R_AMD64_8, 14) \ -_ELF_DEFINE_RELOC(R_AMD64_PC8, 15) \ -_ELF_DEFINE_RELOC(R_AMD64_PC64, 24) \ -_ELF_DEFINE_RELOC(R_AMD64_GOTOFF64, 25) \ -_ELF_DEFINE_RELOC(R_AMD64_GOTPC32, 26) - -#define _ELF_DEFINE_ARM_RELOCATIONS() \ -_ELF_DEFINE_RELOC(R_ARM_NONE, 0) \ -_ELF_DEFINE_RELOC(R_ARM_PC24, 1) \ -_ELF_DEFINE_RELOC(R_ARM_ABS32, 2) \ -_ELF_DEFINE_RELOC(R_ARM_REL32, 3) \ -_ELF_DEFINE_RELOC(R_ARM_LDR_PC_G0, 4) \ -_ELF_DEFINE_RELOC(R_ARM_ABS16, 5) \ -_ELF_DEFINE_RELOC(R_ARM_ABS12, 6) \ -_ELF_DEFINE_RELOC(R_ARM_THM_ABS5, 7) \ -_ELF_DEFINE_RELOC(R_ARM_ABS8, 8) \ -_ELF_DEFINE_RELOC(R_ARM_SBREL32, 9) \ -_ELF_DEFINE_RELOC(R_ARM_THM_CALL, 10) \ -_ELF_DEFINE_RELOC(R_ARM_THM_PC8, 11) \ -_ELF_DEFINE_RELOC(R_ARM_BREL_ADJ, 12) \ -_ELF_DEFINE_RELOC(R_ARM_SWI24, 13) \ -_ELF_DEFINE_RELOC(R_ARM_THM_SWI8, 14) \ -_ELF_DEFINE_RELOC(R_ARM_XPC25, 15) \ -_ELF_DEFINE_RELOC(R_ARM_THM_XPC22, 16) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_DTPMOD32, 17) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_DTPOFF32, 18) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_TPOFF32, 19) \ -_ELF_DEFINE_RELOC(R_ARM_COPY, 20) \ -_ELF_DEFINE_RELOC(R_ARM_GLOB_DAT, 21) \ -_ELF_DEFINE_RELOC(R_ARM_JUMP_SLOT, 22) \ -_ELF_DEFINE_RELOC(R_ARM_RELATIVE, 23) \ -_ELF_DEFINE_RELOC(R_ARM_GOTOFF32, 24) \ -_ELF_DEFINE_RELOC(R_ARM_BASE_PREL, 25) \ -_ELF_DEFINE_RELOC(R_ARM_GOT_BREL, 26) \ -_ELF_DEFINE_RELOC(R_ARM_PLT32, 27) \ -_ELF_DEFINE_RELOC(R_ARM_CALL, 28) \ -_ELF_DEFINE_RELOC(R_ARM_JUMP24, 29) \ -_ELF_DEFINE_RELOC(R_ARM_THM_JUMP24, 30) \ -_ELF_DEFINE_RELOC(R_ARM_BASE_ABS, 31) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_PCREL7_0, 32) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_PCREL15_8, 33) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_PCREL23_15, 34) \ -_ELF_DEFINE_RELOC(R_ARM_LDR_SBREL_11_0, 35) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_SBREL_19_12, 36) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_SBREL_27_20, 37) \ -_ELF_DEFINE_RELOC(R_ARM_TARGET1, 38) \ -_ELF_DEFINE_RELOC(R_ARM_SBREL31, 39) \ -_ELF_DEFINE_RELOC(R_ARM_V4BX, 40) \ -_ELF_DEFINE_RELOC(R_ARM_TARGET2, 41) \ -_ELF_DEFINE_RELOC(R_ARM_PREL31, 42) \ -_ELF_DEFINE_RELOC(R_ARM_MOVW_ABS_NC, 43) \ -_ELF_DEFINE_RELOC(R_ARM_MOVT_ABS, 44) \ -_ELF_DEFINE_RELOC(R_ARM_MOVW_PREL_NC, 45) \ -_ELF_DEFINE_RELOC(R_ARM_MOVT_PREL, 46) \ -_ELF_DEFINE_RELOC(R_ARM_THM_MOVW_ABS_NC, 47) \ -_ELF_DEFINE_RELOC(R_ARM_THM_MOVT_ABS, 48) \ -_ELF_DEFINE_RELOC(R_ARM_MOVW_PREL_NC, 49) \ -_ELF_DEFINE_RELOC(R_ARM_THM_MOVT_PREL, 50) \ -_ELF_DEFINE_RELOC(R_ARM_THM_JUMP19, 51) \ -_ELF_DEFINE_RELOC(R_ARM_THM_JUMP6, 52) \ -_ELF_DEFINE_RELOC(R_ARM_THM_ALU_PREL_11_0, 53) \ -_ELF_DEFINE_RELOC(R_ARM_THM_PC12, 54) \ -_ELF_DEFINE_RELOC(R_ARM_ABS32_NOI, 55) \ -_ELF_DEFINE_RELOC(R_ARM_REL32_NOI, 56) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_PC_G0_NC, 57) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_PC_G0, 58) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_PC_G1_NC, 59) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_PC_G1, 60) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_PC_G2, 61) \ -_ELF_DEFINE_RELOC(R_ARM_LDR_PC_G1, 62) \ -_ELF_DEFINE_RELOC(R_ARM_LDR_PC_G2, 63) \ -_ELF_DEFINE_RELOC(R_ARM_LDRS_PC_G0, 64) \ -_ELF_DEFINE_RELOC(R_ARM_LDRS_PC_G1, 65) \ -_ELF_DEFINE_RELOC(R_ARM_LDRS_PC_G2, 66) \ -_ELF_DEFINE_RELOC(R_ARM_LDC_PC_G0, 67) \ -_ELF_DEFINE_RELOC(R_ARM_LDC_PC_G1, 68) \ -_ELF_DEFINE_RELOC(R_ARM_LDC_PC_G2, 69) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_SB_G0_NC, 70) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_SB_G0, 71) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_SB_G1_NC, 72) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_SB_G1, 73) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_SB_G2, 74) \ -_ELF_DEFINE_RELOC(R_ARM_LDR_SB_G0, 75) \ -_ELF_DEFINE_RELOC(R_ARM_LDR_SB_G1, 76) \ -_ELF_DEFINE_RELOC(R_ARM_LDR_SB_G2, 77) \ -_ELF_DEFINE_RELOC(R_ARM_LDRS_SB_G0, 78) \ -_ELF_DEFINE_RELOC(R_ARM_LDRS_SB_G1, 79) \ -_ELF_DEFINE_RELOC(R_ARM_LDRS_SB_G2, 80) \ -_ELF_DEFINE_RELOC(R_ARM_LDC_SB_G0, 81) \ -_ELF_DEFINE_RELOC(R_ARM_LDC_SB_G1, 82) \ -_ELF_DEFINE_RELOC(R_ARM_LDC_SB_G2, 83) \ -_ELF_DEFINE_RELOC(R_ARM_MOVW_BREL_NC, 84) \ -_ELF_DEFINE_RELOC(R_ARM_MOVT_BREL, 85) \ -_ELF_DEFINE_RELOC(R_ARM_MOVW_BREL, 86) \ -_ELF_DEFINE_RELOC(R_ARM_THM_MOVW_BREL_NC, 87) \ -_ELF_DEFINE_RELOC(R_ARM_THM_MOVT_BREL, 88) \ -_ELF_DEFINE_RELOC(R_ARM_THM_MOVW_BREL, 89) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_GOTDESC, 90) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_CALL, 91) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_DESCSEQ, 92) \ -_ELF_DEFINE_RELOC(R_ARM_THM_TLS_CALL, 93) \ -_ELF_DEFINE_RELOC(R_ARM_PLT32_ABS, 94) \ -_ELF_DEFINE_RELOC(R_ARM_GOT_ABS, 95) \ -_ELF_DEFINE_RELOC(R_ARM_GOT_PREL, 96) \ -_ELF_DEFINE_RELOC(R_ARM_GOT_BREL12, 97) \ -_ELF_DEFINE_RELOC(R_ARM_GOTOFF12, 98) \ -_ELF_DEFINE_RELOC(R_ARM_GOTRELAX, 99) \ -_ELF_DEFINE_RELOC(R_ARM_GNU_VTENTRY, 100) \ -_ELF_DEFINE_RELOC(R_ARM_GNU_VTINHERIT, 101) \ -_ELF_DEFINE_RELOC(R_ARM_THM_JUMP11, 102) \ -_ELF_DEFINE_RELOC(R_ARM_THM_JUMP8, 103) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_GD32, 104) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_LDM32, 105) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_LDO32, 106) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_IE32, 107) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_LE32, 108) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_LDO12, 109) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_LE12, 110) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_IE12GP, 111) \ -_ELF_DEFINE_RELOC(R_ARM_ME_TOO, 128) \ -_ELF_DEFINE_RELOC(R_ARM_THM_TLS_DESCSEQ16, 129) \ -_ELF_DEFINE_RELOC(R_ARM_THM_TLS_DESCSEQ32, 130) - -#define _ELF_DEFINE_IA64_RELOCATIONS() \ -_ELF_DEFINE_RELOC(R_IA_64_NONE, 0) \ -_ELF_DEFINE_RELOC(R_IA_64_IMM14, 0x21) \ -_ELF_DEFINE_RELOC(R_IA_64_IMM22, 0x22) \ -_ELF_DEFINE_RELOC(R_IA_64_IMM64, 0x23) \ -_ELF_DEFINE_RELOC(R_IA_64_DIR32MSB, 0x24) \ -_ELF_DEFINE_RELOC(R_IA_64_DIR32LSB, 0x25) \ -_ELF_DEFINE_RELOC(R_IA_64_DIR64MSB, 0x26) \ -_ELF_DEFINE_RELOC(R_IA_64_DIR64LSB, 0x27) \ -_ELF_DEFINE_RELOC(R_IA_64_GPREL22, 0x2a) \ -_ELF_DEFINE_RELOC(R_IA_64_GPREL64I, 0x2b) \ -_ELF_DEFINE_RELOC(R_IA_64_GPREL32MSB, 0x2c) \ -_ELF_DEFINE_RELOC(R_IA_64_GPREL32LSB, 0x2d) \ -_ELF_DEFINE_RELOC(R_IA_64_GPREL64MSB, 0x2e) \ -_ELF_DEFINE_RELOC(R_IA_64_GPREL64LSB, 0x2f) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF22, 0x32) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF64I, 0x33) \ -_ELF_DEFINE_RELOC(R_IA_64_PLTOFF22, 0x3a) \ -_ELF_DEFINE_RELOC(R_IA_64_PLTOFF64I, 0x3b) \ -_ELF_DEFINE_RELOC(R_IA_64_PLTOFF64MSB, 0x3e) \ -_ELF_DEFINE_RELOC(R_IA_64_PLTOFF64LSB, 0x3f) \ -_ELF_DEFINE_RELOC(R_IA_64_FPTR64I, 0x43) \ -_ELF_DEFINE_RELOC(R_IA_64_FPTR32MSB, 0x44) \ -_ELF_DEFINE_RELOC(R_IA_64_FPTR32LSB, 0x45) \ -_ELF_DEFINE_RELOC(R_IA_64_FPTR64MSB, 0x46) \ -_ELF_DEFINE_RELOC(R_IA_64_FPTR64LSB, 0x47) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL60B, 0x48) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL21B, 0x49) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL21M, 0x4a) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL21F, 0x4b) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL32MSB, 0x4c) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL32LSB, 0x4d) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL64MSB, 0x4e) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL64LSB, 0x4f) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF_FPTR22, 0x52) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF_FPTR64I, 0x53) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF_FPTR32MSB, 0x54) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF_FPTR32LSB, 0x55) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF_FPTR64MSB, 0x56) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF_FPTR64LSB, 0x57) \ -_ELF_DEFINE_RELOC(R_IA_64_SEGREL32MSB, 0x5c) \ -_ELF_DEFINE_RELOC(R_IA_64_SEGREL32LSB, 0x5d) \ -_ELF_DEFINE_RELOC(R_IA_64_SEGREL64MSB, 0x5e) \ -_ELF_DEFINE_RELOC(R_IA_64_SEGREL64LSB, 0x5f) \ -_ELF_DEFINE_RELOC(R_IA_64_SECREL32MSB, 0x64) \ -_ELF_DEFINE_RELOC(R_IA_64_SECREL32LSB, 0x65) \ -_ELF_DEFINE_RELOC(R_IA_64_SECREL64MSB, 0x66) \ -_ELF_DEFINE_RELOC(R_IA_64_SECREL64LSB, 0x67) \ -_ELF_DEFINE_RELOC(R_IA_64_REL32MSB, 0x6c) \ -_ELF_DEFINE_RELOC(R_IA_64_REL32LSB, 0x6d) \ -_ELF_DEFINE_RELOC(R_IA_64_REL64MSB, 0x6e) \ -_ELF_DEFINE_RELOC(R_IA_64_REL64LSB, 0x6f) \ -_ELF_DEFINE_RELOC(R_IA_64_LTV32MSB, 0x74) \ -_ELF_DEFINE_RELOC(R_IA_64_LTV32LSB, 0x75) \ -_ELF_DEFINE_RELOC(R_IA_64_LTV64MSB, 0x76) \ -_ELF_DEFINE_RELOC(R_IA_64_LTV64LSB, 0x77) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL21BIa, 0x79) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL22, 0x7A) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL64I, 0x7B) \ -_ELF_DEFINE_RELOC(R_IA_64_IPLTMSB, 0x80) \ -_ELF_DEFINE_RELOC(R_IA_64_IPLTLSB, 0x81) \ -_ELF_DEFINE_RELOC(R_IA_64_SUB, 0x85) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF22X, 0x86) \ -_ELF_DEFINE_RELOC(R_IA_64_LDXMOV, 0x87) \ -_ELF_DEFINE_RELOC(R_IA_64_TPREL14, 0x91) \ -_ELF_DEFINE_RELOC(R_IA_64_TPREL22, 0x92) \ -_ELF_DEFINE_RELOC(R_IA_64_TPREL64I, 0x93) \ -_ELF_DEFINE_RELOC(R_IA_64_TPREL64MSB, 0x96) \ -_ELF_DEFINE_RELOC(R_IA_64_TPREL64LSB, 0x97) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF_TPREL22, 0x9A) \ -_ELF_DEFINE_RELOC(R_IA_64_DTPMOD64MSB, 0xA6) \ -_ELF_DEFINE_RELOC(R_IA_64_DTPMOD64LSB, 0xA7) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF_DTPMOD22, 0xAA) \ -_ELF_DEFINE_RELOC(R_IA_64_DTPREL14, 0xB1) \ -_ELF_DEFINE_RELOC(R_IA_64_DTPREL22, 0xB2) \ -_ELF_DEFINE_RELOC(R_IA_64_DTPREL64I, 0xB3) \ -_ELF_DEFINE_RELOC(R_IA_64_DTPREL32MSB, 0xB4) \ -_ELF_DEFINE_RELOC(R_IA_64_DTPREL32LSB, 0xB5) \ -_ELF_DEFINE_RELOC(R_IA_64_DTPREL64MSB, 0xB6) \ -_ELF_DEFINE_RELOC(R_IA_64_DTPREL64LSB, 0xB7) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF_DTPREL22, 0xBA) - -#define _ELF_DEFINE_MIPS_RELOCATIONS() \ -_ELF_DEFINE_RELOC(R_MIPS_NONE, 0) \ -_ELF_DEFINE_RELOC(R_MIPS_16, 1) \ -_ELF_DEFINE_RELOC(R_MIPS_32, 2) \ -_ELF_DEFINE_RELOC(R_MIPS_REL32, 3) \ -_ELF_DEFINE_RELOC(R_MIPS_26, 4) \ -_ELF_DEFINE_RELOC(R_MIPS_HI16, 5) \ -_ELF_DEFINE_RELOC(R_MIPS_LO16, 6) \ -_ELF_DEFINE_RELOC(R_MIPS_GPREL16, 7) \ -_ELF_DEFINE_RELOC(R_MIPS_LITERAL, 8) \ -_ELF_DEFINE_RELOC(R_MIPS_GOT16, 9) \ -_ELF_DEFINE_RELOC(R_MIPS_PC16, 10) \ -_ELF_DEFINE_RELOC(R_MIPS_CALL16, 11) \ -_ELF_DEFINE_RELOC(R_MIPS_GPREL32, 12) \ -_ELF_DEFINE_RELOC(R_MIPS_64, 18) \ -_ELF_DEFINE_RELOC(R_MIPS_GOTHI16, 21) \ -_ELF_DEFINE_RELOC(R_MIPS_GOTLO16, 22) \ -_ELF_DEFINE_RELOC(R_MIPS_CALLHI16, 30) \ -_ELF_DEFINE_RELOC(R_MIPS_CALLLO16, 31) - -#define _ELF_DEFINE_PPC32_RELOCATIONS() \ -_ELF_DEFINE_RELOC(R_PPC_NONE, 0) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR32, 1) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR24, 2) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR16, 3) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR16_LO, 4) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR16_HI, 5) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR16_HA, 6) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR14, 7) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR14_BRTAKEN, 8) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR14_BRNTAKEN, 9) \ -_ELF_DEFINE_RELOC(R_PPC_REL24, 10) \ -_ELF_DEFINE_RELOC(R_PPC_REL14, 11) \ -_ELF_DEFINE_RELOC(R_PPC_REL14_BRTAKEN, 12) \ -_ELF_DEFINE_RELOC(R_PPC_REL14_BRNTAKEN, 13) \ -_ELF_DEFINE_RELOC(R_PPC_GOT16, 14) \ -_ELF_DEFINE_RELOC(R_PPC_GOT16_LO, 15) \ -_ELF_DEFINE_RELOC(R_PPC_GOT16_HI, 16) \ -_ELF_DEFINE_RELOC(R_PPC_GOT16_HA, 17) \ -_ELF_DEFINE_RELOC(R_PPC_PLTREL24, 18) \ -_ELF_DEFINE_RELOC(R_PPC_COPY, 19) \ -_ELF_DEFINE_RELOC(R_PPC_GLOB_DAT, 20) \ -_ELF_DEFINE_RELOC(R_PPC_JMP_SLOT, 21) \ -_ELF_DEFINE_RELOC(R_PPC_RELATIVE, 22) \ -_ELF_DEFINE_RELOC(R_PPC_LOCAL24PC, 23) \ -_ELF_DEFINE_RELOC(R_PPC_UADDR32, 24) \ -_ELF_DEFINE_RELOC(R_PPC_UADDR16, 25) \ -_ELF_DEFINE_RELOC(R_PPC_REL32, 26) \ -_ELF_DEFINE_RELOC(R_PPC_PLT32, 27) \ -_ELF_DEFINE_RELOC(R_PPC_PLTREL32, 28) \ -_ELF_DEFINE_RELOC(R_PPC_PLT16_LO, 29) \ -_ELF_DEFINE_RELOC(R_PPL_PLT16_HI, 30) \ -_ELF_DEFINE_RELOC(R_PPC_PLT16_HA, 31) \ -_ELF_DEFINE_RELOC(R_PPC_SDAREL16, 32) \ -_ELF_DEFINE_RELOC(R_PPC_SECTOFF, 33) \ -_ELF_DEFINE_RELOC(R_PPC_SECTOFF_LO, 34) \ -_ELF_DEFINE_RELOC(R_PPC_SECTOFF_HI, 35) \ -_ELF_DEFINE_RELOC(R_PPC_SECTOFF_HA, 36) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR30, 37) \ -_ELF_DEFINE_RELOC(R_PPC_TLS, 67) \ -_ELF_DEFINE_RELOC(R_PPC_DTPMOD32, 68) \ -_ELF_DEFINE_RELOC(R_PPC_TPREL16, 69) \ -_ELF_DEFINE_RELOC(R_PPC_TPREL16_LO, 70) \ -_ELF_DEFINE_RELOC(R_PPC_TPREL16_HI, 71) \ -_ELF_DEFINE_RELOC(R_PPC_TPREL16_HA, 72) \ -_ELF_DEFINE_RELOC(R_PPC_TPREL32, 73) \ -_ELF_DEFINE_RELOC(R_PPC_DTPREL16, 74) \ -_ELF_DEFINE_RELOC(R_PPC_DTPREL16_LO, 75) \ -_ELF_DEFINE_RELOC(R_PPC_DTPREL16_HI, 76) \ -_ELF_DEFINE_RELOC(R_PPC_DTPREL16_HA, 77) \ -_ELF_DEFINE_RELOC(R_PPC_DTPREL32, 78) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TLSGD16, 79) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TLSGD16_LO, 80) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TLSGD16_HI, 81) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TLSGD16_HA, 82) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TLSLD16, 83) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TLSLD16_LO, 84) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TLSLD16_HI, 85) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TLSLD16_HA, 86) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TPREL16, 87) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TPREL16_LO, 88) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TPREL16_HI, 89) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TPREL16_HA, 90) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_DTPREL16, 91) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_DTPREL16_LO, 92) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_DTPREL16_HI, 93) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_DTPREL16_HA, 94) \ -_ELF_DEFINE_RELOC(R_PPC_TLSGD, 95) \ -_ELF_DEFINE_RELOC(R_PPC_TLSLD, 96) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_NADDR32, 101) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_NADDR16, 102) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_NADDR16_LO, 103) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_NADDR16_HI, 104) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_NADDR16_HA, 105) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_SDAI16, 106) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_SDA2I16, 107) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_SDA2REL, 108) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_SDA21, 109) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_MRKREF, 110) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_RELSEC16, 111) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_RELST_LO, 112) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_RELST_HI, 113) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_RELST_HA, 114) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_BIT_FLD, 115) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_RELSDA, 116) \ - -#define _ELF_DEFINE_PPC64_RELOCATIONS() \ -_ELF_DEFINE_RELOC(R_PPC64_NONE, 0) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR32, 1) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR24, 2) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16, 3) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16_LO, 4) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16_HI, 5) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16_HA, 6) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR14, 7) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR14_BRTAKEN, 8) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR14_BRNTAKEN, 9) \ -_ELF_DEFINE_RELOC(R_PPC64_REL24, 10) \ -_ELF_DEFINE_RELOC(R_PPC64_REL14, 11) \ -_ELF_DEFINE_RELOC(R_PPC64_REL14_BRTAKEN, 12) \ -_ELF_DEFINE_RELOC(R_PPC64_REL14_BRNTAKEN, 13) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT16, 14) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT16_LO, 15) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT16_HI, 16) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT16_HA, 17) \ -_ELF_DEFINE_RELOC(R_PPC64_COPY, 19) \ -_ELF_DEFINE_RELOC(R_PPC64_GLOB_DAT, 20) \ -_ELF_DEFINE_RELOC(R_PPC64_JMP_SLOT, 21) \ -_ELF_DEFINE_RELOC(R_PPC64_RELATIVE, 22) \ -_ELF_DEFINE_RELOC(R_PPC64_UADDR32, 24) \ -_ELF_DEFINE_RELOC(R_PPC64_UADDR16, 25) \ -_ELF_DEFINE_RELOC(R_PPC64_REL32, 26) \ -_ELF_DEFINE_RELOC(R_PPC64_PLT32, 27) \ -_ELF_DEFINE_RELOC(R_PPC64_PLTREL32, 28) \ -_ELF_DEFINE_RELOC(R_PPC64_PLT16_LO, 29) \ -_ELF_DEFINE_RELOC(R_PPC64_PLT16_HI, 30) \ -_ELF_DEFINE_RELOC(R_PPC64_PLT16_HA, 31) \ -_ELF_DEFINE_RELOC(R_PPC64_SECTOFF, 33) \ -_ELF_DEFINE_RELOC(R_PPC64_SECTOFF_LO, 34) \ -_ELF_DEFINE_RELOC(R_PPC64_SECTOFF_HI, 35) \ -_ELF_DEFINE_RELOC(R_PPC64_SECTOFF_HA, 36) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR30, 37) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR64, 38) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16_HIGHER, 39) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16_HIGHERA, 40) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16_HIGHEST, 41) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16_HIGHESTA, 42) \ -_ELF_DEFINE_RELOC(R_PPC64_UADDR64, 43) \ -_ELF_DEFINE_RELOC(R_PPC64_REL64, 44) \ -_ELF_DEFINE_RELOC(R_PPC64_PLT64, 45) \ -_ELF_DEFINE_RELOC(R_PPC64_PLTREL64, 46) \ -_ELF_DEFINE_RELOC(R_PPC64_TOC16, 47) \ -_ELF_DEFINE_RELOC(R_PPC64_TOC16_LO, 48) \ -_ELF_DEFINE_RELOC(R_PPC64_TOC16_HI, 49) \ -_ELF_DEFINE_RELOC(R_PPC64_TOC16_HA, 50) \ -_ELF_DEFINE_RELOC(R_PPC64_TOC, 51) \ -_ELF_DEFINE_RELOC(R_PPC64_PLTGOT16, 52) \ -_ELF_DEFINE_RELOC(R_PPC64_PLTGOT16_LO, 53) \ -_ELF_DEFINE_RELOC(R_PPC64_PLTGOT16_HI, 54) \ -_ELF_DEFINE_RELOC(R_PPC64_PLTGOT16_HA, 55) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16_DS, 56) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16_LO_DS, 57) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT16_DS, 58) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT16_LO_DS, 59) \ -_ELF_DEFINE_RELOC(R_PPC64_PLT16_LO_DS, 60) \ -_ELF_DEFINE_RELOC(R_PPC64_SECTOFF_DS, 61) \ -_ELF_DEFINE_RELOC(R_PPC64_SECTOFF_LO_DS, 62) \ -_ELF_DEFINE_RELOC(R_PPC64_TOC16_DS, 63) \ -_ELF_DEFINE_RELOC(R_PPC64_TOC16_LO_DS, 64) \ -_ELF_DEFINE_RELOC(R_PPC64_PLTGOT16_DS, 65) \ -_ELF_DEFINE_RELOC(R_PPC64_PLTGOT16_LO_DS, 66) \ -_ELF_DEFINE_RELOC(R_PPC64_TLS, 67) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPMOD64, 68) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16, 69) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16_LO, 60) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16_HI, 71) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16_HA, 72) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL64, 73) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16, 74) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_LO, 75) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_HI, 76) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_HA, 77) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL64, 78) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSGD16, 79) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSGD16_LO, 80) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSGD16_HI, 81) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSGD16_HA, 82) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSLD16, 83) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSLD16_LO, 84) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSLD16_HI, 85) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSLD16_HA, 86) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TPREL16_DS, 87) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TPREL16_LO_DS, 88) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TPREL16_HI, 89) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TPREL16_HA, 90) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_DTPREL16_DS, 91) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_DTPREL16_LO_DS, 92) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_DTPREL16_HI, 93) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_DTPREL16_HA, 94) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16_DS, 95) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16_LO_DS, 96) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16_HIGHER, 97) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16_HIGHERA, 98) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16_HIGHEST, 99) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16_HIGHESTA, 100) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_DS, 101) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_LO_DS, 102) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_HIGHER, 103) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_HIGHERA, 104) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_HIGHEST, 105) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_HIGHESTA, 106) \ -_ELF_DEFINE_RELOC(R_PPC64_TLSGD, 107) \ -_ELF_DEFINE_RELOC(R_PPC64_TLSLD, 108) - -#define _ELF_DEFINE_SPARC_RELOCATIONS() \ -_ELF_DEFINE_RELOC(R_SPARC_NONE, 0) \ -_ELF_DEFINE_RELOC(R_SPARC_8, 1) \ -_ELF_DEFINE_RELOC(R_SPARC_16, 2) \ -_ELF_DEFINE_RELOC(R_SPARC_32, 3) \ -_ELF_DEFINE_RELOC(R_SPARC_DISP8, 4) \ -_ELF_DEFINE_RELOC(R_SPARC_DISP16, 5) \ -_ELF_DEFINE_RELOC(R_SPARC_DISP32, 6) \ -_ELF_DEFINE_RELOC(R_SPARC_WDISP30, 7) \ -_ELF_DEFINE_RELOC(R_SPARC_WDISP22, 8) \ -_ELF_DEFINE_RELOC(R_SPARC_HI22, 9) \ -_ELF_DEFINE_RELOC(R_SPARC_22, 10) \ -_ELF_DEFINE_RELOC(R_SPARC_13, 11) \ -_ELF_DEFINE_RELOC(R_SPARC_LO10, 12) \ -_ELF_DEFINE_RELOC(R_SPARC_GOT10, 13) \ -_ELF_DEFINE_RELOC(R_SPARC_GOT13, 14) \ -_ELF_DEFINE_RELOC(R_SPARC_GOT22, 15) \ -_ELF_DEFINE_RELOC(R_SPARC_PC10, 16) \ -_ELF_DEFINE_RELOC(R_SPARC_PC22, 17) \ -_ELF_DEFINE_RELOC(R_SPARC_WPLT30, 18) \ -_ELF_DEFINE_RELOC(R_SPARC_COPY, 19) \ -_ELF_DEFINE_RELOC(R_SPARC_GLOB_DAT, 20) \ -_ELF_DEFINE_RELOC(R_SPARC_JMP_SLOT, 21) \ -_ELF_DEFINE_RELOC(R_SPARC_RELATIVE, 22) \ -_ELF_DEFINE_RELOC(R_SPARC_UA32, 23) \ -_ELF_DEFINE_RELOC(R_SPARC_PLT32, 24) \ -_ELF_DEFINE_RELOC(R_SPARC_HIPLT22, 25) \ -_ELF_DEFINE_RELOC(R_SPARC_LOPLT10, 26) \ -_ELF_DEFINE_RELOC(R_SPARC_PCPLT32, 27) \ -_ELF_DEFINE_RELOC(R_SPARC_PCPLT22, 28) \ -_ELF_DEFINE_RELOC(R_SPARC_PCPLT10, 29) \ -_ELF_DEFINE_RELOC(R_SPARC_10, 30) \ -_ELF_DEFINE_RELOC(R_SPARC_11, 31) \ -_ELF_DEFINE_RELOC(R_SPARC_64, 32) \ -_ELF_DEFINE_RELOC(R_SPARC_OLO10, 33) \ -_ELF_DEFINE_RELOC(R_SPARC_HH22, 34) \ -_ELF_DEFINE_RELOC(R_SPARC_HM10, 35) \ -_ELF_DEFINE_RELOC(R_SPARC_LM22, 36) \ -_ELF_DEFINE_RELOC(R_SPARC_PC_HH22, 37) \ -_ELF_DEFINE_RELOC(R_SPARC_PC_HM10, 38) \ -_ELF_DEFINE_RELOC(R_SPARC_PC_LM22, 39) \ -_ELF_DEFINE_RELOC(R_SPARC_WDISP16, 40) \ -_ELF_DEFINE_RELOC(R_SPARC_WDISP19, 41) \ -_ELF_DEFINE_RELOC(R_SPARC_7, 43) \ -_ELF_DEFINE_RELOC(R_SPARC_5, 44) \ -_ELF_DEFINE_RELOC(R_SPARC_6, 45) \ -_ELF_DEFINE_RELOC(R_SPARC_DISP64, 46) \ -_ELF_DEFINE_RELOC(R_SPARC_PLT64, 47) \ -_ELF_DEFINE_RELOC(R_SPARC_HIX22, 48) \ -_ELF_DEFINE_RELOC(R_SPARC_LOX10, 49) \ -_ELF_DEFINE_RELOC(R_SPARC_H44, 50) \ -_ELF_DEFINE_RELOC(R_SPARC_M44, 51) \ -_ELF_DEFINE_RELOC(R_SPARC_L44, 52) \ -_ELF_DEFINE_RELOC(R_SPARC_REGISTER, 53) \ -_ELF_DEFINE_RELOC(R_SPARC_UA64, 54) \ -_ELF_DEFINE_RELOC(R_SPARC_UA16, 55) \ -_ELF_DEFINE_RELOC(R_SPARC_GOTDATA_HIX22, 80) \ -_ELF_DEFINE_RELOC(R_SPARC_GOTDATA_LOX10, 81) \ -_ELF_DEFINE_RELOC(R_SPARC_GOTDATA_OP_HIX22, 82) \ -_ELF_DEFINE_RELOC(R_SPARC_GOTDATA_OP_LOX10, 83) \ -_ELF_DEFINE_RELOC(R_SPARC_GOTDATA_OP, 84) \ -_ELF_DEFINE_RELOC(R_SPARC_H34, 85) - -#define _ELF_DEFINE_X86_64_RELOCATIONS() \ -_ELF_DEFINE_RELOC(R_X86_64_NONE, 0) \ -_ELF_DEFINE_RELOC(R_X86_64_64, 1) \ -_ELF_DEFINE_RELOC(R_X86_64_PC32, 2) \ -_ELF_DEFINE_RELOC(R_X86_64_GOT32, 3) \ -_ELF_DEFINE_RELOC(R_X86_64_PLT32, 4) \ -_ELF_DEFINE_RELOC(R_X86_64_COPY, 5) \ -_ELF_DEFINE_RELOC(R_X86_64_GLOB_DAT, 6) \ -_ELF_DEFINE_RELOC(R_X86_64_JUMP_SLOT, 7) \ -_ELF_DEFINE_RELOC(R_X86_64_RELATIVE, 8) \ -_ELF_DEFINE_RELOC(R_X86_64_GOTPCREL, 9) \ -_ELF_DEFINE_RELOC(R_X86_64_32, 10) \ -_ELF_DEFINE_RELOC(R_X86_64_32S, 11) \ -_ELF_DEFINE_RELOC(R_X86_64_16, 12) \ -_ELF_DEFINE_RELOC(R_X86_64_PC16, 13) \ -_ELF_DEFINE_RELOC(R_X86_64_8, 14) \ -_ELF_DEFINE_RELOC(R_X86_64_PC8, 15) \ -_ELF_DEFINE_RELOC(R_X86_64_DTPMOD64, 16) \ -_ELF_DEFINE_RELOC(R_X86_64_DTPOFF64, 17) \ -_ELF_DEFINE_RELOC(R_X86_64_TPOFF64, 18) \ -_ELF_DEFINE_RELOC(R_X86_64_TLSGD, 19) \ -_ELF_DEFINE_RELOC(R_X86_64_TLSLD, 20) \ -_ELF_DEFINE_RELOC(R_X86_64_DTPOFF32, 21) \ -_ELF_DEFINE_RELOC(R_X86_64_GOTTPOFF, 22) \ -_ELF_DEFINE_RELOC(R_X86_64_TPOFF32, 23) \ -_ELF_DEFINE_RELOC(R_X86_64_PC64, 24) \ -_ELF_DEFINE_RELOC(R_X86_64_GOTOFF64, 25) \ -_ELF_DEFINE_RELOC(R_X86_64_GOTPC32, 26) \ -_ELF_DEFINE_RELOC(R_X86_64_SIZE32, 32) \ -_ELF_DEFINE_RELOC(R_X86_64_SIZE64, 33) \ -_ELF_DEFINE_RELOC(R_X86_64_GOTPC32_TLSDESC, 34) \ -_ELF_DEFINE_RELOC(R_X86_64_TLSDESC_CALL, 35) \ -_ELF_DEFINE_RELOC(R_X86_64_TLSDESC, 36) - -#define _ELF_DEFINE_RELOCATIONS() \ -_ELF_DEFINE_386_RELOCATIONS() \ -_ELF_DEFINE_AMD64_RELOCATIONS() \ -_ELF_DEFINE_IA64_RELOCATIONS() \ -_ELF_DEFINE_MIPS_RELOCATIONS() \ -_ELF_DEFINE_PPC32_RELOCATIONS() \ -_ELF_DEFINE_PPC64_RELOCATIONS() \ -_ELF_DEFINE_SPARC_RELOCATIONS() \ -_ELF_DEFINE_X86_64_RELOCATIONS() - -#undef _ELF_DEFINE_RELOC -#define _ELF_DEFINE_RELOC(N, V) N = V , -enum { - _ELF_DEFINE_RELOCATIONS() - R__LAST__ -}; - -#define PN_XNUM 0xFFFFU /* Use extended section numbering. */ - -/** - ** ELF Types. - **/ - -typedef uint32_t Elf32_Addr; /* Program address. */ -typedef uint8_t Elf32_Byte; /* Unsigned tiny integer. */ -typedef uint16_t Elf32_Half; /* Unsigned medium integer. */ -typedef uint32_t Elf32_Off; /* File offset. */ -typedef uint16_t Elf32_Section; /* Section index. */ -typedef int32_t Elf32_Sword; /* Signed integer. */ -typedef uint32_t Elf32_Word; /* Unsigned integer. */ -typedef uint64_t Elf32_Lword; /* Unsigned long integer. */ - -typedef uint64_t Elf64_Addr; /* Program address. */ -typedef uint8_t Elf64_Byte; /* Unsigned tiny integer. */ -typedef uint16_t Elf64_Half; /* Unsigned medium integer. */ -typedef uint64_t Elf64_Off; /* File offset. */ -typedef uint16_t Elf64_Section; /* Section index. */ -typedef int32_t Elf64_Sword; /* Signed integer. */ -typedef uint32_t Elf64_Word; /* Unsigned integer. */ -typedef uint64_t Elf64_Lword; /* Unsigned long integer. */ -typedef uint64_t Elf64_Xword; /* Unsigned long integer. */ -typedef int64_t Elf64_Sxword; /* Signed long integer. */ - - -/* - * Capability descriptors. - */ - -/* 32-bit capability descriptor. */ -typedef struct { - Elf32_Word c_tag; /* Type of entry. */ - union { - Elf32_Word c_val; /* Integer value. */ - Elf32_Addr c_ptr; /* Pointer value. */ - } c_un; -} Elf32_Cap; - -/* 64-bit capability descriptor. */ -typedef struct { - Elf64_Xword c_tag; /* Type of entry. */ - union { - Elf64_Xword c_val; /* Integer value. */ - Elf64_Addr c_ptr; /* Pointer value. */ - } c_un; -} Elf64_Cap; - -/* - * MIPS .conflict section entries. - */ - -/* 32-bit entry. */ -typedef struct { - Elf32_Addr c_index; -} Elf32_Conflict; - -/* 64-bit entry. */ -typedef struct { - Elf64_Addr c_index; -} Elf64_Conflict; - -/* - * Dynamic section entries. - */ - -/* 32-bit entry. */ -typedef struct { - Elf32_Sword d_tag; /* Type of entry. */ - union { - Elf32_Word d_val; /* Integer value. */ - Elf32_Addr d_ptr; /* Pointer value. */ - } d_un; -} Elf32_Dyn; - -/* 64-bit entry. */ -typedef struct { - Elf64_Sxword d_tag; /* Type of entry. */ - union { - Elf64_Xword d_val; /* Integer value. */ - Elf64_Addr d_ptr; /* Pointer value; */ - } d_un; -} Elf64_Dyn; - - -/* - * The executable header (EHDR). - */ - -/* 32 bit EHDR. */ -typedef struct { - unsigned char e_ident[EI_NIDENT]; /* ELF identification. */ - Elf32_Half e_type; /* Object file type (ET_*). */ - Elf32_Half e_machine; /* Machine type (EM_*). */ - Elf32_Word e_version; /* File format version (EV_*). */ - Elf32_Addr e_entry; /* Start address. */ - Elf32_Off e_phoff; /* File offset to the PHDR table. */ - Elf32_Off e_shoff; /* File offset to the SHDRheader. */ - Elf32_Word e_flags; /* Flags (EF_*). */ - Elf32_Half e_ehsize; /* Elf header size in bytes. */ - Elf32_Half e_phentsize; /* PHDR table entry size in bytes. */ - Elf32_Half e_phnum; /* Number of PHDR entries. */ - Elf32_Half e_shentsize; /* SHDR table entry size in bytes. */ - Elf32_Half e_shnum; /* Number of SHDR entries. */ - Elf32_Half e_shstrndx; /* Index of section name string table. */ -} Elf32_Ehdr; - - -/* 64 bit EHDR. */ -typedef struct { - unsigned char e_ident[EI_NIDENT]; /* ELF identification. */ - Elf64_Half e_type; /* Object file type (ET_*). */ - Elf64_Half e_machine; /* Machine type (EM_*). */ - Elf64_Word e_version; /* File format version (EV_*). */ - Elf64_Addr e_entry; /* Start address. */ - Elf64_Off e_phoff; /* File offset to the PHDR table. */ - Elf64_Off e_shoff; /* File offset to the SHDRheader. */ - Elf64_Word e_flags; /* Flags (EF_*). */ - Elf64_Half e_ehsize; /* Elf header size in bytes. */ - Elf64_Half e_phentsize; /* PHDR table entry size in bytes. */ - Elf64_Half e_phnum; /* Number of PHDR entries. */ - Elf64_Half e_shentsize; /* SHDR table entry size in bytes. */ - Elf64_Half e_shnum; /* Number of SHDR entries. */ - Elf64_Half e_shstrndx; /* Index of section name string table. */ -} Elf64_Ehdr; - - -/* - * Shared object information. - */ - -/* 32-bit entry. */ -typedef struct { - Elf32_Word l_name; /* The name of a shared object. */ - Elf32_Word l_time_stamp; /* 32-bit timestamp. */ - Elf32_Word l_checksum; /* Checksum of visible symbols, sizes. */ - Elf32_Word l_version; /* Interface version string index. */ - Elf32_Word l_flags; /* Flags (LL_*). */ -} Elf32_Lib; - -/* 64-bit entry. */ -typedef struct { - Elf64_Word l_name; - Elf64_Word l_time_stamp; - Elf64_Word l_checksum; - Elf64_Word l_version; - Elf64_Word l_flags; -} Elf64_Lib; - -#define _ELF_DEFINE_LL_FLAGS() \ -_ELF_DEFINE_LL(LL_NONE, 0, \ - "no flags") \ -_ELF_DEFINE_LL(LL_EXACT_MATCH, 0x1, \ - "require an exact match") \ -_ELF_DEFINE_LL(LL_IGNORE_INT_VER, 0x2, \ - "ignore version incompatibilities") \ -_ELF_DEFINE_LL(LL_REQUIRE_MINOR, 0x4, \ - "") \ -_ELF_DEFINE_LL(LL_EXPORTS, 0x8, \ - "") \ -_ELF_DEFINE_LL(LL_DELAY_LOAD, 0x10, \ - "") \ -_ELF_DEFINE_LL(LL_DELTA, 0x20, \ - "") - -#undef _ELF_DEFINE_LL -#define _ELF_DEFINE_LL(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_LL_FLAGS() - LL__LAST__ -}; - -/* - * Note tags - */ - -#define _ELF_DEFINE_NOTE_ENTRY_TYPES() \ -_ELF_DEFINE_NT(NT_ABI_TAG, 1, "Tag indicating the ABI") \ -_ELF_DEFINE_NT(NT_GNU_HWCAP, 2, "Hardware capabilities") \ -_ELF_DEFINE_NT(NT_GNU_BUILD_ID, 3, "Build id, set by ld(1)") \ -_ELF_DEFINE_NT(NT_GNU_GOLD_VERSION, 4, \ - "Version number of the GNU gold linker") \ -_ELF_DEFINE_NT(NT_PRSTATUS, 1, "Process status") \ -_ELF_DEFINE_NT(NT_FPREGSET, 2, "Floating point information") \ -_ELF_DEFINE_NT(NT_PRPSINFO, 3, "Process information") \ -_ELF_DEFINE_NT(NT_AUXV, 6, "Auxiliary vector") \ -_ELF_DEFINE_NT(NT_PRXFPREG, 0x46E62B7FUL, \ - "Linux user_xfpregs structure") \ -_ELF_DEFINE_NT(NT_PSTATUS, 10, "Linux process status") \ -_ELF_DEFINE_NT(NT_FPREGS, 12, "Linux floating point regset") \ -_ELF_DEFINE_NT(NT_PSINFO, 13, "Linux process information") \ -_ELF_DEFINE_NT(NT_LWPSTATUS, 16, "Linux lwpstatus_t type") \ -_ELF_DEFINE_NT(NT_LWPSINFO, 17, "Linux lwpinfo_t type") - -#undef _ELF_DEFINE_NT -#define _ELF_DEFINE_NT(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_NOTE_ENTRY_TYPES() - NT__LAST__ -}; - -/* Aliases for the ABI tag. */ -#define NT_FREEBSD_ABI_TAG NT_ABI_TAG -#define NT_GNU_ABI_TAG NT_ABI_TAG -#define NT_NETBSD_IDENT NT_ABI_TAG -#define NT_OPENBSD_IDENT NT_ABI_TAG - -/* - * Note descriptors. - */ - -typedef struct { - uint32_t n_namesz; /* Length of note's name. */ - uint32_t n_descsz; /* Length of note's value. */ - uint32_t n_type; /* Type of note. */ -} Elf_Note; - -typedef Elf_Note Elf32_Nhdr; /* 32-bit note header. */ -typedef Elf_Note Elf64_Nhdr; /* 64-bit note header. */ - -/* - * MIPS ELF options descriptor header. - */ - -typedef struct { - Elf64_Byte kind; /* Type of options. */ - Elf64_Byte size; /* Size of option descriptor. */ - Elf64_Half section; /* Index of section affected. */ - Elf64_Word info; /* Kind-specific information. */ -} Elf_Options; - -/* - * Option kinds. - */ - -#define _ELF_DEFINE_OPTION_KINDS() \ -_ELF_DEFINE_ODK(ODK_NULL, 0, "undefined") \ -_ELF_DEFINE_ODK(ODK_REGINFO, 1, "register usage info") \ -_ELF_DEFINE_ODK(ODK_EXCEPTIONS, 2, "exception processing info") \ -_ELF_DEFINE_ODK(ODK_PAD, 3, "section padding") \ -_ELF_DEFINE_ODK(ODK_HWPATCH, 4, "hardware patch applied") \ -_ELF_DEFINE_ODK(ODK_FILL, 5, "fill value used by linker") \ -_ELF_DEFINE_ODK(ODK_TAGS, 6, "reserved space for tools") \ -_ELF_DEFINE_ODK(ODK_HWAND, 7, "hardware AND patch applied") \ -_ELF_DEFINE_ODK(ODK_HWOR, 8, "hardware OR patch applied") \ -_ELF_DEFINE_ODK(ODK_GP_GROUP, 9, \ - "GP group to use for text/data sections") \ -_ELF_DEFINE_ODK(ODK_IDENT, 10, "ID information") \ -_ELF_DEFINE_ODK(ODK_PAGESIZE, 11, "page size infomation") - -#undef _ELF_DEFINE_ODK -#define _ELF_DEFINE_ODK(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_OPTION_KINDS() - ODK__LAST__ -}; - -/* - * ODK_EXCEPTIONS info field masks. - */ - -#define _ELF_DEFINE_ODK_EXCEPTIONS_MASK() \ -_ELF_DEFINE_OEX(OEX_FPU_MIN, 0x0000001FUL, \ - "minimum FPU exception which must be enabled") \ -_ELF_DEFINE_OEX(OEX_FPU_MAX, 0x00001F00UL, \ - "maximum FPU exception which can be enabled") \ -_ELF_DEFINE_OEX(OEX_PAGE0, 0x00010000UL, \ - "page zero must be mapped") \ -_ELF_DEFINE_OEX(OEX_SMM, 0x00020000UL, \ - "run in sequential memory mode") \ -_ELF_DEFINE_OEX(OEX_PRECISEFP, 0x00040000UL, \ - "run in precise FP exception mode") \ -_ELF_DEFINE_OEX(OEX_DISMISS, 0x00080000UL, \ - "dismiss invalid address traps") - -#undef _ELF_DEFINE_OEX -#define _ELF_DEFINE_OEX(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_ODK_EXCEPTIONS_MASK() - OEX__LAST__ -}; - -/* - * ODK_PAD info field masks. - */ - -#define _ELF_DEFINE_ODK_PAD_MASK() \ -_ELF_DEFINE_OPAD(OPAD_PREFIX, 0x0001) \ -_ELF_DEFINE_OPAD(OPAD_POSTFIX, 0x0002) \ -_ELF_DEFINE_OPAD(OPAD_SYMBOL, 0x0004) - -#undef _ELF_DEFINE_OPAD -#define _ELF_DEFINE_OPAD(N, V) N = V , -enum { - _ELF_DEFINE_ODK_PAD_MASK() - OPAD__LAST__ -}; - -/* - * ODK_HWPATCH info field masks. - */ - -#define _ELF_DEFINE_ODK_HWPATCH_MASK() \ -_ELF_DEFINE_OHW(OHW_R4KEOP, 0x00000001UL, \ - "patch for R4000 branch at end-of-page bug") \ -_ELF_DEFINE_OHW(OHW_R8KPFETCH, 0x00000002UL, \ - "R8000 prefetch bug may occur") \ -_ELF_DEFINE_OHW(OHW_R5KEOP, 0x00000004UL, \ - "patch for R5000 branch at end-of-page bug") \ -_ELF_DEFINE_OHW(OHW_R5KCVTL, 0x00000008UL, \ - "R5000 cvt.[ds].l bug: clean == 1") \ -_ELF_DEFINE_OHW(OHW_R10KLDL, 0x00000010UL, \ - "needd patch for R10000 misaligned load") - -#undef _ELF_DEFINE_OHW -#define _ELF_DEFINE_OHW(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_ODK_HWPATCH_MASK() - OHW__LAST__ -}; - -/* - * ODK_HWAND/ODK_HWOR info field and hwp_flags[12] masks. - */ - -#define _ELF_DEFINE_ODK_HWP_MASK() \ -_ELF_DEFINE_HWP(OHWA0_R4KEOP_CHECKED, 0x00000001UL, \ - "object checked for R4000 end-of-page bug") \ -_ELF_DEFINE_HWP(OHWA0_R4KEOP_CLEAN, 0x00000002UL, \ - "object verified clean for R4000 end-of-page bug") \ -_ELF_DEFINE_HWP(OHWO0_FIXADE, 0x00000001UL, \ - "object requires call to fixade") - -#undef _ELF_DEFINE_HWP -#define _ELF_DEFINE_HWP(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_ODK_HWP_MASK() - OHWX0__LAST__ -}; - -/* - * ODK_IDENT/ODK_GP_GROUP info field masks. - */ - -#define _ELF_DEFINE_ODK_GP_MASK() \ -_ELF_DEFINE_OGP(OGP_GROUP, 0x0000FFFFUL, "GP group number") \ -_ELF_DEFINE_OGP(OGP_SELF, 0x00010000UL, \ - "GP group is self-contained") - -#undef _ELF_DEFINE_OGP -#define _ELF_DEFINE_OGP(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_ODK_GP_MASK() - OGP__LAST__ -}; - -/* - * MIPS ELF register info descriptor. - */ - -/* 32 bit RegInfo entry. */ -typedef struct { - Elf32_Word ri_gprmask; /* Mask of general register used. */ - Elf32_Word ri_cprmask[4]; /* Mask of coprocessor register used. */ - Elf32_Addr ri_gp_value; /* GP register value. */ -} Elf32_RegInfo; - -/* 64 bit RegInfo entry. */ -typedef struct { - Elf64_Word ri_gprmask; /* Mask of general register used. */ - Elf64_Word ri_pad; /* Padding. */ - Elf64_Word ri_cprmask[4]; /* Mask of coprocessor register used. */ - Elf64_Addr ri_gp_value; /* GP register value. */ -} Elf64_RegInfo; - -/* - * Program Header Table (PHDR) entries. - */ - -/* 32 bit PHDR entry. */ -typedef struct { - Elf32_Word p_type; /* Type of segment. */ - Elf32_Off p_offset; /* File offset to segment. */ - Elf32_Addr p_vaddr; /* Virtual address in memory. */ - Elf32_Addr p_paddr; /* Physical address (if relevant). */ - Elf32_Word p_filesz; /* Size of segment in file. */ - Elf32_Word p_memsz; /* Size of segment in memory. */ - Elf32_Word p_flags; /* Segment flags. */ - Elf32_Word p_align; /* Alignment constraints. */ -} Elf32_Phdr; - -/* 64 bit PHDR entry. */ -typedef struct { - Elf64_Word p_type; /* Type of segment. */ - Elf64_Word p_flags; /* File offset to segment. */ - Elf64_Off p_offset; /* Virtual address in memory. */ - Elf64_Addr p_vaddr; /* Physical address (if relevant). */ - Elf64_Addr p_paddr; /* Size of segment in file. */ - Elf64_Xword p_filesz; /* Size of segment in memory. */ - Elf64_Xword p_memsz; /* Segment flags. */ - Elf64_Xword p_align; /* Alignment constraints. */ -} Elf64_Phdr; - - -/* - * Move entries, for describing data in COMMON blocks in a compact - * manner. - */ - -/* 32-bit move entry. */ -typedef struct { - Elf32_Lword m_value; /* Initialization value. */ - Elf32_Word m_info; /* Encoded size and index. */ - Elf32_Word m_poffset; /* Offset relative to symbol. */ - Elf32_Half m_repeat; /* Repeat count. */ - Elf32_Half m_stride; /* Number of units to skip. */ -} Elf32_Move; - -/* 64-bit move entry. */ -typedef struct { - Elf64_Lword m_value; /* Initialization value. */ - Elf64_Xword m_info; /* Encoded size and index. */ - Elf64_Xword m_poffset; /* Offset relative to symbol. */ - Elf64_Half m_repeat; /* Repeat count. */ - Elf64_Half m_stride; /* Number of units to skip. */ -} Elf64_Move; - -#define ELF32_M_SYM(I) ((I) >> 8) -#define ELF32_M_SIZE(I) ((unsigned char) (I)) -#define ELF32_M_INFO(M, S) (((M) << 8) + (unsigned char) (S)) - -#define ELF64_M_SYM(I) ((I) >> 8) -#define ELF64_M_SIZE(I) ((unsigned char) (I)) -#define ELF64_M_INFO(M, S) (((M) << 8) + (unsigned char) (S)) - -/* - * Section Header Table (SHDR) entries. - */ - -/* 32 bit SHDR */ -typedef struct { - Elf32_Word sh_name; /* index of section name */ - Elf32_Word sh_type; /* section type */ - Elf32_Word sh_flags; /* section flags */ - Elf32_Addr sh_addr; /* in-memory address of section */ - Elf32_Off sh_offset; /* file offset of section */ - Elf32_Word sh_size; /* section size in bytes */ - Elf32_Word sh_link; /* section header table link */ - Elf32_Word sh_info; /* extra information */ - Elf32_Word sh_addralign; /* alignment constraint */ - Elf32_Word sh_entsize; /* size for fixed-size entries */ -} Elf32_Shdr; - -/* 64 bit SHDR */ -typedef struct { - Elf64_Word sh_name; /* index of section name */ - Elf64_Word sh_type; /* section type */ - Elf64_Xword sh_flags; /* section flags */ - Elf64_Addr sh_addr; /* in-memory address of section */ - Elf64_Off sh_offset; /* file offset of section */ - Elf64_Xword sh_size; /* section size in bytes */ - Elf64_Word sh_link; /* section header table link */ - Elf64_Word sh_info; /* extra information */ - Elf64_Xword sh_addralign; /* alignment constraint */ - Elf64_Xword sh_entsize; /* size for fixed-size entries */ -} Elf64_Shdr; - - -/* - * Symbol table entries. - */ - -typedef struct { - Elf32_Word st_name; /* index of symbol's name */ - Elf32_Addr st_value; /* value for the symbol */ - Elf32_Word st_size; /* size of associated data */ - unsigned char st_info; /* type and binding attributes */ - unsigned char st_other; /* visibility */ - Elf32_Half st_shndx; /* index of related section */ -} Elf32_Sym; - -typedef struct { - Elf64_Word st_name; /* index of symbol's name */ - unsigned char st_info; /* value for the symbol */ - unsigned char st_other; /* size of associated data */ - Elf64_Half st_shndx; /* type and binding attributes */ - Elf64_Addr st_value; /* visibility */ - Elf64_Xword st_size; /* index of related section */ -} Elf64_Sym; - -#define ELF32_ST_BIND(I) ((I) >> 4) -#define ELF32_ST_TYPE(I) ((I) & 0xFU) -#define ELF32_ST_INFO(B,T) (((B) << 4) + ((T) & 0xF)) - -#define ELF64_ST_BIND(I) ((I) >> 4) -#define ELF64_ST_TYPE(I) ((I) & 0xFU) -#define ELF64_ST_INFO(B,T) (((B) << 4) + ((T) & 0xF)) - -#define ELF32_ST_VISIBILITY(O) ((O) & 0x3) -#define ELF64_ST_VISIBILITY(O) ((O) & 0x3) - -/* - * Syminfo descriptors, containing additional symbol information. - */ - -/* 32-bit entry. */ -typedef struct { - Elf32_Half si_boundto; /* Entry index with additional flags. */ - Elf32_Half si_flags; /* Flags. */ -} Elf32_Syminfo; - -/* 64-bit entry. */ -typedef struct { - Elf64_Half si_boundto; /* Entry index with additional flags. */ - Elf64_Half si_flags; /* Flags. */ -} Elf64_Syminfo; - -/* - * Relocation descriptors. - */ - -typedef struct { - Elf32_Addr r_offset; /* location to apply relocation to */ - Elf32_Word r_info; /* type+section for relocation */ -} Elf32_Rel; - -typedef struct { - Elf32_Addr r_offset; /* location to apply relocation to */ - Elf32_Word r_info; /* type+section for relocation */ - Elf32_Sword r_addend; /* constant addend */ -} Elf32_Rela; - -typedef struct { - Elf64_Addr r_offset; /* location to apply relocation to */ - Elf64_Xword r_info; /* type+section for relocation */ -} Elf64_Rel; - -typedef struct { - Elf64_Addr r_offset; /* location to apply relocation to */ - Elf64_Xword r_info; /* type+section for relocation */ - Elf64_Sxword r_addend; /* constant addend */ -} Elf64_Rela; - - -#define ELF32_R_SYM(I) ((I) >> 8) -#define ELF32_R_TYPE(I) ((unsigned char) (I)) -#define ELF32_R_INFO(S,T) (((S) << 8) + (unsigned char) (T)) - -#define ELF64_R_SYM(I) ((I) >> 32) -#define ELF64_R_TYPE(I) ((I) & 0xFFFFFFFFUL) -#define ELF64_R_INFO(S,T) (((S) << 32) + ((T) & 0xFFFFFFFFUL)) - -/* - * Symbol versioning structures. - */ - -/* 32-bit structures. */ -typedef struct -{ - Elf32_Word vda_name; /* Index to name. */ - Elf32_Word vda_next; /* Offset to next entry. */ -} Elf32_Verdaux; - -typedef struct -{ - Elf32_Word vna_hash; /* Hash value of dependency name. */ - Elf32_Half vna_flags; /* Flags. */ - Elf32_Half vna_other; /* Unused. */ - Elf32_Word vna_name; /* Offset to dependency name. */ - Elf32_Word vna_next; /* Offset to next vernaux entry. */ -} Elf32_Vernaux; - -typedef struct -{ - Elf32_Half vd_version; /* Version information. */ - Elf32_Half vd_flags; /* Flags. */ - Elf32_Half vd_ndx; /* Index into the versym section. */ - Elf32_Half vd_cnt; /* Number of aux entries. */ - Elf32_Word vd_hash; /* Hash value of name. */ - Elf32_Word vd_aux; /* Offset to aux entries. */ - Elf32_Word vd_next; /* Offset to next version definition. */ -} Elf32_Verdef; - -typedef struct -{ - Elf32_Half vn_version; /* Version number. */ - Elf32_Half vn_cnt; /* Number of aux entries. */ - Elf32_Word vn_file; /* Offset of associated file name. */ - Elf32_Word vn_aux; /* Offset of vernaux array. */ - Elf32_Word vn_next; /* Offset of next verneed entry. */ -} Elf32_Verneed; - -typedef Elf32_Half Elf32_Versym; - -/* 64-bit structures. */ - -typedef struct { - Elf64_Word vda_name; /* Index to name. */ - Elf64_Word vda_next; /* Offset to next entry. */ -} Elf64_Verdaux; - -typedef struct { - Elf64_Word vna_hash; /* Hash value of dependency name. */ - Elf64_Half vna_flags; /* Flags. */ - Elf64_Half vna_other; /* Unused. */ - Elf64_Word vna_name; /* Offset to dependency name. */ - Elf64_Word vna_next; /* Offset to next vernaux entry. */ -} Elf64_Vernaux; - -typedef struct { - Elf64_Half vd_version; /* Version information. */ - Elf64_Half vd_flags; /* Flags. */ - Elf64_Half vd_ndx; /* Index into the versym section. */ - Elf64_Half vd_cnt; /* Number of aux entries. */ - Elf64_Word vd_hash; /* Hash value of name. */ - Elf64_Word vd_aux; /* Offset to aux entries. */ - Elf64_Word vd_next; /* Offset to next version definition. */ -} Elf64_Verdef; - -typedef struct { - Elf64_Half vn_version; /* Version number. */ - Elf64_Half vn_cnt; /* Number of aux entries. */ - Elf64_Word vn_file; /* Offset of associated file name. */ - Elf64_Word vn_aux; /* Offset of vernaux array. */ - Elf64_Word vn_next; /* Offset of next verneed entry. */ -} Elf64_Verneed; - -typedef Elf64_Half Elf64_Versym; - - -/* - * The header for GNU-style hash sections. - */ - -typedef struct { - uint32_t gh_nbuckets; /* Number of hash buckets. */ - uint32_t gh_symndx; /* First visible symbol in .dynsym. */ - uint32_t gh_maskwords; /* #maskwords used in bloom filter. */ - uint32_t gh_shift2; /* Bloom filter shift count. */ -} Elf_GNU_Hash_Header; - -#endif /* _ELFDEFINITIONS_H_ */ diff --git a/src/libelf/gelf.h b/src/libelf/gelf.h deleted file mode 100644 index b6e07f9..0000000 --- a/src/libelf/gelf.h +++ /dev/null @@ -1,106 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: gelf.h 1168 2010-09-04 01:03:25Z jkoshy $ - */ - -#ifndef _GELF_H_ -#define _GELF_H_ - -#include - -#include - -typedef Elf64_Addr GElf_Addr; /* Addresses */ -typedef Elf64_Half GElf_Half; /* Half words (16 bit) */ -typedef Elf64_Off GElf_Off; /* Offsets */ -typedef Elf64_Sword GElf_Sword; /* Signed words (32 bit) */ -typedef Elf64_Sxword GElf_Sxword; /* Signed long words (64 bit) */ -typedef Elf64_Word GElf_Word; /* Unsigned words (32 bit) */ -typedef Elf64_Xword GElf_Xword; /* Unsigned long words (64 bit) */ - -typedef Elf64_Dyn GElf_Dyn; /* ".dynamic" section entries */ -typedef Elf64_Ehdr GElf_Ehdr; /* ELF header */ -typedef Elf64_Phdr GElf_Phdr; /* Program header */ -typedef Elf64_Shdr GElf_Shdr; /* Section header */ -typedef Elf64_Sym GElf_Sym; /* Symbol table entries */ -typedef Elf64_Rel GElf_Rel; /* Relocation entries */ -typedef Elf64_Rela GElf_Rela; /* Relocation entries with addend */ - -typedef Elf64_Cap GElf_Cap; /* SW/HW capabilities */ -typedef Elf64_Move GElf_Move; /* Move entries */ -typedef Elf64_Syminfo GElf_Syminfo; /* Symbol information */ - -#define GELF_M_INFO ELF64_M_INFO -#define GELF_M_SIZE ELF64_M_SIZE -#define GELF_M_SYM ELF64_M_SYM - -#define GELF_R_INFO ELF64_R_INFO -#define GELF_R_SYM ELF64_R_SYM -#define GELF_R_TYPE ELF64_R_TYPE -#define GELF_R_TYPE_DATA ELF64_R_TYPE_DATA -#define GELF_R_TYPE_ID ELF64_R_TYPE_ID -#define GELF_R_TYPE_INFO ELF64_R_TYPE_INFO - -#define GELF_ST_BIND ELF64_ST_BIND -#define GELF_ST_INFO ELF64_ST_INFO -#define GELF_ST_TYPE ELF64_ST_TYPE -#define GELF_ST_VISIBILITY ELF64_ST_VISIBILITY - -long gelf_checksum(Elf *_elf); -size_t gelf_fsize(Elf *_elf, Elf_Type _type, size_t _count, - unsigned int _version); -int gelf_getclass(Elf *_elf); -GElf_Dyn *gelf_getdyn(Elf_Data *_data, int _index, GElf_Dyn *_dst); -GElf_Ehdr *gelf_getehdr(Elf *_elf, GElf_Ehdr *_dst); -GElf_Phdr *gelf_getphdr(Elf *_elf, int _index, GElf_Phdr *_dst); -GElf_Rel *gelf_getrel(Elf_Data *_src, int _index, GElf_Rel *_dst); -GElf_Rela *gelf_getrela(Elf_Data *_src, int _index, GElf_Rela *_dst); -GElf_Shdr *gelf_getshdr(Elf_Scn *_scn, GElf_Shdr *_dst); -GElf_Sym *gelf_getsym(Elf_Data *_src, int _index, GElf_Sym *_dst); -GElf_Sym *gelf_getsymshndx(Elf_Data *_src, Elf_Data *_shindexsrc, - int _index, GElf_Sym *_dst, Elf32_Word *_shindexdst); -void * gelf_newehdr(Elf *_elf, int _class); -void * gelf_newphdr(Elf *_elf, size_t _phnum); -int gelf_update_dyn(Elf_Data *_dst, int _index, GElf_Dyn *_src); -int gelf_update_ehdr(Elf *_elf, GElf_Ehdr *_src); -int gelf_update_phdr(Elf *_elf, int _index, GElf_Phdr *_src); -int gelf_update_rel(Elf_Data *_dst, int _index, GElf_Rel *_src); -int gelf_update_rela(Elf_Data *_dst, int _index, GElf_Rela *_src); -int gelf_update_shdr(Elf_Scn *_dst, GElf_Shdr *_src); -int gelf_update_sym(Elf_Data *_dst, int _index, GElf_Sym *_src); -int gelf_update_symshndx(Elf_Data *_symdst, Elf_Data *_shindexdst, - int _index, GElf_Sym *_symsrc, Elf32_Word _shindexsrc); -Elf_Data *gelf_xlatetof(Elf *_elf, Elf_Data *_dst, const Elf_Data *_src, unsigned int _encode); -Elf_Data *gelf_xlatetom(Elf *_elf, Elf_Data *_dst, const Elf_Data *_src, unsigned int _encode); - -GElf_Cap *gelf_getcap(Elf_Data *_data, int _index, GElf_Cap *_cap); -GElf_Move *gelf_getmove(Elf_Data *_src, int _index, GElf_Move *_dst); -GElf_Syminfo *gelf_getsyminfo(Elf_Data *_src, int _index, GElf_Syminfo *_dst); -int gelf_update_cap(Elf_Data *_dst, int _index, GElf_Cap *_src); -int gelf_update_move(Elf_Data *_dst, int _index, GElf_Move *_src); -int gelf_update_syminfo(Elf_Data *_dst, int _index, GElf_Syminfo *_src); - -#endif /* _GELF_H_ */ diff --git a/src/libelf/gelf_cap.c b/src/libelf/gelf_cap.c deleted file mode 100644 index ad4c342..0000000 --- a/src/libelf/gelf_cap.c +++ /dev/null @@ -1,151 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include "gelf.h" -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: gelf_cap.c 2272 2011-12-03 17:07:31Z jkoshy $"); - -GElf_Cap * -gelf_getcap(Elf_Data *ed, int ndx, GElf_Cap *dst) -{ - int ec; - Elf *e; - size_t msz; - Elf_Scn *scn; - Elf32_Cap *cap32; - Elf64_Cap *cap64; - uint32_t sh_type; - struct _Libelf_Data *d; - - d = (struct _Libelf_Data *) ed; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_CAP) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_CAP, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_data.d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - - cap32 = (Elf32_Cap *) d->d_data.d_buf + ndx; - - dst->c_tag = cap32->c_tag; - dst->c_un.c_val = (Elf64_Xword) cap32->c_un.c_val; - - } else { - - cap64 = (Elf64_Cap *) d->d_data.d_buf + ndx; - - *dst = *cap64; - } - - return (dst); -} - -int -gelf_update_cap(Elf_Data *ed, int ndx, GElf_Cap *gc) -{ - int ec; - Elf *e; - size_t msz; - Elf_Scn *scn; - Elf32_Cap *cap32; - Elf64_Cap *cap64; - uint32_t sh_type; - struct _Libelf_Data *d; - - d = (struct _Libelf_Data *) ed; - - if (d == NULL || ndx < 0 || gc == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_CAP) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_CAP, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_data.d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - cap32 = (Elf32_Cap *) d->d_data.d_buf + ndx; - - LIBELF_COPY_U32(cap32, gc, c_tag); - LIBELF_COPY_U32(cap32, gc, c_un.c_val); - } else { - cap64 = (Elf64_Cap *) d->d_data.d_buf + ndx; - - *cap64 = *gc; - } - - return (1); -} diff --git a/src/libelf/gelf_checksum.c b/src/libelf/gelf_checksum.c deleted file mode 100644 index 71254af..0000000 --- a/src/libelf/gelf_checksum.c +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include "gelf.h" -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: gelf_checksum.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -long -elf32_checksum(Elf *e) -{ - return (_libelf_checksum(e, ELFCLASS32)); -} - -long -elf64_checksum(Elf *e) -{ - return (_libelf_checksum(e, ELFCLASS64)); -} - -long -gelf_checksum(Elf *e) -{ - int ec; - if (e == NULL || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0L); - } - return (_libelf_checksum(e, ec)); -} diff --git a/src/libelf/gelf_dyn.c b/src/libelf/gelf_dyn.c deleted file mode 100644 index 212efef..0000000 --- a/src/libelf/gelf_dyn.c +++ /dev/null @@ -1,150 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include "gelf.h" -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: gelf_dyn.c 2272 2011-12-03 17:07:31Z jkoshy $"); - -GElf_Dyn * -gelf_getdyn(Elf_Data *ed, int ndx, GElf_Dyn *dst) -{ - int ec; - Elf *e; - size_t msz; - Elf_Scn *scn; - Elf32_Dyn *dyn32; - Elf64_Dyn *dyn64; - uint32_t sh_type; - struct _Libelf_Data *d; - - d = (struct _Libelf_Data *) ed; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_DYN) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_DYN, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_data.d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - dyn32 = (Elf32_Dyn *) d->d_data.d_buf + ndx; - - dst->d_tag = dyn32->d_tag; - dst->d_un.d_val = (Elf64_Xword) dyn32->d_un.d_val; - - } else { - - dyn64 = (Elf64_Dyn *) d->d_data.d_buf + ndx; - - *dst = *dyn64; - } - - return (dst); -} - -int -gelf_update_dyn(Elf_Data *ed, int ndx, GElf_Dyn *ds) -{ - int ec; - Elf *e; - size_t msz; - Elf_Scn *scn; - Elf32_Dyn *dyn32; - Elf64_Dyn *dyn64; - uint32_t sh_type; - struct _Libelf_Data *d; - - d = (struct _Libelf_Data *) ed; - - if (d == NULL || ndx < 0 || ds == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_DYN) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_DYN, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_data.d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - dyn32 = (Elf32_Dyn *) d->d_data.d_buf + ndx; - - LIBELF_COPY_S32(dyn32, ds, d_tag); - LIBELF_COPY_U32(dyn32, ds, d_un.d_val); - } else { - dyn64 = (Elf64_Dyn *) d->d_data.d_buf + ndx; - - *dyn64 = *ds; - } - - return (1); -} diff --git a/src/libelf/gelf_ehdr.c b/src/libelf/gelf_ehdr.c deleted file mode 100644 index 293bf7b..0000000 --- a/src/libelf/gelf_ehdr.c +++ /dev/null @@ -1,168 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include "gelf.h" -#include -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: gelf_ehdr.c 2268 2011-12-03 17:05:11Z jkoshy $"); - -Elf32_Ehdr * -elf32_getehdr(Elf *e) -{ - return (_libelf_ehdr(e, ELFCLASS32, 0)); -} - -Elf64_Ehdr * -elf64_getehdr(Elf *e) -{ - return (_libelf_ehdr(e, ELFCLASS64, 0)); -} - -GElf_Ehdr * -gelf_getehdr(Elf *e, GElf_Ehdr *d) -{ - int ec; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - - if (d == NULL || e == NULL || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - if ((eh32 = _libelf_ehdr(e, ELFCLASS32, 0)) == NULL) - return (NULL); - - (void) memcpy(d->e_ident, eh32->e_ident, - sizeof(eh32->e_ident)); - d->e_type = eh32->e_type; - d->e_machine = eh32->e_machine; - d->e_version = eh32->e_version; - d->e_entry = eh32->e_entry; - d->e_phoff = eh32->e_phoff; - d->e_shoff = eh32->e_shoff; - d->e_flags = eh32->e_flags; - d->e_ehsize = eh32->e_ehsize; - d->e_phentsize = eh32->e_phentsize; - d->e_phnum = eh32->e_phnum; - d->e_shentsize = eh32->e_shentsize; - d->e_shnum = eh32->e_shnum; - d->e_shstrndx = eh32->e_shstrndx; - - return (d); - } - - assert(ec == ELFCLASS64); - - if ((eh64 = _libelf_ehdr(e, ELFCLASS64, 0)) == NULL) - return (NULL); - *d = *eh64; - - return (d); -} - -Elf32_Ehdr * -elf32_newehdr(Elf *e) -{ - return (_libelf_ehdr(e, ELFCLASS32, 1)); -} - -Elf64_Ehdr * -elf64_newehdr(Elf *e) -{ - return (_libelf_ehdr(e, ELFCLASS64, 1)); -} - -void * -gelf_newehdr(Elf *e, int ec) -{ - if (e != NULL && - (ec == ELFCLASS32 || ec == ELFCLASS64)) - return (_libelf_ehdr(e, ec, 1)); - - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); -} - -int -gelf_update_ehdr(Elf *e, GElf_Ehdr *s) -{ - int ec; - void *ehdr; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - - if (s== NULL || e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (e->e_cmd == ELF_C_READ) { - LIBELF_SET_ERROR(MODE, 0); - return (0); - } - - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) - return (0); - - (void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY); - - if (ec == ELFCLASS64) { - eh64 = (Elf64_Ehdr *) ehdr; - *eh64 = *s; - return (1); - } - - eh32 = (Elf32_Ehdr *) ehdr; - - (void) memcpy(eh32->e_ident, s->e_ident, sizeof(eh32->e_ident)); - - eh32->e_type = s->e_type; - eh32->e_machine = s->e_machine; - eh32->e_version = s->e_version; - LIBELF_COPY_U32(eh32, s, e_entry); - LIBELF_COPY_U32(eh32, s, e_phoff); - LIBELF_COPY_U32(eh32, s, e_shoff); - eh32->e_flags = s->e_flags; - eh32->e_ehsize = s->e_ehsize; - eh32->e_phentsize = s->e_phentsize; - eh32->e_phnum = s->e_phnum; - eh32->e_shentsize = s->e_shentsize; - eh32->e_shnum = s->e_shnum; - eh32->e_shstrndx = s->e_shstrndx; - - return (1); -} diff --git a/src/libelf/gelf_fsize.c b/src/libelf/gelf_fsize.c deleted file mode 100644 index 7139e42..0000000 --- a/src/libelf/gelf_fsize.c +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include "gelf.h" -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: gelf_fsize.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -size_t -elf32_fsize(Elf_Type t, size_t c, unsigned int v) -{ - return (_libelf_fsize(t, ELFCLASS32, v, c)); -} - -size_t -elf64_fsize(Elf_Type t, size_t c, unsigned int v) -{ - return (_libelf_fsize(t, ELFCLASS64, v, c)); -} - -size_t -gelf_fsize(Elf *e, Elf_Type t, size_t c, unsigned int v) -{ - - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (e->e_class == ELFCLASS32 || e->e_class == ELFCLASS64) - return (_libelf_fsize(t, e->e_class, v, c)); - - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); -} diff --git a/src/libelf/gelf_getclass.c b/src/libelf/gelf_getclass.c deleted file mode 100644 index 03df319..0000000 --- a/src/libelf/gelf_getclass.c +++ /dev/null @@ -1,39 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include "gelf.h" - -#include "_libelf.h" - -ELFTC_VCSID("$Id: gelf_getclass.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -int -gelf_getclass(Elf *e) -{ - return (e != NULL ? e->e_class : ELFCLASSNONE); -} diff --git a/src/libelf/gelf_move.c b/src/libelf/gelf_move.c deleted file mode 100644 index 0ba362e..0000000 --- a/src/libelf/gelf_move.c +++ /dev/null @@ -1,157 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include "gelf.h" -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: gelf_move.c 2272 2011-12-03 17:07:31Z jkoshy $"); - -GElf_Move * -gelf_getmove(Elf_Data *ed, int ndx, GElf_Move *dst) -{ - int ec; - Elf *e; - size_t msz; - Elf_Scn *scn; - uint32_t sh_type; - Elf32_Move *move32; - Elf64_Move *move64; - struct _Libelf_Data *d; - - d = (struct _Libelf_Data *) ed; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_data.d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - - move32 = (Elf32_Move *) d->d_data.d_buf + ndx; - - dst->m_value = move32->m_value; - dst->m_info = (Elf64_Xword) move32->m_info; - dst->m_poffset = (Elf64_Xword) move32->m_poffset; - dst->m_repeat = move32->m_repeat; - dst->m_stride = move32->m_stride; - } else { - - move64 = (Elf64_Move *) d->d_data.d_buf + ndx; - - *dst = *move64; - } - - return (dst); -} - -int -gelf_update_move(Elf_Data *ed, int ndx, GElf_Move *gm) -{ - int ec; - Elf *e; - size_t msz; - Elf_Scn *scn; - uint32_t sh_type; - Elf32_Move *move32; - Elf64_Move *move64; - struct _Libelf_Data *d; - - d = (struct _Libelf_Data *) ed; - - if (d == NULL || ndx < 0 || gm == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_data.d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - move32 = (Elf32_Move *) d->d_data.d_buf + ndx; - - move32->m_value = gm->m_value; - LIBELF_COPY_U32(move32, gm, m_info); - LIBELF_COPY_U32(move32, gm, m_poffset); - move32->m_repeat = gm->m_repeat; - move32->m_stride = gm->m_stride; - - } else { - move64 = (Elf64_Move *) d->d_data.d_buf + ndx; - - *move64 = *gm; - } - - return (1); -} diff --git a/src/libelf/gelf_phdr.c b/src/libelf/gelf_phdr.c deleted file mode 100644 index c414c5d..0000000 --- a/src/libelf/gelf_phdr.c +++ /dev/null @@ -1,178 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include "gelf.h" -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: gelf_phdr.c 2268 2011-12-03 17:05:11Z jkoshy $"); - -Elf32_Phdr * -elf32_getphdr(Elf *e) -{ - return (_libelf_getphdr(e, ELFCLASS32)); -} - -Elf64_Phdr * -elf64_getphdr(Elf *e) -{ - return (_libelf_getphdr(e, ELFCLASS64)); -} - -GElf_Phdr * -gelf_getphdr(Elf *e, int index, GElf_Phdr *d) -{ - int ec; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - Elf32_Phdr *ep32; - Elf64_Phdr *ep64; - - if (d == NULL || e == NULL || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) || - (e->e_kind != ELF_K_ELF) || index < 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - if ((eh32 = _libelf_ehdr(e, ELFCLASS32, 0)) == NULL || - ((ep32 = _libelf_getphdr(e, ELFCLASS32)) == NULL)) - return (NULL); - - if (index >= eh32->e_phnum) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ep32 += index; - - d->p_type = ep32->p_type; - d->p_offset = ep32->p_offset; - d->p_vaddr = (Elf64_Addr) ep32->p_vaddr; - d->p_paddr = (Elf64_Addr) ep32->p_paddr; - d->p_filesz = (Elf64_Xword) ep32->p_filesz; - d->p_memsz = (Elf64_Xword) ep32->p_memsz; - d->p_flags = ep32->p_flags; - d->p_align = (Elf64_Xword) ep32->p_align; - - } else { - if ((eh64 = _libelf_ehdr(e, ELFCLASS64, 0)) == NULL || - (ep64 = _libelf_getphdr(e, ELFCLASS64)) == NULL) - return (NULL); - - if (index >= eh64->e_phnum) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ep64 += index; - - *d = *ep64; - } - - return (d); -} - -Elf32_Phdr * -elf32_newphdr(Elf *e, size_t count) -{ - return (_libelf_newphdr(e, ELFCLASS32, count)); -} - -Elf64_Phdr * -elf64_newphdr(Elf *e, size_t count) -{ - return (_libelf_newphdr(e, ELFCLASS64, count)); -} - -void * -gelf_newphdr(Elf *e, size_t count) -{ - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - return (_libelf_newphdr(e, e->e_class, count)); -} - -int -gelf_update_phdr(Elf *e, int ndx, GElf_Phdr *s) -{ - int ec, phnum; - void *ehdr; - Elf32_Phdr *ph32; - Elf64_Phdr *ph64; - - if (s == NULL || e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (e->e_cmd == ELF_C_READ) { - LIBELF_SET_ERROR(MODE, 0); - return (0); - } - - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) - return (0); - - if (ec == ELFCLASS32) - phnum = ((Elf32_Ehdr *) ehdr)->e_phnum; - else - phnum = ((Elf64_Ehdr *) ehdr)->e_phnum; - - if (ndx < 0 || ndx > phnum) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - (void) elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY); - - if (ec == ELFCLASS64) { - ph64 = e->e_u.e_elf.e_phdr.e_phdr64 + ndx; - *ph64 = *s; - return (1); - } - - ph32 = e->e_u.e_elf.e_phdr.e_phdr32 + ndx; - - ph32->p_type = s->p_type; - ph32->p_flags = s->p_flags; - LIBELF_COPY_U32(ph32, s, p_offset); - LIBELF_COPY_U32(ph32, s, p_vaddr); - LIBELF_COPY_U32(ph32, s, p_paddr); - LIBELF_COPY_U32(ph32, s, p_filesz); - LIBELF_COPY_U32(ph32, s, p_memsz); - LIBELF_COPY_U32(ph32, s, p_align); - - return (1); -} diff --git a/src/libelf/gelf_rel.c b/src/libelf/gelf_rel.c deleted file mode 100644 index 51e3f4a..0000000 --- a/src/libelf/gelf_rel.c +++ /dev/null @@ -1,159 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include "gelf.h" -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: gelf_rel.c 2272 2011-12-03 17:07:31Z jkoshy $"); - -GElf_Rel * -gelf_getrel(Elf_Data *ed, int ndx, GElf_Rel *dst) -{ - int ec; - Elf *e; - size_t msz; - Elf_Scn *scn; - uint32_t sh_type; - Elf32_Rel *rel32; - Elf64_Rel *rel64; - struct _Libelf_Data *d; - - d = (struct _Libelf_Data *) ed; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_REL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_REL, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_data.d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - rel32 = (Elf32_Rel *) d->d_data.d_buf + ndx; - - dst->r_offset = (Elf64_Addr) rel32->r_offset; - dst->r_info = ELF64_R_INFO( - (Elf64_Xword) ELF32_R_SYM(rel32->r_info), - ELF32_R_TYPE(rel32->r_info)); - - } else { - - rel64 = (Elf64_Rel *) d->d_data.d_buf + ndx; - - *dst = *rel64; - } - - return (dst); -} - -int -gelf_update_rel(Elf_Data *ed, int ndx, GElf_Rel *dr) -{ - int ec; - Elf *e; - size_t msz; - Elf_Scn *scn; - uint32_t sh_type; - Elf32_Rel *rel32; - Elf64_Rel *rel64; - struct _Libelf_Data *d; - - d = (struct _Libelf_Data *) ed; - - if (d == NULL || ndx < 0 || dr == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_REL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_REL, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_data.d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - rel32 = (Elf32_Rel *) d->d_data.d_buf + ndx; - - LIBELF_COPY_U32(rel32, dr, r_offset); - - if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) || - ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) { - LIBELF_SET_ERROR(RANGE, 0); - return (0); - } - rel32->r_info = ELF32_R_INFO(ELF64_R_SYM(dr->r_info), - ELF64_R_TYPE(dr->r_info)); - } else { - rel64 = (Elf64_Rel *) d->d_data.d_buf + ndx; - - *rel64 = *dr; - } - - return (1); -} diff --git a/src/libelf/gelf_rela.c b/src/libelf/gelf_rela.c deleted file mode 100644 index d5e62a7..0000000 --- a/src/libelf/gelf_rela.c +++ /dev/null @@ -1,162 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include "gelf.h" -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: gelf_rela.c 2272 2011-12-03 17:07:31Z jkoshy $"); - -GElf_Rela * -gelf_getrela(Elf_Data *ed, int ndx, GElf_Rela *dst) -{ - int ec; - Elf *e; - size_t msz; - Elf_Scn *scn; - uint32_t sh_type; - Elf32_Rela *rela32; - Elf64_Rela *rela64; - struct _Libelf_Data *d; - - d = (struct _Libelf_Data *) ed; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_RELA) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_RELA, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_data.d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - rela32 = (Elf32_Rela *) d->d_data.d_buf + ndx; - - dst->r_offset = (Elf64_Addr) rela32->r_offset; - dst->r_info = ELF64_R_INFO( - (Elf64_Xword) ELF32_R_SYM(rela32->r_info), - ELF32_R_TYPE(rela32->r_info)); - dst->r_addend = (Elf64_Sxword) rela32->r_addend; - - } else { - - rela64 = (Elf64_Rela *) d->d_data.d_buf + ndx; - - *dst = *rela64; - } - - return (dst); -} - -int -gelf_update_rela(Elf_Data *ed, int ndx, GElf_Rela *dr) -{ - int ec; - Elf *e; - size_t msz; - Elf_Scn *scn; - uint32_t sh_type; - Elf32_Rela *rela32; - Elf64_Rela *rela64; - struct _Libelf_Data *d; - - d = (struct _Libelf_Data *) ed; - - if (d == NULL || ndx < 0 || dr == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_RELA) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_RELA, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_data.d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - rela32 = (Elf32_Rela *) d->d_data.d_buf + ndx; - - LIBELF_COPY_U32(rela32, dr, r_offset); - - if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) || - ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) { - LIBELF_SET_ERROR(RANGE, 0); - return (0); - } - rela32->r_info = ELF32_R_INFO(ELF64_R_SYM(dr->r_info), - ELF64_R_TYPE(dr->r_info)); - - LIBELF_COPY_S32(rela32, dr, r_addend); - } else { - rela64 = (Elf64_Rela *) d->d_data.d_buf + ndx; - - *rela64 = *dr; - } - - return (1); -} diff --git a/src/libelf/gelf_shdr.c b/src/libelf/gelf_shdr.c deleted file mode 100644 index 6263870..0000000 --- a/src/libelf/gelf_shdr.c +++ /dev/null @@ -1,131 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include "gelf.h" -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: gelf_shdr.c 2268 2011-12-03 17:05:11Z jkoshy $"); - -Elf32_Shdr * -elf32_getshdr(Elf_Scn *s) -{ - return (_libelf_getshdr(s, ELFCLASS32)); -} - -Elf64_Shdr * -elf64_getshdr(Elf_Scn *s) -{ - return (_libelf_getshdr(s, ELFCLASS64)); -} - -GElf_Shdr * -gelf_getshdr(Elf_Scn *s, GElf_Shdr *d) -{ - int ec; - void *sh; - Elf32_Shdr *sh32; - Elf64_Shdr *sh64; - - if (d == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((sh = _libelf_getshdr(s, ELFCLASSNONE)) == NULL) - return (NULL); - - ec = s->s_elf->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) { - sh32 = (Elf32_Shdr *) sh; - - d->sh_name = sh32->sh_name; - d->sh_type = sh32->sh_type; - d->sh_flags = (Elf64_Xword) sh32->sh_flags; - d->sh_addr = (Elf64_Addr) sh32->sh_addr; - d->sh_offset = (Elf64_Off) sh32->sh_offset; - d->sh_size = (Elf64_Xword) sh32->sh_size; - d->sh_link = sh32->sh_link; - d->sh_info = sh32->sh_info; - d->sh_addralign = (Elf64_Xword) sh32->sh_addralign; - d->sh_entsize = (Elf64_Xword) sh32->sh_entsize; - } else { - sh64 = (Elf64_Shdr *) sh; - *d = *sh64; - } - - return (d); -} - -int -gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *s) -{ - int ec; - Elf *e; - Elf32_Shdr *sh32; - - - if (s == NULL || scn == NULL || (e = scn->s_elf) == NULL || - e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (e->e_cmd == ELF_C_READ) { - LIBELF_SET_ERROR(MODE, 0); - return (0); - } - - (void) elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY); - - if (ec == ELFCLASS64) { - scn->s_shdr.s_shdr64 = *s; - return (1); - } - - sh32 = &scn->s_shdr.s_shdr32; - - sh32->sh_name = s->sh_name; - sh32->sh_type = s->sh_type; - LIBELF_COPY_U32(sh32, s, sh_flags); - LIBELF_COPY_U32(sh32, s, sh_addr); - LIBELF_COPY_U32(sh32, s, sh_offset); - LIBELF_COPY_U32(sh32, s, sh_size); - sh32->sh_link = s->sh_link; - sh32->sh_info = s->sh_info; - LIBELF_COPY_U32(sh32, s, sh_addralign); - LIBELF_COPY_U32(sh32, s, sh_entsize); - - return (1); -} diff --git a/src/libelf/gelf_sym.c b/src/libelf/gelf_sym.c deleted file mode 100644 index 7f72ded..0000000 --- a/src/libelf/gelf_sym.c +++ /dev/null @@ -1,160 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include "gelf.h" -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: gelf_sym.c 2272 2011-12-03 17:07:31Z jkoshy $"); - -GElf_Sym * -gelf_getsym(Elf_Data *ed, int ndx, GElf_Sym *dst) -{ - int ec; - Elf *e; - size_t msz; - Elf_Scn *scn; - uint32_t sh_type; - Elf32_Sym *sym32; - Elf64_Sym *sym64; - struct _Libelf_Data *d; - - d = (struct _Libelf_Data *) ed; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_SYM, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_data.d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - - sym32 = (Elf32_Sym *) d->d_data.d_buf + ndx; - - dst->st_name = sym32->st_name; - dst->st_value = (Elf64_Addr) sym32->st_value; - dst->st_size = (Elf64_Xword) sym32->st_size; - dst->st_info = ELF64_ST_INFO(ELF32_ST_BIND(sym32->st_info), - ELF32_ST_TYPE(sym32->st_info)); - dst->st_other = sym32->st_other; - dst->st_shndx = sym32->st_shndx; - } else { - - sym64 = (Elf64_Sym *) d->d_data.d_buf + ndx; - - *dst = *sym64; - } - - return (dst); -} - -int -gelf_update_sym(Elf_Data *ed, int ndx, GElf_Sym *gs) -{ - int ec; - Elf *e; - size_t msz; - Elf_Scn *scn; - uint32_t sh_type; - Elf32_Sym *sym32; - Elf64_Sym *sym64; - struct _Libelf_Data *d; - - d = (struct _Libelf_Data *) ed; - - if (d == NULL || ndx < 0 || gs == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_SYM, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_data.d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - sym32 = (Elf32_Sym *) d->d_data.d_buf + ndx; - - sym32->st_name = gs->st_name; - sym32->st_info = gs->st_info; - sym32->st_other = gs->st_other; - sym32->st_shndx = gs->st_shndx; - - LIBELF_COPY_U32(sym32, gs, st_value); - LIBELF_COPY_U32(sym32, gs, st_size); - } else { - sym64 = (Elf64_Sym *) d->d_data.d_buf + ndx; - - *sym64 = *gs; - } - - return (1); -} diff --git a/src/libelf/gelf_syminfo.c b/src/libelf/gelf_syminfo.c deleted file mode 100644 index 6193339..0000000 --- a/src/libelf/gelf_syminfo.c +++ /dev/null @@ -1,151 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include "gelf.h" - -#include "_libelf.h" - -ELFTC_VCSID("$Id: gelf_syminfo.c 2272 2011-12-03 17:07:31Z jkoshy $"); - -GElf_Syminfo * -gelf_getsyminfo(Elf_Data *ed, int ndx, GElf_Syminfo *dst) -{ - int ec; - Elf *e; - size_t msz; - Elf_Scn *scn; - uint32_t sh_type; - struct _Libelf_Data *d; - Elf32_Syminfo *syminfo32; - Elf64_Syminfo *syminfo64; - - d = (struct _Libelf_Data *) ed; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_SYMINFO) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_data.d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - - syminfo32 = (Elf32_Syminfo *) d->d_data.d_buf + ndx; - - dst->si_boundto = syminfo32->si_boundto; - dst->si_flags = syminfo32->si_flags; - - } else { - - syminfo64 = (Elf64_Syminfo *) d->d_data.d_buf + ndx; - - *dst = *syminfo64; - } - - return (dst); -} - -int -gelf_update_syminfo(Elf_Data *ed, int ndx, GElf_Syminfo *gs) -{ - int ec; - Elf *e; - size_t msz; - Elf_Scn *scn; - uint32_t sh_type; - struct _Libelf_Data *d; - Elf32_Syminfo *syminfo32; - Elf64_Syminfo *syminfo64; - - d = (struct _Libelf_Data *) ed; - - if (d == NULL || ndx < 0 || gs == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_SYMINFO) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_data.d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - syminfo32 = (Elf32_Syminfo *) d->d_data.d_buf + ndx; - - syminfo32->si_boundto = gs->si_boundto; - syminfo32->si_flags = gs->si_flags; - - } else { - syminfo64 = (Elf64_Syminfo *) d->d_data.d_buf + ndx; - - *syminfo64 = *gs; - } - - return (1); -} diff --git a/src/libelf/gelf_symshndx.c b/src/libelf/gelf_symshndx.c deleted file mode 100644 index 804cb95..0000000 --- a/src/libelf/gelf_symshndx.c +++ /dev/null @@ -1,136 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include "gelf.h" - -#include "_libelf.h" - -ELFTC_VCSID("$Id: gelf_symshndx.c 2283 2011-12-04 04:07:24Z jkoshy $"); - -GElf_Sym * -gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst, - Elf32_Word *shindex) -{ - int ec; - Elf *e; - size_t msz; - Elf_Scn *scn; - uint32_t sh_type; - struct _Libelf_Data *ld, *lid; - - ld = (struct _Libelf_Data *) d; - lid = (struct _Libelf_Data *) id; - - if (gelf_getsym(d, ndx, dst) == 0) - return (NULL); - - if (lid == NULL || (scn = lid->d_scn) == NULL || - (e = scn->s_elf) == NULL || (e != ld->d_scn->s_elf) || - shindex == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_WORD || - id->d_type != ELF_T_WORD) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_WORD, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= id->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - *shindex = ((Elf32_Word *) id->d_buf)[ndx]; - - return (dst); -} - -int -gelf_update_symshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *gs, - Elf32_Word xindex) -{ - int ec; - Elf *e; - size_t msz; - Elf_Scn *scn; - uint32_t sh_type; - struct _Libelf_Data *ld, *lid; - - ld = (struct _Libelf_Data *) d; - lid = (struct _Libelf_Data *) id; - - if (gelf_update_sym(d, ndx, gs) == 0) - return (0); - - if (lid == NULL || (scn = lid->d_scn) == NULL || - (e = scn->s_elf) == NULL || (e != ld->d_scn->s_elf)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_WORD || - d->d_type != ELF_T_WORD) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_WORD, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= id->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - *(((Elf32_Word *) id->d_buf) + ndx) = xindex; - - return (1); -} diff --git a/src/libelf/gelf_xlate.c b/src/libelf/gelf_xlate.c deleted file mode 100644 index 478222d..0000000 --- a/src/libelf/gelf_xlate.c +++ /dev/null @@ -1,81 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include "gelf.h" -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: gelf_xlate.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -Elf_Data * -elf32_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) -{ - return _libelf_xlate(dst, src, encoding, ELFCLASS32, ELF_TOFILE); -} - -Elf_Data * -elf64_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) -{ - return _libelf_xlate(dst, src, encoding, ELFCLASS64, ELF_TOFILE); -} - -Elf_Data * -elf32_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) -{ - return _libelf_xlate(dst, src, encoding, ELFCLASS32, ELF_TOMEMORY); -} - -Elf_Data * -elf64_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) -{ - return _libelf_xlate(dst, src, encoding, ELFCLASS64, ELF_TOMEMORY); -} - -Elf_Data * -gelf_xlatetom(Elf *e, Elf_Data *dst, const Elf_Data *src, - unsigned int encoding) -{ - if (e != NULL) - return (_libelf_xlate(dst, src, encoding, e->e_class, - ELF_TOMEMORY)); - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); -} - -Elf_Data * -gelf_xlatetof(Elf *e, Elf_Data *dst, const Elf_Data *src, - unsigned int encoding) -{ - if (e != NULL) - return (_libelf_xlate(dst, src, encoding, e->e_class, - ELF_TOFILE)); - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); -} diff --git a/src/libelf/libelf.h b/src/libelf/libelf.h deleted file mode 100644 index 21cc2f9..0000000 --- a/src/libelf/libelf.h +++ /dev/null @@ -1,250 +0,0 @@ -/*- - * Copyright (c) 2006,2008-2010 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: libelf.h 2366 2011-12-29 06:12:14Z jkoshy $ - */ - -#ifndef _LIBELF_H_ -#define _LIBELF_H_ - -#include - -#include "elfdefinitions.h" - -/* Library private data structures */ -typedef struct _Elf Elf; -typedef struct _Elf_Scn Elf_Scn; - -/* File types */ -typedef enum { - ELF_K_NONE = 0, - ELF_K_AR, /* `ar' archives */ - ELF_K_COFF, /* COFF files (unsupported) */ - ELF_K_ELF, /* ELF files */ - ELF_K_NUM -} Elf_Kind; - -#define ELF_K_FIRST ELF_K_NONE -#define ELF_K_LAST ELF_K_NUM - -/* Data types */ -typedef enum { - ELF_T_ADDR, - ELF_T_BYTE, - ELF_T_CAP, - ELF_T_DYN, - ELF_T_EHDR, - ELF_T_HALF, - ELF_T_LWORD, - ELF_T_MOVE, - ELF_T_MOVEP, - ELF_T_NOTE, - ELF_T_OFF, - ELF_T_PHDR, - ELF_T_REL, - ELF_T_RELA, - ELF_T_SHDR, - ELF_T_SWORD, - ELF_T_SXWORD, - ELF_T_SYMINFO, - ELF_T_SYM, - ELF_T_VDEF, - ELF_T_VNEED, - ELF_T_WORD, - ELF_T_XWORD, - ELF_T_GNUHASH, /* GNU style hash tables. */ - ELF_T_NUM -} Elf_Type; - -#define ELF_T_FIRST ELF_T_ADDR -#define ELF_T_LAST ELF_T_GNUHASH - -/* Commands */ -typedef enum { - ELF_C_NULL = 0, - ELF_C_CLR, - ELF_C_FDDONE, - ELF_C_FDREAD, - ELF_C_RDWR, - ELF_C_READ, - ELF_C_SET, - ELF_C_WRITE, - ELF_C_NUM -} Elf_Cmd; - -#define ELF_C_FIRST ELF_C_NULL -#define ELF_C_LAST ELF_C_NUM - -/* - * An `Elf_Data' structure describes data in an - * ELF section. - */ -typedef struct _Elf_Data { - /* - * `Public' members that are part of the ELF(3) API. - */ - uint64_t d_align; - void *d_buf; - uint64_t d_off; - uint64_t d_size; - Elf_Type d_type; - unsigned int d_version; -} Elf_Data; - -/* - * An `Elf_Arhdr' structure describes an archive - * header. - */ -typedef struct { - time_t ar_date; - char *ar_name; /* archive member name */ - gid_t ar_gid; - mode_t ar_mode; - char *ar_rawname; /* 'raw' member name */ - size_t ar_size; - uid_t ar_uid; - - /* - * Members that are not part of the public API. - */ - int ar_flags; -} Elf_Arhdr; - -/* - * An `Elf_Arsym' describes an entry in the archive - * symbol table. - */ -typedef struct { - off_t as_off; /* byte offset to member's header */ - unsigned long as_hash; /* elf_hash() value for name */ - char *as_name; /* null terminated symbol name */ -} Elf_Arsym; - -/* - * Error numbers. - */ - -enum Elf_Error { - ELF_E_NONE, /* No error */ - ELF_E_ARCHIVE, /* Malformed ar(1) archive */ - ELF_E_ARGUMENT, /* Invalid argument */ - ELF_E_CLASS, /* Mismatched ELF class */ - ELF_E_DATA, /* Invalid data descriptor */ - ELF_E_HEADER, /* Missing or malformed ELF header */ - ELF_E_IO, /* I/O error */ - ELF_E_LAYOUT, /* Layout constraint violation */ - ELF_E_MODE, /* Wrong mode for ELF descriptor */ - ELF_E_RANGE, /* Value out of range */ - ELF_E_RESOURCE, /* Resource exhaustion */ - ELF_E_SECTION, /* Invalid section descriptor */ - ELF_E_SEQUENCE, /* API calls out of sequence */ - ELF_E_UNIMPL, /* Feature is unimplemented */ - ELF_E_VERSION, /* Unknown API version */ - ELF_E_NUM /* Max error number */ -}; - -/* - * Flags defined by the API. - */ - -#define ELF_F_LAYOUT 0x001U /* application will layout the file */ -#define ELF_F_DIRTY 0x002U /* a section or ELF file is dirty */ - -/* ELF(3) API extensions. */ -#define ELF_F_ARCHIVE 0x100U /* archive creation */ -#define ELF_F_ARCHIVE_SYSV 0x200U /* SYSV style archive */ - -Elf *elf_begin(int _fd, Elf_Cmd _cmd, Elf *_elf); -int elf_cntl(Elf *_elf, Elf_Cmd _cmd); -int elf_end(Elf *_elf); -const char *elf_errmsg(int _error); -int elf_errno(void); -void elf_fill(int _fill); -unsigned int elf_flagarhdr(Elf_Arhdr *_arh, Elf_Cmd _cmd, - unsigned int _flags); -unsigned int elf_flagdata(Elf_Data *_data, Elf_Cmd _cmd, - unsigned int _flags); -unsigned int elf_flagehdr(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); -unsigned int elf_flagelf(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); -unsigned int elf_flagphdr(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); -unsigned int elf_flagscn(Elf_Scn *_scn, Elf_Cmd _cmd, unsigned int _flags); -unsigned int elf_flagshdr(Elf_Scn *_scn, Elf_Cmd _cmd, unsigned int _flags); -Elf_Arhdr *elf_getarhdr(Elf *_elf); -Elf_Arsym *elf_getarsym(Elf *_elf, size_t *_ptr); -off_t elf_getbase(Elf *_elf); -Elf_Data *elf_getdata(Elf_Scn *, Elf_Data *); -char *elf_getident(Elf *_elf, size_t *_ptr); -int elf_getphdrnum(Elf *_elf, size_t *_dst); -int elf_getphnum(Elf *_elf, size_t *_dst); /* Deprecated */ -Elf_Scn *elf_getscn(Elf *_elf, size_t _index); -int elf_getshdrnum(Elf *_elf, size_t *_dst); -int elf_getshnum(Elf *_elf, size_t *_dst); /* Deprecated */ -int elf_getshdrstrndx(Elf *_elf, size_t *_dst); -int elf_getshstrndx(Elf *_elf, size_t *_dst); /* Deprecated */ -unsigned long elf_hash(const char *_name); -Elf_Kind elf_kind(Elf *_elf); -Elf *elf_memory(char *_image, size_t _size); -size_t elf_ndxscn(Elf_Scn *_scn); -Elf_Data *elf_newdata(Elf_Scn *_scn); -Elf_Scn *elf_newscn(Elf *_elf); -Elf_Scn *elf_nextscn(Elf *_elf, Elf_Scn *_scn); -Elf_Cmd elf_next(Elf *_elf); -Elf *elf_open(int _fd); -Elf *elf_openmemory(char *_image, size_t _size); -off_t elf_rand(Elf *_elf, off_t _off); -Elf_Data *elf_rawdata(Elf_Scn *_scn, Elf_Data *_data); -char *elf_rawfile(Elf *_elf, size_t *_size); -int elf_setshstrndx(Elf *_elf, size_t _shnum); -char *elf_strptr(Elf *_elf, size_t _section, size_t _offset); -off_t elf_update(Elf *_elf, Elf_Cmd _cmd); -unsigned int elf_version(unsigned int _version); - -long elf32_checksum(Elf *_elf); -size_t elf32_fsize(Elf_Type _type, size_t _count, - unsigned int _version); -Elf32_Ehdr *elf32_getehdr(Elf *_elf); -Elf32_Phdr *elf32_getphdr(Elf *_elf); -Elf32_Shdr *elf32_getshdr(Elf_Scn *_scn); -Elf32_Ehdr *elf32_newehdr(Elf *_elf); -Elf32_Phdr *elf32_newphdr(Elf *_elf, size_t _count); -Elf_Data *elf32_xlatetof(Elf_Data *_dst, const Elf_Data *_src, - unsigned int _enc); -Elf_Data *elf32_xlatetom(Elf_Data *_dst, const Elf_Data *_src, - unsigned int _enc); - -long elf64_checksum(Elf *_elf); -size_t elf64_fsize(Elf_Type _type, size_t _count, - unsigned int _version); -Elf64_Ehdr *elf64_getehdr(Elf *_elf); -Elf64_Phdr *elf64_getphdr(Elf *_elf); -Elf64_Shdr *elf64_getshdr(Elf_Scn *_scn); -Elf64_Ehdr *elf64_newehdr(Elf *_elf); -Elf64_Phdr *elf64_newphdr(Elf *_elf, size_t _count); -Elf_Data *elf64_xlatetof(Elf_Data *_dst, const Elf_Data *_src, - unsigned int _enc); -Elf_Data *elf64_xlatetom(Elf_Data *_dst, const Elf_Data *_src, - unsigned int _enc); - -#endif /* _LIBELF_H_ */ diff --git a/src/libelf/libelf_align.c b/src/libelf/libelf_align.c deleted file mode 100644 index 9550c5b..0000000 --- a/src/libelf/libelf_align.c +++ /dev/null @@ -1,137 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: libelf_align.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -struct align { - int a32; - int a64; -}; - -#ifdef __GNUC__ -#define MALIGN(N) { \ - .a32 = __alignof__(Elf32_##N), \ - .a64 = __alignof__(Elf64_##N) \ - } -#define MALIGN64(V) { \ - .a32 = 0, \ - .a64 = __alignof__(Elf64_##V) \ - } -#define MALIGN_WORD() { \ - .a32 = __alignof__(int32_t), \ - .a64 = __alignof__(int64_t) \ - } -#else -#error Need the __alignof__ builtin. -#endif -#define UNSUPPORTED() { \ - .a32 = 0, \ - .a64 = 0 \ - } - -static struct align malign[ELF_T_NUM] = { - [ELF_T_ADDR] = MALIGN(Addr), - [ELF_T_BYTE] = { .a32 = 1, .a64 = 1 }, - [ELF_T_CAP] = MALIGN(Cap), - [ELF_T_DYN] = MALIGN(Dyn), - [ELF_T_EHDR] = MALIGN(Ehdr), - [ELF_T_HALF] = MALIGN(Half), - [ELF_T_LWORD] = MALIGN(Lword), - [ELF_T_MOVE] = MALIGN(Move), - [ELF_T_MOVEP] = UNSUPPORTED(), - [ELF_T_NOTE] = MALIGN(Nhdr), - [ELF_T_OFF] = MALIGN(Off), - [ELF_T_PHDR] = MALIGN(Phdr), - [ELF_T_REL] = MALIGN(Rel), - [ELF_T_RELA] = MALIGN(Rela), - [ELF_T_SHDR] = MALIGN(Shdr), - [ELF_T_SWORD] = MALIGN(Sword), - [ELF_T_SXWORD] = MALIGN64(Sxword), - [ELF_T_SYM] = MALIGN(Sym), - [ELF_T_SYMINFO] = MALIGN(Syminfo), - [ELF_T_VDEF] = MALIGN(Verdef), - [ELF_T_VNEED] = MALIGN(Verneed), - [ELF_T_WORD] = MALIGN(Word), - [ELF_T_XWORD] = MALIGN64(Xword), - [ELF_T_GNUHASH] = MALIGN_WORD() -}; - -int -_libelf_malign(Elf_Type t, int elfclass) -{ - if (t >= ELF_T_NUM || (int) t < 0) - return (0); - - return (elfclass == ELFCLASS32 ? malign[t].a32 : - malign[t].a64); -} - -#define FALIGN(A32,A64) { .a32 = (A32), .a64 = (A64) } - -static struct align falign[ELF_T_NUM] = { - [ELF_T_ADDR] = FALIGN(4,8), - [ELF_T_BYTE] = FALIGN(1,1), - [ELF_T_CAP] = FALIGN(4,8), - [ELF_T_DYN] = FALIGN(4,8), - [ELF_T_EHDR] = FALIGN(4,8), - [ELF_T_HALF] = FALIGN(2,2), - [ELF_T_LWORD] = FALIGN(8,8), - [ELF_T_MOVE] = FALIGN(8,8), - [ELF_T_MOVEP] = UNSUPPORTED(), - [ELF_T_NOTE] = FALIGN(4,4), - [ELF_T_OFF] = FALIGN(4,8), - [ELF_T_PHDR] = FALIGN(4,8), - [ELF_T_REL] = FALIGN(4,8), - [ELF_T_RELA] = FALIGN(4,8), - [ELF_T_SHDR] = FALIGN(4,8), - [ELF_T_SWORD] = FALIGN(4,4), - [ELF_T_SXWORD] = FALIGN(0,8), - [ELF_T_SYM] = FALIGN(4,8), - [ELF_T_SYMINFO] = FALIGN(2,2), - [ELF_T_VDEF] = FALIGN(4,4), - [ELF_T_VNEED] = FALIGN(4,4), - [ELF_T_WORD] = FALIGN(4,4), - [ELF_T_XWORD] = FALIGN(0,8), - [ELF_T_GNUHASH] = FALIGN(4,8) -}; - -int -_libelf_falign(Elf_Type t, int elfclass) -{ - if (t >= ELF_T_NUM || (int) t < 0) - return (0); - - return (elfclass == ELFCLASS32 ? falign[t].a32 : - falign[t].a64); -} diff --git a/src/libelf/libelf_allocate.c b/src/libelf/libelf_allocate.c deleted file mode 100644 index 9a5df6b..0000000 --- a/src/libelf/libelf_allocate.c +++ /dev/null @@ -1,212 +0,0 @@ -/*- - * Copyright (c) 2006,2008,2010 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Internal APIs - */ - -#include - -#include -#include -#include -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: libelf_allocate.c 2272 2011-12-03 17:07:31Z jkoshy $"); - -Elf * -_libelf_allocate_elf(void) -{ - Elf *e; - - if ((e = malloc(sizeof(*e))) == NULL) { - LIBELF_SET_ERROR(RESOURCE, errno); - return NULL; - } - - e->e_activations = 1; - e->e_hdr.e_rawhdr = NULL; - e->e_byteorder = ELFDATANONE; - e->e_class = ELFCLASSNONE; - e->e_cmd = ELF_C_NULL; - e->e_fd = -1; - e->e_flags = 0; - e->e_kind = ELF_K_NONE; - e->e_parent = NULL; - e->e_rawfile = NULL; - e->e_rawsize = 0; - e->e_version = LIBELF_PRIVATE(version); - - (void) memset(&e->e_u, 0, sizeof(e->e_u)); - - return (e); -} - -void -_libelf_init_elf(Elf *e, Elf_Kind kind) -{ - assert(e != NULL); - assert(e->e_kind == ELF_K_NONE); - - e->e_kind = kind; - - switch (kind) { - case ELF_K_ELF: - STAILQ_INIT(&e->e_u.e_elf.e_scn); - break; - default: - break; - } -} - -#define FREE(P) do { \ - if (P) \ - free(P); \ - } while (0) - - -Elf * -_libelf_release_elf(Elf *e) -{ - Elf_Arhdr *arh; - - switch (e->e_kind) { - case ELF_K_AR: - FREE(e->e_u.e_ar.e_symtab); - break; - - case ELF_K_ELF: - switch (e->e_class) { - case ELFCLASS32: - FREE(e->e_u.e_elf.e_ehdr.e_ehdr32); - FREE(e->e_u.e_elf.e_phdr.e_phdr32); - break; - case ELFCLASS64: - FREE(e->e_u.e_elf.e_ehdr.e_ehdr64); - FREE(e->e_u.e_elf.e_phdr.e_phdr64); - break; - } - - assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); - - if (e->e_flags & LIBELF_F_AR_HEADER) { - arh = e->e_hdr.e_arhdr; - FREE(arh->ar_name); - FREE(arh->ar_rawname); - free(arh); - } - - break; - - default: - break; - } - - free(e); - - return (NULL); -} - -struct _Libelf_Data * -_libelf_allocate_data(Elf_Scn *s) -{ - struct _Libelf_Data *d; - - if ((d = calloc((size_t) 1, sizeof(*d))) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - d->d_scn = s; - - return (d); -} - -struct _Libelf_Data * -_libelf_release_data(struct _Libelf_Data *d) -{ - - if (d->d_flags & LIBELF_F_DATA_MALLOCED) - free(d->d_data.d_buf); - - free(d); - - return (NULL); -} - -Elf_Scn * -_libelf_allocate_scn(Elf *e, size_t ndx) -{ - Elf_Scn *s; - - if ((s = calloc((size_t) 1, sizeof(Elf_Scn))) == NULL) { - LIBELF_SET_ERROR(RESOURCE, errno); - return (NULL); - } - - s->s_elf = e; - s->s_ndx = ndx; - - STAILQ_INIT(&s->s_data); - STAILQ_INIT(&s->s_rawdata); - - STAILQ_INSERT_TAIL(&e->e_u.e_elf.e_scn, s, s_next); - - return (s); -} - -Elf_Scn * -_libelf_release_scn(Elf_Scn *s) -{ - Elf *e; - struct _Libelf_Data *d, *td; - - assert(s != NULL); - - STAILQ_FOREACH_SAFE(d, &s->s_data, d_next, td) { - STAILQ_REMOVE(&s->s_data, d, _Libelf_Data, d_next); - d = _libelf_release_data(d); - } - - STAILQ_FOREACH_SAFE(d, &s->s_rawdata, d_next, td) { - assert((d->d_flags & LIBELF_F_DATA_MALLOCED) == 0); - STAILQ_REMOVE(&s->s_rawdata, d, _Libelf_Data, d_next); - d = _libelf_release_data(d); - } - - e = s->s_elf; - - assert(e != NULL); - - STAILQ_REMOVE(&e->e_u.e_elf.e_scn, s, _Elf_Scn, s_next); - - free(s); - - return (NULL); -} diff --git a/src/libelf/libelf_ar.c b/src/libelf/libelf_ar.c deleted file mode 100644 index c990d6d..0000000 --- a/src/libelf/libelf_ar.c +++ /dev/null @@ -1,461 +0,0 @@ -/*- - * Copyright (c) 2006,2008,2010 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include -#include -#include - -#include "_libelf.h" -#include "_libelf_ar.h" - -ELFTC_VCSID("$Id: libelf_ar.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -#define LIBELF_NALLOC_SIZE 16 - -/* - * `ar' archive handling. - * - * `ar' archives start with signature `ARMAG'. Each archive member is - * preceded by a header containing meta-data for the member. This - * header is described in (struct ar_hdr). The header always - * starts on an even address. File data is padded with "\n" - * characters to keep this invariant. - * - * Special considerations for `ar' archives: - * - * There are two variants of the `ar' archive format: traditional BSD - * and SVR4. These differ in the way long file names are treated, and - * in the layout of the archive symbol table. - * - * The `ar' header only has space for a 16 character file name. - * - * In the SVR4 format, file names are terminated with a '/', so this - * effectively leaves 15 characters for the actual file name. Longer - * file names stored in a separate 'string table' and referenced - * indirectly from the name field. The string table itself appears as - * an archive member with name "// ". An `indirect' file name in an - * `ar' header matches the pattern "/[0-9]*". The digits form a - * decimal number that corresponds to a byte offset into the string - * table where the actual file name of the object starts. Strings in - * the string table are padded to start on even addresses. - * - * In the BSD format, file names can be upto 16 characters. File - * names shorter than 16 characters are padded to 16 characters using - * (ASCII) space characters. File names with embedded spaces and file - * names longer than 16 characters are stored immediately after the - * archive header and the name field set to a special indirect name - * matching the pattern "#1/[0-9]+". The digits form a decimal number - * that corresponds to the actual length of the file name following - * the archive header. The content of the archive member immediately - * follows the file name, and the size field of the archive member - * holds the sum of the sizes of the member and of the appended file - * name. - * - * Archives may also have a symbol table (see ranlib(1)), mapping - * program symbols to object files inside the archive. - * - * In the SVR4 format, a symbol table uses a file name of "/ " in its - * archive header. The symbol table is structured as: - * - a 4-byte count of entries stored as a binary value, MSB first - * - 'n' 4-byte offsets, stored as binary values, MSB first - * - 'n' NUL-terminated strings, for ELF symbol names, stored unpadded. - * - * In the BSD format, the symbol table uses a file name of "__.SYMDEF". - * It is structured as two parts: - * - The first part is an array of "ranlib" structures preceded by - * the size of the array in bytes. Each "ranlib" structure - * describes one symbol. Each structure contains an offset into - * the string table for the symbol name, and a file offset into the - * archive for the member defining the symbol. - * - The second part is a string table containing NUL-terminated - * strings, preceded by the size of the string table in bytes. - * - * If the symbol table and string table are is present in an archive - * they must be the very first objects and in that order. - */ - - -/* - * Retrieve an archive header descriptor. - */ - -Elf_Arhdr * -_libelf_ar_gethdr(Elf *e) -{ - Elf *parent; - char *namelen; - Elf_Arhdr *eh; - size_t n, nlen; - struct ar_hdr *arh; - - if ((parent = e->e_parent) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - assert((e->e_flags & LIBELF_F_AR_HEADER) == 0); - - arh = (struct ar_hdr *) (uintptr_t) e->e_hdr.e_rawhdr; - - assert((uintptr_t) arh >= (uintptr_t) parent->e_rawfile + SARMAG); - assert((uintptr_t) arh <= (uintptr_t) parent->e_rawfile + - parent->e_rawsize - sizeof(struct ar_hdr)); - - if ((eh = malloc(sizeof(Elf_Arhdr))) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - e->e_hdr.e_arhdr = eh; - e->e_flags |= LIBELF_F_AR_HEADER; - - eh->ar_name = eh->ar_rawname = NULL; - - if ((eh->ar_name = _libelf_ar_get_translated_name(arh, parent)) == - NULL) - goto error; - - if (_libelf_ar_get_number(arh->ar_uid, sizeof(arh->ar_uid), 10, - &n) == 0) - goto error; - eh->ar_uid = (uid_t) n; - - if (_libelf_ar_get_number(arh->ar_gid, sizeof(arh->ar_gid), 10, - &n) == 0) - goto error; - eh->ar_gid = (gid_t) n; - - if (_libelf_ar_get_number(arh->ar_mode, sizeof(arh->ar_mode), 8, - &n) == 0) - goto error; - eh->ar_mode = (mode_t) n; - - if (_libelf_ar_get_number(arh->ar_size, sizeof(arh->ar_size), 10, - &n) == 0) - goto error; - - /* - * Get the true size of the member if extended naming is being used. - */ - if (IS_EXTENDED_BSD_NAME(arh->ar_name)) { - namelen = arh->ar_name + - LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE; - if (_libelf_ar_get_number(namelen, sizeof(arh->ar_name) - - LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE, 10, &nlen) == 0) - goto error; - n -= nlen; - } - - eh->ar_size = n; - - if ((eh->ar_rawname = _libelf_ar_get_raw_name(arh)) == NULL) - goto error; - - eh->ar_flags = 0; - - return (eh); - - error: - if (eh) { - if (eh->ar_name) - free(eh->ar_name); - if (eh->ar_rawname) - free(eh->ar_rawname); - free(eh); - } - - e->e_flags &= ~LIBELF_F_AR_HEADER; - e->e_hdr.e_rawhdr = (char *) arh; - - return (NULL); -} - -Elf * -_libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf) -{ - Elf *e; - char *member, *namelen; - size_t nsz, sz; - off_t next; - struct ar_hdr *arh; - - assert(elf->e_kind == ELF_K_AR); - - next = elf->e_u.e_ar.e_next; - - /* - * `next' is only set to zero by elf_next() when the last - * member of an archive is processed. - */ - if (next == (off_t) 0) - return (NULL); - - assert((next & 1) == 0); - - arh = (struct ar_hdr *) (elf->e_rawfile + next); - - /* - * Retrieve the size of the member. - */ - if (_libelf_ar_get_number(arh->ar_size, sizeof(arh->ar_size), 10, - &sz) == 0) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); - } - - /* - * Adjust the size field for members in BSD archives using - * extended naming. - */ - if (IS_EXTENDED_BSD_NAME(arh->ar_name)) { - namelen = arh->ar_name + - LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE; - if (_libelf_ar_get_number(namelen, sizeof(arh->ar_name) - - LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE, 10, &nsz) == 0) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); - } - - member = (char *) (arh + 1) + nsz; - sz -= nsz; - } else - member = (char *) (arh + 1); - - - if ((e = elf_memory((char *) member, sz)) == NULL) - return (NULL); - - e->e_fd = fd; - e->e_cmd = c; - e->e_hdr.e_rawhdr = (char *) arh; - - elf->e_u.e_ar.e_nchildren++; - e->e_parent = elf; - - return (e); -} - -/* - * A BSD-style ar(1) symbol table has the following layout: - * - * - A count of bytes used by the following array of 'ranlib' - * structures, stored as a 'long'. - * - An array of 'ranlib' structures. Each array element is - * two 'long's in size. - * - A count of bytes used for the following symbol table. - * - The symbol table itself. - */ - -/* - * A helper macro to read in a 'long' value from the archive. We use - * memcpy() since the source pointer may be misaligned with respect to - * the natural alignment for a C 'long'. - */ -#define GET_LONG(P, V)do { \ - memcpy(&(V), (P), sizeof(long)); \ - (P) += sizeof(long); \ - } while (0) - -Elf_Arsym * -_libelf_ar_process_bsd_symtab(Elf *e, size_t *count) -{ - Elf_Arsym *symtab, *sym; - unsigned char *end, *p, *p0, *s, *s0; - const unsigned int entrysize = 2 * sizeof(long); - long arraysize, fileoffset, n, nentries, stroffset, strtabsize; - - assert(e != NULL); - assert(count != NULL); - assert(e->e_u.e_ar.e_symtab == NULL); - - symtab = NULL; - - /* - * The BSD symbol table always contains the count fields even - * if there are no entries in it. - */ - if (e->e_u.e_ar.e_rawsymtabsz < 2 * sizeof(long)) - goto symtaberror; - - p = p0 = (unsigned char *) e->e_u.e_ar.e_rawsymtab; - end = p0 + e->e_u.e_ar.e_rawsymtabsz; - - /* - * Retrieve the size of the array of ranlib descriptors and - * check it for validity. - */ - GET_LONG(p, arraysize); - - if (p0 + arraysize >= end || (arraysize % entrysize != 0)) - goto symtaberror; - - /* - * Check the value of the string table size. - */ - s = p + arraysize; - GET_LONG(s, strtabsize); - - s0 = s; /* Start of string table. */ - if (s0 + strtabsize > end) - goto symtaberror; - - nentries = arraysize / entrysize; - - /* - * Allocate space for the returned Elf_Arsym array. - */ - if ((symtab = malloc(sizeof(Elf_Arsym) * (nentries + 1))) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - /* Read in symbol table entries. */ - for (n = 0, sym = symtab; n < nentries; n++, sym++) { - GET_LONG(p, stroffset); - GET_LONG(p, fileoffset); - - s = s0 + stroffset; - - if (s >= end) - goto symtaberror; - - sym->as_off = fileoffset; - sym->as_hash = elf_hash((char *) s); - sym->as_name = (char *) s; - } - - /* Fill up the sentinel entry. */ - sym->as_name = NULL; - sym->as_hash = ~0UL; - sym->as_off = (off_t) 0; - - /* Remember the processed symbol table. */ - e->e_u.e_ar.e_symtab = symtab; - - *count = e->e_u.e_ar.e_symtabsz = nentries + 1; - - return (symtab); - -symtaberror: - if (symtab) - free(symtab); - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); -} - -/* - * An SVR4-style ar(1) symbol table has the following layout: - * - * - The first 4 bytes are a binary count of the number of entries in the - * symbol table, stored MSB-first. - * - Then there are 'n' 4-byte binary offsets, also stored MSB first. - * - Following this, there are 'n' null-terminated strings. - */ - -#define GET_WORD(P, V) do { \ - (V) = 0; \ - (V) = (P)[0]; (V) <<= 8; \ - (V) += (P)[1]; (V) <<= 8; \ - (V) += (P)[2]; (V) <<= 8; \ - (V) += (P)[3]; \ - } while (0) - -#define INTSZ 4 - - -Elf_Arsym * -_libelf_ar_process_svr4_symtab(Elf *e, size_t *count) -{ - size_t n, nentries, off; - Elf_Arsym *symtab, *sym; - unsigned char *p, *s, *end; - - assert(e != NULL); - assert(count != NULL); - assert(e->e_u.e_ar.e_symtab == NULL); - - symtab = NULL; - - if (e->e_u.e_ar.e_rawsymtabsz < INTSZ) - goto symtaberror; - - p = (unsigned char *) e->e_u.e_ar.e_rawsymtab; - end = p + e->e_u.e_ar.e_rawsymtabsz; - - GET_WORD(p, nentries); - p += INTSZ; - - if (nentries == 0 || p + nentries * INTSZ >= end) - goto symtaberror; - - /* Allocate space for a nentries + a sentinel. */ - if ((symtab = malloc(sizeof(Elf_Arsym) * (nentries+1))) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - s = p + (nentries * INTSZ); /* start of the string table. */ - - for (n = nentries, sym = symtab; n > 0; n--) { - - if (s >= end) - goto symtaberror; - - off = 0; - - GET_WORD(p, off); - - sym->as_off = off; - sym->as_hash = elf_hash((char *) s); - sym->as_name = (char *) s; - - p += INTSZ; - sym++; - - for (; s < end && *s++ != '\0';) /* skip to next string */ - ; - } - - /* Fill up the sentinel entry. */ - sym->as_name = NULL; - sym->as_hash = ~0UL; - sym->as_off = (off_t) 0; - - *count = e->e_u.e_ar.e_symtabsz = nentries + 1; - e->e_u.e_ar.e_symtab = symtab; - - return (symtab); - -symtaberror: - if (symtab) - free(symtab); - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); -} diff --git a/src/libelf/libelf_ar_util.c b/src/libelf/libelf_ar_util.c deleted file mode 100644 index 958fbbf..0000000 --- a/src/libelf/libelf_ar_util.c +++ /dev/null @@ -1,359 +0,0 @@ -/*- - * Copyright (c) 2006,2009,2010 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include -#include - -#include "_libelf.h" -#include "_libelf_ar.h" - -ELFTC_VCSID("$Id: libelf_ar_util.c 2365 2011-12-29 04:36:44Z jkoshy $"); - -/* - * Convert a string bounded by `start' and `start+sz' (exclusive) to a - * number in the specified base. - */ -int -_libelf_ar_get_number(const char *s, size_t sz, int base, size_t *ret) -{ - int c, v; - size_t r; - const char *e; - - assert(base <= 10); - - e = s + sz; - - /* skip leading blanks */ - for (;s < e && (c = *s) == ' '; s++) - ; - - r = 0L; - for (;s < e; s++) { - if ((c = *s) == ' ') - break; - if (c < '0' || c > '9') - return (0); - v = c - '0'; - if (v >= base) /* Illegal digit. */ - break; - r *= base; - r += v; - } - - *ret = r; - - return (1); -} - -/* - * Return the translated name for an archive member. - */ -char * -_libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar) -{ - char c, *s; - size_t len, offset; - const char *buf, *p, *q, *r; - const size_t bufsize = sizeof(arh->ar_name); - - assert(arh != NULL); - assert(ar->e_kind == ELF_K_AR); - assert((const char *) arh >= ar->e_rawfile && - (const char *) arh < ar->e_rawfile + ar->e_rawsize); - - buf = arh->ar_name; - - /* - * Check for extended naming. - * - * If the name matches the pattern "^/[0-9]+", it is an - * SVR4-style extended name. If the name matches the pattern - * "#1/[0-9]+", the entry uses BSD style extended naming. - */ - if (buf[0] == '/' && (c = buf[1]) >= '0' && c <= '9') { - /* - * The value in field ar_name is a decimal offset into - * the archive string table where the actual name - * resides. - */ - if (_libelf_ar_get_number(buf + 1, bufsize - 1, 10, - &offset) == 0) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); - } - - if (offset > ar->e_u.e_ar.e_rawstrtabsz) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); - } - - p = q = ar->e_u.e_ar.e_rawstrtab + offset; - r = ar->e_u.e_ar.e_rawstrtab + ar->e_u.e_ar.e_rawstrtabsz; - - for (; p < r && *p != '/'; p++) - ; - len = p - q + 1; /* space for the trailing NUL */ - - if ((s = malloc(len)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - (void) strncpy(s, q, len - 1); - s[len - 1] = '\0'; - - return (s); - } else if (IS_EXTENDED_BSD_NAME(buf)) { - r = buf + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE; - - if (_libelf_ar_get_number(r, bufsize - - LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE, 10, - &len) == 0) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); - } - - /* - * Allocate space for the file name plus a - * trailing NUL. - */ - if ((s = malloc(len + 1)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - /* - * The file name follows the archive header. - */ - q = (const char *) (arh + 1); - - (void) strncpy(s, q, len); - s[len] = '\0'; - - return (s); - } - - /* - * A 'normal' name. - * - * Skip back over trailing blanks from the end of the field. - * In the SVR4 format, a '/' is used as a terminator for - * non-special names. - */ - for (q = buf + bufsize - 1; q >= buf && *q == ' '; --q) - ; - - if (q >= buf) { - if (*q == '/') { - /* - * SVR4 style names: ignore the trailing - * character '/', but only if the name is not - * one of the special names "/" and "//". - */ - if (q > buf + 1 || - (q == (buf + 1) && *buf != '/')) - q--; - } - - len = q - buf + 2; /* Add space for a trailing NUL. */ - } else { - /* The buffer only had blanks. */ - buf = ""; - len = 1; - } - - if ((s = malloc(len)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - (void) strncpy(s, buf, len - 1); - s[len - 1] = '\0'; - - return (s); -} - -/* - * Return the raw name for an archive member, inclusive of any - * formatting characters. - */ -char * -_libelf_ar_get_raw_name(const struct ar_hdr *arh) -{ - char *rawname; - const size_t namesz = sizeof(arh->ar_name); - - if ((rawname = malloc(namesz + 1)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - (void) strncpy(rawname, arh->ar_name, namesz); - rawname[namesz] = '\0'; - return (rawname); -} - -/* - * Open an 'ar' archive. - */ -Elf * -_libelf_ar_open(Elf *e, int reporterror) -{ - size_t sz; - int scanahead; - char *s, *end; - struct ar_hdr arh; - - _libelf_init_elf(e, ELF_K_AR); - - e->e_u.e_ar.e_nchildren = 0; - e->e_u.e_ar.e_next = (off_t) -1; - - /* - * Look for special members. - */ - - s = e->e_rawfile + SARMAG; - end = e->e_rawfile + e->e_rawsize; - - assert(e->e_rawsize > 0); - - /* - * We use heuristics to determine the flavor of the archive we - * are examining. - * - * SVR4 flavor archives use the name "/ " and "// " for - * special members. - * - * In BSD flavor archives the symbol table, if present, is the - * first archive with name "__.SYMDEF". - */ - -#define READ_AR_HEADER(S, ARH, SZ, END) \ - do { \ - if ((S) + sizeof((ARH)) > (END)) \ - goto error; \ - (void) memcpy(&(ARH), (S), sizeof((ARH))); \ - if ((ARH).ar_fmag[0] != '`' || (ARH).ar_fmag[1] != '\n') \ - goto error; \ - if (_libelf_ar_get_number((ARH).ar_size, \ - sizeof((ARH).ar_size), 10, &(SZ)) == 0) \ - goto error; \ - } while (0) - - READ_AR_HEADER(s, arh, sz, end); - - /* - * Handle special archive members for the SVR4 format. - */ - if (arh.ar_name[0] == '/') { - - assert(sz > 0); - - e->e_flags |= LIBELF_F_AR_VARIANT_SVR4; - - scanahead = 0; - - /* - * The symbol table (file name "/ ") always comes before the - * string table (file name "// "). - */ - if (arh.ar_name[1] == ' ') { - /* "/ " => symbol table. */ - scanahead = 1; /* The string table to follow. */ - - s += sizeof(arh); - e->e_u.e_ar.e_rawsymtab = s; - e->e_u.e_ar.e_rawsymtabsz = sz; - - sz = LIBELF_ADJUST_AR_SIZE(sz); - s += sz; - - } else if (arh.ar_name[1] == '/' && arh.ar_name[2] == ' ') { - /* "// " => string table for long file names. */ - s += sizeof(arh); - e->e_u.e_ar.e_rawstrtab = s; - e->e_u.e_ar.e_rawstrtabsz = sz; - - sz = LIBELF_ADJUST_AR_SIZE(sz); - s += sz; - } - - /* - * If the string table hasn't been seen yet, look for - * it in the next member. - */ - if (scanahead) { - READ_AR_HEADER(s, arh, sz, end); - - /* "// " => string table for long file names. */ - if (arh.ar_name[0] == '/' && arh.ar_name[1] == '/' && - arh.ar_name[2] == ' ') { - - s += sizeof(arh); - - e->e_u.e_ar.e_rawstrtab = s; - e->e_u.e_ar.e_rawstrtabsz = sz; - - sz = LIBELF_ADJUST_AR_SIZE(sz); - s += sz; - } - } - } else if (strncmp(arh.ar_name, LIBELF_AR_BSD_SYMTAB_NAME, - sizeof(LIBELF_AR_BSD_SYMTAB_NAME) - 1) == 0) { - /* - * BSD style archive symbol table. - */ - s += sizeof(arh); - e->e_u.e_ar.e_rawsymtab = s; - e->e_u.e_ar.e_rawsymtabsz = sz; - - sz = LIBELF_ADJUST_AR_SIZE(sz); - s += sz; - } - - /* - * Update the 'next' offset, so that a subsequent elf_begin() - * works as expected. - */ - e->e_u.e_ar.e_next = (off_t) (s - e->e_rawfile); - - return (e); - -error: - if (!reporterror) { - e->e_kind = ELF_K_NONE; - return (e); - } - - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); -} diff --git a/src/libelf/libelf_checksum.c b/src/libelf/libelf_checksum.c deleted file mode 100644 index a92578c..0000000 --- a/src/libelf/libelf_checksum.c +++ /dev/null @@ -1,100 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include "gelf.h" - -#include "_libelf.h" - -ELFTC_VCSID("$Id: libelf_checksum.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -static unsigned long -_libelf_sum(unsigned long c, const unsigned char *s, size_t size) -{ - if (s == NULL || size == 0) - return (c); - - while (size--) - c += *s++; - - return (c); -} - -unsigned long -_libelf_checksum(Elf *e, int elfclass) -{ - size_t shn; - Elf_Scn *scn; - Elf_Data *d; - unsigned long checksum; - GElf_Ehdr eh; - GElf_Shdr shdr; - - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0L); - } - - if (e->e_class != elfclass) { - LIBELF_SET_ERROR(CLASS, 0); - return (0L); - } - - if (gelf_getehdr(e, &eh) == NULL) - return (0); - - /* - * Iterate over all sections in the ELF file, computing the - * checksum along the way. - * - * The first section is always SHN_UNDEF and can be skipped. - * Non-allocatable sections are skipped, as are sections that - * could be affected by utilities such as strip(1). - */ - - checksum = 0; - for (shn = 1; shn < e->e_u.e_elf.e_nscn; shn++) { - if ((scn = elf_getscn(e, shn)) == NULL) - return (0); - if (gelf_getshdr(scn, &shdr) == NULL) - return (0); - if ((shdr.sh_flags & SHF_ALLOC) == 0 || - shdr.sh_type == SHT_DYNAMIC || - shdr.sh_type == SHT_DYNSYM) - continue; - - d = NULL; - while ((d = elf_rawdata(scn, d)) != NULL) - checksum = _libelf_sum(checksum, - (unsigned char *) d->d_buf, d->d_size); - } - - /* - * Return a 16-bit checksum compatible with Solaris. - */ - return (((checksum >> 16) & 0xFFFFUL) + (checksum & 0xFFFFUL)); -} diff --git a/src/libelf/libelf_convert.c b/src/libelf/libelf_convert.c deleted file mode 100644 index e51c63d..0000000 --- a/src/libelf/libelf_convert.c +++ /dev/null @@ -1,3465 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: elf_types.m4 321 2009-03-07 16:59:14Z jkoshy $ - */ - -/* - * ELF types, defined in the "enum Elf_Type" API. - * - * The members of the list form a 2-tuple: (name, C-type-suffix). - * + name is an Elf_Type symbol without the ELF_T_ prefix. - * + C-type-suffix is the suffix for Elf32_ and Elf64_ type names. - */ - - - -/* - * DEFINE_STRUCT(NAME,MEMBERLIST...) - * - * Map a type name to its members. - * - * Each member-list element comprises of pairs of (field name, type), - * in the sequence used in the file representation of NAME. - * - * Each member list element comprises a pair containing a field name - * and a basic type. Basic types include IDENT, HALF, WORD, LWORD, - * ADDR{32,64}, OFF{32,64}, SWORD, XWORD, SXWORD. - * - * The last element of a member list is the null element: _,_. - */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -/*- - * Copyright (c) 2006-2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: libelf_convert.m4 2361 2011-12-28 12:03:05Z jkoshy $"); - -/* WARNING: GENERATED FROM libelf_convert.m4. */ - - - -/* - * C macros to byte swap integral quantities. - */ - -#define SWAP_BYTE(X) do { (void) (X); } while (0) -#define SWAP_IDENT(X) do { (void) (X); } while (0) -#define SWAP_HALF(X) do { \ - uint16_t _x = (uint16_t) (X); \ - uint16_t _t = _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - (X) = _t; \ - } while (0) -#define SWAP_WORD(X) do { \ - uint32_t _x = (uint32_t) (X); \ - uint32_t _t = _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - (X) = _t; \ - } while (0) -#define SWAP_ADDR32(X) SWAP_WORD(X) -#define SWAP_OFF32(X) SWAP_WORD(X) -#define SWAP_SWORD(X) SWAP_WORD(X) -#define SWAP_WORD64(X) do { \ - uint64_t _x = (uint64_t) (X); \ - uint64_t _t = _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - (X) = _t; \ - } while (0) -#define SWAP_ADDR64(X) SWAP_WORD64(X) -#define SWAP_LWORD(X) SWAP_WORD64(X) -#define SWAP_OFF64(X) SWAP_WORD64(X) -#define SWAP_SXWORD(X) SWAP_WORD64(X) -#define SWAP_XWORD(X) SWAP_WORD64(X) - -/* - * C macros to write out various integral values. - * - * Note: - * - The destination pointer could be unaligned. - * - Values are written out in native byte order. - * - The destination pointer is incremented after the write. - */ -#define WRITE_BYTE(P,X) do { \ - char *const _p = (char *) (P); \ - _p[0] = (char) (X); \ - (P) = _p + 1; \ - } while (0) -#define WRITE_HALF(P,X) do { \ - uint16_t _t = (X); \ - char *const _p = (char *) (P); \ - const char *const _q = (char *) &_t; \ - _p[0] = _q[0]; \ - _p[1] = _q[1]; \ - (P) = _p + 2; \ - } while (0) -#define WRITE_WORD(P,X) do { \ - uint32_t _t = (X); \ - char *const _p = (char *) (P); \ - const char *const _q = (char *) &_t; \ - _p[0] = _q[0]; \ - _p[1] = _q[1]; \ - _p[2] = _q[2]; \ - _p[3] = _q[3]; \ - (P) = _p + 4; \ - } while (0) -#define WRITE_ADDR32(P,X) WRITE_WORD(P,X) -#define WRITE_OFF32(P,X) WRITE_WORD(P,X) -#define WRITE_SWORD(P,X) WRITE_WORD(P,X) -#define WRITE_WORD64(P,X) do { \ - uint64_t _t = (X); \ - char *const _p = (char *) (P); \ - const char *const _q = (char *) &_t; \ - _p[0] = _q[0]; \ - _p[1] = _q[1]; \ - _p[2] = _q[2]; \ - _p[3] = _q[3]; \ - _p[4] = _q[4]; \ - _p[5] = _q[5]; \ - _p[6] = _q[6]; \ - _p[7] = _q[7]; \ - (P) = _p + 8; \ - } while (0) -#define WRITE_ADDR64(P,X) WRITE_WORD64(P,X) -#define WRITE_LWORD(P,X) WRITE_WORD64(P,X) -#define WRITE_OFF64(P,X) WRITE_WORD64(P,X) -#define WRITE_SXWORD(P,X) WRITE_WORD64(P,X) -#define WRITE_XWORD(P,X) WRITE_WORD64(P,X) -#define WRITE_IDENT(P,X) do { \ - (void) memcpy((P), (X), sizeof((X))); \ - (P) = (P) + EI_NIDENT; \ - } while (0) - -/* - * C macros to read in various integral values. - * - * Note: - * - The source pointer could be unaligned. - * - Values are read in native byte order. - * - The source pointer is incremented appropriately. - */ - -#define READ_BYTE(P,X) do { \ - const char *const _p = \ - (const char *) (P); \ - (X) = _p[0]; \ - (P) = (P) + 1; \ - } while (0) -#define READ_HALF(P,X) do { \ - uint16_t _t; \ - char *const _q = (char *) &_t; \ - const char *const _p = \ - (const char *) (P); \ - _q[0] = _p[0]; \ - _q[1] = _p[1]; \ - (P) = (P) + 2; \ - (X) = _t; \ - } while (0) -#define READ_WORD(P,X) do { \ - uint32_t _t; \ - char *const _q = (char *) &_t; \ - const char *const _p = \ - (const char *) (P); \ - _q[0] = _p[0]; \ - _q[1] = _p[1]; \ - _q[2] = _p[2]; \ - _q[3] = _p[3]; \ - (P) = (P) + 4; \ - (X) = _t; \ - } while (0) -#define READ_ADDR32(P,X) READ_WORD(P,X) -#define READ_OFF32(P,X) READ_WORD(P,X) -#define READ_SWORD(P,X) READ_WORD(P,X) -#define READ_WORD64(P,X) do { \ - uint64_t _t; \ - char *const _q = (char *) &_t; \ - const char *const _p = \ - (const char *) (P); \ - _q[0] = _p[0]; \ - _q[1] = _p[1]; \ - _q[2] = _p[2]; \ - _q[3] = _p[3]; \ - _q[4] = _p[4]; \ - _q[5] = _p[5]; \ - _q[6] = _p[6]; \ - _q[7] = _p[7]; \ - (P) = (P) + 8; \ - (X) = _t; \ - } while (0) -#define READ_ADDR64(P,X) READ_WORD64(P,X) -#define READ_LWORD(P,X) READ_WORD64(P,X) -#define READ_OFF64(P,X) READ_WORD64(P,X) -#define READ_SXWORD(P,X) READ_WORD64(P,X) -#define READ_XWORD(P,X) READ_WORD64(P,X) -#define READ_IDENT(P,X) do { \ - (void) memcpy((X), (P), sizeof((X))); \ - (P) = (P) + EI_NIDENT; \ - } while (0) - -#define ROUNDUP2(V,N) (V) = ((((V) + (N) - 1)) & ~((N) - 1)) - -/*[*/ - -static int -_libelf_cvt_ADDR32_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Addr t, *s = (Elf32_Addr *) (uintptr_t) src; - size_t c; - - (void) dsz; - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*s)); - return (1); - } - - for (c = 0; c < count; c++) { - t = *s++; - SWAP_ADDR32(t); - WRITE_ADDR32(dst,t); - } - - return (1); -} - -static int -_libelf_cvt_ADDR32_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Addr t, *d = (Elf32_Addr *) (uintptr_t) dst; - size_t c; - - if (dsz < count * sizeof(Elf32_Addr)) - return (0); - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*d)); - return (1); - } - - for (c = 0; c < count; c++) { - READ_ADDR32(src,t); - SWAP_ADDR32(t); - *d++ = t; - } - - return (1); -} - -static int -_libelf_cvt_ADDR64_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Addr t, *s = (Elf64_Addr *) (uintptr_t) src; - size_t c; - - (void) dsz; - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*s)); - return (1); - } - - for (c = 0; c < count; c++) { - t = *s++; - SWAP_ADDR64(t); - WRITE_ADDR64(dst,t); - } - - return (1); -} - -static int -_libelf_cvt_ADDR64_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Addr t, *d = (Elf64_Addr *) (uintptr_t) dst; - size_t c; - - if (dsz < count * sizeof(Elf64_Addr)) - return (0); - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*d)); - return (1); - } - - for (c = 0; c < count; c++) { - READ_ADDR64(src,t); - SWAP_ADDR64(t); - *d++ = t; - } - - return (1); -} - -static int -_libelf_cvt_CAP32_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Cap t, *s; - size_t c; - - (void) dsz; - - s = (Elf32_Cap *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf32_Cap */ - SWAP_WORD(t.c_tag); - SWAP_WORD(t.c_un.c_val); - /**/ - } - /* Write an Elf32_Cap */ - WRITE_WORD(dst,t.c_tag); - WRITE_WORD(dst,t.c_un.c_val); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_CAP32_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Cap t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf32_fsize(ELF_T_CAP, (size_t) 1, EV_CURRENT); - d = ((Elf32_Cap *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf32_Cap)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf32_Cap */ - READ_WORD(s,t.c_tag); - READ_WORD(s,t.c_un.c_val); - /**/ - if (byteswap) { - /* Swap an Elf32_Cap */ - SWAP_WORD(t.c_tag); - SWAP_WORD(t.c_un.c_val); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_CAP64_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Cap t, *s; - size_t c; - - (void) dsz; - - s = (Elf64_Cap *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf64_Cap */ - SWAP_XWORD(t.c_tag); - SWAP_XWORD(t.c_un.c_val); - /**/ - } - /* Write an Elf64_Cap */ - WRITE_XWORD(dst,t.c_tag); - WRITE_XWORD(dst,t.c_un.c_val); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_CAP64_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Cap t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf64_fsize(ELF_T_CAP, (size_t) 1, EV_CURRENT); - d = ((Elf64_Cap *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf64_Cap)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf64_Cap */ - READ_XWORD(s,t.c_tag); - READ_XWORD(s,t.c_un.c_val); - /**/ - if (byteswap) { - /* Swap an Elf64_Cap */ - SWAP_XWORD(t.c_tag); - SWAP_XWORD(t.c_un.c_val); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_DYN32_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Dyn t, *s; - size_t c; - - (void) dsz; - - s = (Elf32_Dyn *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf32_Dyn */ - SWAP_SWORD(t.d_tag); - SWAP_WORD(t.d_un.d_ptr); - /**/ - } - /* Write an Elf32_Dyn */ - WRITE_SWORD(dst,t.d_tag); - WRITE_WORD(dst,t.d_un.d_ptr); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_DYN32_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Dyn t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf32_fsize(ELF_T_DYN, (size_t) 1, EV_CURRENT); - d = ((Elf32_Dyn *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf32_Dyn)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf32_Dyn */ - READ_SWORD(s,t.d_tag); - READ_WORD(s,t.d_un.d_ptr); - /**/ - if (byteswap) { - /* Swap an Elf32_Dyn */ - SWAP_SWORD(t.d_tag); - SWAP_WORD(t.d_un.d_ptr); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_DYN64_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Dyn t, *s; - size_t c; - - (void) dsz; - - s = (Elf64_Dyn *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf64_Dyn */ - SWAP_SXWORD(t.d_tag); - SWAP_XWORD(t.d_un.d_ptr); - /**/ - } - /* Write an Elf64_Dyn */ - WRITE_SXWORD(dst,t.d_tag); - WRITE_XWORD(dst,t.d_un.d_ptr); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_DYN64_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Dyn t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf64_fsize(ELF_T_DYN, (size_t) 1, EV_CURRENT); - d = ((Elf64_Dyn *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf64_Dyn)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf64_Dyn */ - READ_SXWORD(s,t.d_tag); - READ_XWORD(s,t.d_un.d_ptr); - /**/ - if (byteswap) { - /* Swap an Elf64_Dyn */ - SWAP_SXWORD(t.d_tag); - SWAP_XWORD(t.d_un.d_ptr); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_EHDR32_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Ehdr t, *s; - size_t c; - - (void) dsz; - - s = (Elf32_Ehdr *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf32_Ehdr */ - SWAP_IDENT(t.e_ident); - SWAP_HALF(t.e_type); - SWAP_HALF(t.e_machine); - SWAP_WORD(t.e_version); - SWAP_ADDR32(t.e_entry); - SWAP_OFF32(t.e_phoff); - SWAP_OFF32(t.e_shoff); - SWAP_WORD(t.e_flags); - SWAP_HALF(t.e_ehsize); - SWAP_HALF(t.e_phentsize); - SWAP_HALF(t.e_phnum); - SWAP_HALF(t.e_shentsize); - SWAP_HALF(t.e_shnum); - SWAP_HALF(t.e_shstrndx); - /**/ - } - /* Write an Elf32_Ehdr */ - WRITE_IDENT(dst,t.e_ident); - WRITE_HALF(dst,t.e_type); - WRITE_HALF(dst,t.e_machine); - WRITE_WORD(dst,t.e_version); - WRITE_ADDR32(dst,t.e_entry); - WRITE_OFF32(dst,t.e_phoff); - WRITE_OFF32(dst,t.e_shoff); - WRITE_WORD(dst,t.e_flags); - WRITE_HALF(dst,t.e_ehsize); - WRITE_HALF(dst,t.e_phentsize); - WRITE_HALF(dst,t.e_phnum); - WRITE_HALF(dst,t.e_shentsize); - WRITE_HALF(dst,t.e_shnum); - WRITE_HALF(dst,t.e_shstrndx); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_EHDR32_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Ehdr t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf32_fsize(ELF_T_EHDR, (size_t) 1, EV_CURRENT); - d = ((Elf32_Ehdr *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf32_Ehdr)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf32_Ehdr */ - READ_IDENT(s,t.e_ident); - READ_HALF(s,t.e_type); - READ_HALF(s,t.e_machine); - READ_WORD(s,t.e_version); - READ_ADDR32(s,t.e_entry); - READ_OFF32(s,t.e_phoff); - READ_OFF32(s,t.e_shoff); - READ_WORD(s,t.e_flags); - READ_HALF(s,t.e_ehsize); - READ_HALF(s,t.e_phentsize); - READ_HALF(s,t.e_phnum); - READ_HALF(s,t.e_shentsize); - READ_HALF(s,t.e_shnum); - READ_HALF(s,t.e_shstrndx); - /**/ - if (byteswap) { - /* Swap an Elf32_Ehdr */ - SWAP_IDENT(t.e_ident); - SWAP_HALF(t.e_type); - SWAP_HALF(t.e_machine); - SWAP_WORD(t.e_version); - SWAP_ADDR32(t.e_entry); - SWAP_OFF32(t.e_phoff); - SWAP_OFF32(t.e_shoff); - SWAP_WORD(t.e_flags); - SWAP_HALF(t.e_ehsize); - SWAP_HALF(t.e_phentsize); - SWAP_HALF(t.e_phnum); - SWAP_HALF(t.e_shentsize); - SWAP_HALF(t.e_shnum); - SWAP_HALF(t.e_shstrndx); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_EHDR64_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Ehdr t, *s; - size_t c; - - (void) dsz; - - s = (Elf64_Ehdr *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf64_Ehdr */ - SWAP_IDENT(t.e_ident); - SWAP_HALF(t.e_type); - SWAP_HALF(t.e_machine); - SWAP_WORD(t.e_version); - SWAP_ADDR64(t.e_entry); - SWAP_OFF64(t.e_phoff); - SWAP_OFF64(t.e_shoff); - SWAP_WORD(t.e_flags); - SWAP_HALF(t.e_ehsize); - SWAP_HALF(t.e_phentsize); - SWAP_HALF(t.e_phnum); - SWAP_HALF(t.e_shentsize); - SWAP_HALF(t.e_shnum); - SWAP_HALF(t.e_shstrndx); - /**/ - } - /* Write an Elf64_Ehdr */ - WRITE_IDENT(dst,t.e_ident); - WRITE_HALF(dst,t.e_type); - WRITE_HALF(dst,t.e_machine); - WRITE_WORD(dst,t.e_version); - WRITE_ADDR64(dst,t.e_entry); - WRITE_OFF64(dst,t.e_phoff); - WRITE_OFF64(dst,t.e_shoff); - WRITE_WORD(dst,t.e_flags); - WRITE_HALF(dst,t.e_ehsize); - WRITE_HALF(dst,t.e_phentsize); - WRITE_HALF(dst,t.e_phnum); - WRITE_HALF(dst,t.e_shentsize); - WRITE_HALF(dst,t.e_shnum); - WRITE_HALF(dst,t.e_shstrndx); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_EHDR64_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Ehdr t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf64_fsize(ELF_T_EHDR, (size_t) 1, EV_CURRENT); - d = ((Elf64_Ehdr *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf64_Ehdr)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf64_Ehdr */ - READ_IDENT(s,t.e_ident); - READ_HALF(s,t.e_type); - READ_HALF(s,t.e_machine); - READ_WORD(s,t.e_version); - READ_ADDR64(s,t.e_entry); - READ_OFF64(s,t.e_phoff); - READ_OFF64(s,t.e_shoff); - READ_WORD(s,t.e_flags); - READ_HALF(s,t.e_ehsize); - READ_HALF(s,t.e_phentsize); - READ_HALF(s,t.e_phnum); - READ_HALF(s,t.e_shentsize); - READ_HALF(s,t.e_shnum); - READ_HALF(s,t.e_shstrndx); - /**/ - if (byteswap) { - /* Swap an Elf64_Ehdr */ - SWAP_IDENT(t.e_ident); - SWAP_HALF(t.e_type); - SWAP_HALF(t.e_machine); - SWAP_WORD(t.e_version); - SWAP_ADDR64(t.e_entry); - SWAP_OFF64(t.e_phoff); - SWAP_OFF64(t.e_shoff); - SWAP_WORD(t.e_flags); - SWAP_HALF(t.e_ehsize); - SWAP_HALF(t.e_phentsize); - SWAP_HALF(t.e_phnum); - SWAP_HALF(t.e_shentsize); - SWAP_HALF(t.e_shnum); - SWAP_HALF(t.e_shstrndx); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_HALF_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Half t, *s = (Elf64_Half *) (uintptr_t) src; - size_t c; - - (void) dsz; - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*s)); - return (1); - } - - for (c = 0; c < count; c++) { - t = *s++; - SWAP_HALF(t); - WRITE_HALF(dst,t); - } - - return (1); -} - -static int -_libelf_cvt_HALF_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Half t, *d = (Elf64_Half *) (uintptr_t) dst; - size_t c; - - if (dsz < count * sizeof(Elf64_Half)) - return (0); - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*d)); - return (1); - } - - for (c = 0; c < count; c++) { - READ_HALF(src,t); - SWAP_HALF(t); - *d++ = t; - } - - return (1); -} - -static int -_libelf_cvt_LWORD_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Lword t, *s = (Elf64_Lword *) (uintptr_t) src; - size_t c; - - (void) dsz; - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*s)); - return (1); - } - - for (c = 0; c < count; c++) { - t = *s++; - SWAP_LWORD(t); - WRITE_LWORD(dst,t); - } - - return (1); -} - -static int -_libelf_cvt_LWORD_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Lword t, *d = (Elf64_Lword *) (uintptr_t) dst; - size_t c; - - if (dsz < count * sizeof(Elf64_Lword)) - return (0); - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*d)); - return (1); - } - - for (c = 0; c < count; c++) { - READ_LWORD(src,t); - SWAP_LWORD(t); - *d++ = t; - } - - return (1); -} - -static int -_libelf_cvt_MOVE32_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Move t, *s; - size_t c; - - (void) dsz; - - s = (Elf32_Move *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf32_Move */ - SWAP_LWORD(t.m_value); - SWAP_WORD(t.m_info); - SWAP_WORD(t.m_poffset); - SWAP_HALF(t.m_repeat); - SWAP_HALF(t.m_stride); - /**/ - } - /* Write an Elf32_Move */ - WRITE_LWORD(dst,t.m_value); - WRITE_WORD(dst,t.m_info); - WRITE_WORD(dst,t.m_poffset); - WRITE_HALF(dst,t.m_repeat); - WRITE_HALF(dst,t.m_stride); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_MOVE32_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Move t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf32_fsize(ELF_T_MOVE, (size_t) 1, EV_CURRENT); - d = ((Elf32_Move *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf32_Move)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf32_Move */ - READ_LWORD(s,t.m_value); - READ_WORD(s,t.m_info); - READ_WORD(s,t.m_poffset); - READ_HALF(s,t.m_repeat); - READ_HALF(s,t.m_stride); - /**/ - if (byteswap) { - /* Swap an Elf32_Move */ - SWAP_LWORD(t.m_value); - SWAP_WORD(t.m_info); - SWAP_WORD(t.m_poffset); - SWAP_HALF(t.m_repeat); - SWAP_HALF(t.m_stride); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_MOVE64_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Move t, *s; - size_t c; - - (void) dsz; - - s = (Elf64_Move *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf64_Move */ - SWAP_LWORD(t.m_value); - SWAP_XWORD(t.m_info); - SWAP_XWORD(t.m_poffset); - SWAP_HALF(t.m_repeat); - SWAP_HALF(t.m_stride); - /**/ - } - /* Write an Elf64_Move */ - WRITE_LWORD(dst,t.m_value); - WRITE_XWORD(dst,t.m_info); - WRITE_XWORD(dst,t.m_poffset); - WRITE_HALF(dst,t.m_repeat); - WRITE_HALF(dst,t.m_stride); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_MOVE64_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Move t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf64_fsize(ELF_T_MOVE, (size_t) 1, EV_CURRENT); - d = ((Elf64_Move *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf64_Move)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf64_Move */ - READ_LWORD(s,t.m_value); - READ_XWORD(s,t.m_info); - READ_XWORD(s,t.m_poffset); - READ_HALF(s,t.m_repeat); - READ_HALF(s,t.m_stride); - /**/ - if (byteswap) { - /* Swap an Elf64_Move */ - SWAP_LWORD(t.m_value); - SWAP_XWORD(t.m_info); - SWAP_XWORD(t.m_poffset); - SWAP_HALF(t.m_repeat); - SWAP_HALF(t.m_stride); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_OFF32_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Off t, *s = (Elf32_Off *) (uintptr_t) src; - size_t c; - - (void) dsz; - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*s)); - return (1); - } - - for (c = 0; c < count; c++) { - t = *s++; - SWAP_OFF32(t); - WRITE_OFF32(dst,t); - } - - return (1); -} - -static int -_libelf_cvt_OFF32_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Off t, *d = (Elf32_Off *) (uintptr_t) dst; - size_t c; - - if (dsz < count * sizeof(Elf32_Off)) - return (0); - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*d)); - return (1); - } - - for (c = 0; c < count; c++) { - READ_OFF32(src,t); - SWAP_OFF32(t); - *d++ = t; - } - - return (1); -} - -static int -_libelf_cvt_OFF64_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Off t, *s = (Elf64_Off *) (uintptr_t) src; - size_t c; - - (void) dsz; - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*s)); - return (1); - } - - for (c = 0; c < count; c++) { - t = *s++; - SWAP_OFF64(t); - WRITE_OFF64(dst,t); - } - - return (1); -} - -static int -_libelf_cvt_OFF64_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Off t, *d = (Elf64_Off *) (uintptr_t) dst; - size_t c; - - if (dsz < count * sizeof(Elf64_Off)) - return (0); - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*d)); - return (1); - } - - for (c = 0; c < count; c++) { - READ_OFF64(src,t); - SWAP_OFF64(t); - *d++ = t; - } - - return (1); -} - -static int -_libelf_cvt_PHDR32_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Phdr t, *s; - size_t c; - - (void) dsz; - - s = (Elf32_Phdr *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf32_Phdr */ - SWAP_WORD(t.p_type); - SWAP_OFF32(t.p_offset); - SWAP_ADDR32(t.p_vaddr); - SWAP_ADDR32(t.p_paddr); - SWAP_WORD(t.p_filesz); - SWAP_WORD(t.p_memsz); - SWAP_WORD(t.p_flags); - SWAP_WORD(t.p_align); - /**/ - } - /* Write an Elf32_Phdr */ - WRITE_WORD(dst,t.p_type); - WRITE_OFF32(dst,t.p_offset); - WRITE_ADDR32(dst,t.p_vaddr); - WRITE_ADDR32(dst,t.p_paddr); - WRITE_WORD(dst,t.p_filesz); - WRITE_WORD(dst,t.p_memsz); - WRITE_WORD(dst,t.p_flags); - WRITE_WORD(dst,t.p_align); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_PHDR32_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Phdr t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf32_fsize(ELF_T_PHDR, (size_t) 1, EV_CURRENT); - d = ((Elf32_Phdr *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf32_Phdr)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf32_Phdr */ - READ_WORD(s,t.p_type); - READ_OFF32(s,t.p_offset); - READ_ADDR32(s,t.p_vaddr); - READ_ADDR32(s,t.p_paddr); - READ_WORD(s,t.p_filesz); - READ_WORD(s,t.p_memsz); - READ_WORD(s,t.p_flags); - READ_WORD(s,t.p_align); - /**/ - if (byteswap) { - /* Swap an Elf32_Phdr */ - SWAP_WORD(t.p_type); - SWAP_OFF32(t.p_offset); - SWAP_ADDR32(t.p_vaddr); - SWAP_ADDR32(t.p_paddr); - SWAP_WORD(t.p_filesz); - SWAP_WORD(t.p_memsz); - SWAP_WORD(t.p_flags); - SWAP_WORD(t.p_align); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_PHDR64_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Phdr t, *s; - size_t c; - - (void) dsz; - - s = (Elf64_Phdr *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf64_Phdr */ - SWAP_WORD(t.p_type); - SWAP_WORD(t.p_flags); - SWAP_OFF64(t.p_offset); - SWAP_ADDR64(t.p_vaddr); - SWAP_ADDR64(t.p_paddr); - SWAP_XWORD(t.p_filesz); - SWAP_XWORD(t.p_memsz); - SWAP_XWORD(t.p_align); - /**/ - } - /* Write an Elf64_Phdr */ - WRITE_WORD(dst,t.p_type); - WRITE_WORD(dst,t.p_flags); - WRITE_OFF64(dst,t.p_offset); - WRITE_ADDR64(dst,t.p_vaddr); - WRITE_ADDR64(dst,t.p_paddr); - WRITE_XWORD(dst,t.p_filesz); - WRITE_XWORD(dst,t.p_memsz); - WRITE_XWORD(dst,t.p_align); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_PHDR64_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Phdr t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf64_fsize(ELF_T_PHDR, (size_t) 1, EV_CURRENT); - d = ((Elf64_Phdr *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf64_Phdr)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf64_Phdr */ - READ_WORD(s,t.p_type); - READ_WORD(s,t.p_flags); - READ_OFF64(s,t.p_offset); - READ_ADDR64(s,t.p_vaddr); - READ_ADDR64(s,t.p_paddr); - READ_XWORD(s,t.p_filesz); - READ_XWORD(s,t.p_memsz); - READ_XWORD(s,t.p_align); - /**/ - if (byteswap) { - /* Swap an Elf64_Phdr */ - SWAP_WORD(t.p_type); - SWAP_WORD(t.p_flags); - SWAP_OFF64(t.p_offset); - SWAP_ADDR64(t.p_vaddr); - SWAP_ADDR64(t.p_paddr); - SWAP_XWORD(t.p_filesz); - SWAP_XWORD(t.p_memsz); - SWAP_XWORD(t.p_align); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_REL32_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Rel t, *s; - size_t c; - - (void) dsz; - - s = (Elf32_Rel *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf32_Rel */ - SWAP_ADDR32(t.r_offset); - SWAP_WORD(t.r_info); - /**/ - } - /* Write an Elf32_Rel */ - WRITE_ADDR32(dst,t.r_offset); - WRITE_WORD(dst,t.r_info); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_REL32_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Rel t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf32_fsize(ELF_T_REL, (size_t) 1, EV_CURRENT); - d = ((Elf32_Rel *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf32_Rel)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf32_Rel */ - READ_ADDR32(s,t.r_offset); - READ_WORD(s,t.r_info); - /**/ - if (byteswap) { - /* Swap an Elf32_Rel */ - SWAP_ADDR32(t.r_offset); - SWAP_WORD(t.r_info); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_REL64_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Rel t, *s; - size_t c; - - (void) dsz; - - s = (Elf64_Rel *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf64_Rel */ - SWAP_ADDR64(t.r_offset); - SWAP_XWORD(t.r_info); - /**/ - } - /* Write an Elf64_Rel */ - WRITE_ADDR64(dst,t.r_offset); - WRITE_XWORD(dst,t.r_info); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_REL64_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Rel t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf64_fsize(ELF_T_REL, (size_t) 1, EV_CURRENT); - d = ((Elf64_Rel *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf64_Rel)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf64_Rel */ - READ_ADDR64(s,t.r_offset); - READ_XWORD(s,t.r_info); - /**/ - if (byteswap) { - /* Swap an Elf64_Rel */ - SWAP_ADDR64(t.r_offset); - SWAP_XWORD(t.r_info); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_RELA32_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Rela t, *s; - size_t c; - - (void) dsz; - - s = (Elf32_Rela *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf32_Rela */ - SWAP_ADDR32(t.r_offset); - SWAP_WORD(t.r_info); - SWAP_SWORD(t.r_addend); - /**/ - } - /* Write an Elf32_Rela */ - WRITE_ADDR32(dst,t.r_offset); - WRITE_WORD(dst,t.r_info); - WRITE_SWORD(dst,t.r_addend); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_RELA32_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Rela t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf32_fsize(ELF_T_RELA, (size_t) 1, EV_CURRENT); - d = ((Elf32_Rela *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf32_Rela)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf32_Rela */ - READ_ADDR32(s,t.r_offset); - READ_WORD(s,t.r_info); - READ_SWORD(s,t.r_addend); - /**/ - if (byteswap) { - /* Swap an Elf32_Rela */ - SWAP_ADDR32(t.r_offset); - SWAP_WORD(t.r_info); - SWAP_SWORD(t.r_addend); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_RELA64_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Rela t, *s; - size_t c; - - (void) dsz; - - s = (Elf64_Rela *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf64_Rela */ - SWAP_ADDR64(t.r_offset); - SWAP_XWORD(t.r_info); - SWAP_SXWORD(t.r_addend); - /**/ - } - /* Write an Elf64_Rela */ - WRITE_ADDR64(dst,t.r_offset); - WRITE_XWORD(dst,t.r_info); - WRITE_SXWORD(dst,t.r_addend); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_RELA64_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Rela t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf64_fsize(ELF_T_RELA, (size_t) 1, EV_CURRENT); - d = ((Elf64_Rela *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf64_Rela)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf64_Rela */ - READ_ADDR64(s,t.r_offset); - READ_XWORD(s,t.r_info); - READ_SXWORD(s,t.r_addend); - /**/ - if (byteswap) { - /* Swap an Elf64_Rela */ - SWAP_ADDR64(t.r_offset); - SWAP_XWORD(t.r_info); - SWAP_SXWORD(t.r_addend); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_SHDR32_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Shdr t, *s; - size_t c; - - (void) dsz; - - s = (Elf32_Shdr *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf32_Shdr */ - SWAP_WORD(t.sh_name); - SWAP_WORD(t.sh_type); - SWAP_WORD(t.sh_flags); - SWAP_ADDR32(t.sh_addr); - SWAP_OFF32(t.sh_offset); - SWAP_WORD(t.sh_size); - SWAP_WORD(t.sh_link); - SWAP_WORD(t.sh_info); - SWAP_WORD(t.sh_addralign); - SWAP_WORD(t.sh_entsize); - /**/ - } - /* Write an Elf32_Shdr */ - WRITE_WORD(dst,t.sh_name); - WRITE_WORD(dst,t.sh_type); - WRITE_WORD(dst,t.sh_flags); - WRITE_ADDR32(dst,t.sh_addr); - WRITE_OFF32(dst,t.sh_offset); - WRITE_WORD(dst,t.sh_size); - WRITE_WORD(dst,t.sh_link); - WRITE_WORD(dst,t.sh_info); - WRITE_WORD(dst,t.sh_addralign); - WRITE_WORD(dst,t.sh_entsize); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_SHDR32_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Shdr t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf32_fsize(ELF_T_SHDR, (size_t) 1, EV_CURRENT); - d = ((Elf32_Shdr *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf32_Shdr)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf32_Shdr */ - READ_WORD(s,t.sh_name); - READ_WORD(s,t.sh_type); - READ_WORD(s,t.sh_flags); - READ_ADDR32(s,t.sh_addr); - READ_OFF32(s,t.sh_offset); - READ_WORD(s,t.sh_size); - READ_WORD(s,t.sh_link); - READ_WORD(s,t.sh_info); - READ_WORD(s,t.sh_addralign); - READ_WORD(s,t.sh_entsize); - /**/ - if (byteswap) { - /* Swap an Elf32_Shdr */ - SWAP_WORD(t.sh_name); - SWAP_WORD(t.sh_type); - SWAP_WORD(t.sh_flags); - SWAP_ADDR32(t.sh_addr); - SWAP_OFF32(t.sh_offset); - SWAP_WORD(t.sh_size); - SWAP_WORD(t.sh_link); - SWAP_WORD(t.sh_info); - SWAP_WORD(t.sh_addralign); - SWAP_WORD(t.sh_entsize); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_SHDR64_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Shdr t, *s; - size_t c; - - (void) dsz; - - s = (Elf64_Shdr *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf64_Shdr */ - SWAP_WORD(t.sh_name); - SWAP_WORD(t.sh_type); - SWAP_XWORD(t.sh_flags); - SWAP_ADDR64(t.sh_addr); - SWAP_OFF64(t.sh_offset); - SWAP_XWORD(t.sh_size); - SWAP_WORD(t.sh_link); - SWAP_WORD(t.sh_info); - SWAP_XWORD(t.sh_addralign); - SWAP_XWORD(t.sh_entsize); - /**/ - } - /* Write an Elf64_Shdr */ - WRITE_WORD(dst,t.sh_name); - WRITE_WORD(dst,t.sh_type); - WRITE_XWORD(dst,t.sh_flags); - WRITE_ADDR64(dst,t.sh_addr); - WRITE_OFF64(dst,t.sh_offset); - WRITE_XWORD(dst,t.sh_size); - WRITE_WORD(dst,t.sh_link); - WRITE_WORD(dst,t.sh_info); - WRITE_XWORD(dst,t.sh_addralign); - WRITE_XWORD(dst,t.sh_entsize); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_SHDR64_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Shdr t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf64_fsize(ELF_T_SHDR, (size_t) 1, EV_CURRENT); - d = ((Elf64_Shdr *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf64_Shdr)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf64_Shdr */ - READ_WORD(s,t.sh_name); - READ_WORD(s,t.sh_type); - READ_XWORD(s,t.sh_flags); - READ_ADDR64(s,t.sh_addr); - READ_OFF64(s,t.sh_offset); - READ_XWORD(s,t.sh_size); - READ_WORD(s,t.sh_link); - READ_WORD(s,t.sh_info); - READ_XWORD(s,t.sh_addralign); - READ_XWORD(s,t.sh_entsize); - /**/ - if (byteswap) { - /* Swap an Elf64_Shdr */ - SWAP_WORD(t.sh_name); - SWAP_WORD(t.sh_type); - SWAP_XWORD(t.sh_flags); - SWAP_ADDR64(t.sh_addr); - SWAP_OFF64(t.sh_offset); - SWAP_XWORD(t.sh_size); - SWAP_WORD(t.sh_link); - SWAP_WORD(t.sh_info); - SWAP_XWORD(t.sh_addralign); - SWAP_XWORD(t.sh_entsize); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_SWORD_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Sword t, *s = (Elf64_Sword *) (uintptr_t) src; - size_t c; - - (void) dsz; - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*s)); - return (1); - } - - for (c = 0; c < count; c++) { - t = *s++; - SWAP_SWORD(t); - WRITE_SWORD(dst,t); - } - - return (1); -} - -static int -_libelf_cvt_SWORD_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Sword t, *d = (Elf64_Sword *) (uintptr_t) dst; - size_t c; - - if (dsz < count * sizeof(Elf64_Sword)) - return (0); - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*d)); - return (1); - } - - for (c = 0; c < count; c++) { - READ_SWORD(src,t); - SWAP_SWORD(t); - *d++ = t; - } - - return (1); -} - -static int -_libelf_cvt_SXWORD_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Sxword t, *s = (Elf64_Sxword *) (uintptr_t) src; - size_t c; - - (void) dsz; - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*s)); - return (1); - } - - for (c = 0; c < count; c++) { - t = *s++; - SWAP_SXWORD(t); - WRITE_SXWORD(dst,t); - } - - return (1); -} - -static int -_libelf_cvt_SXWORD_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Sxword t, *d = (Elf64_Sxword *) (uintptr_t) dst; - size_t c; - - if (dsz < count * sizeof(Elf64_Sxword)) - return (0); - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*d)); - return (1); - } - - for (c = 0; c < count; c++) { - READ_SXWORD(src,t); - SWAP_SXWORD(t); - *d++ = t; - } - - return (1); -} - -static int -_libelf_cvt_SYMINFO32_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Syminfo t, *s; - size_t c; - - (void) dsz; - - s = (Elf32_Syminfo *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf32_Syminfo */ - SWAP_HALF(t.si_boundto); - SWAP_HALF(t.si_flags); - /**/ - } - /* Write an Elf32_Syminfo */ - WRITE_HALF(dst,t.si_boundto); - WRITE_HALF(dst,t.si_flags); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_SYMINFO32_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Syminfo t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf32_fsize(ELF_T_SYMINFO, (size_t) 1, EV_CURRENT); - d = ((Elf32_Syminfo *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf32_Syminfo)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf32_Syminfo */ - READ_HALF(s,t.si_boundto); - READ_HALF(s,t.si_flags); - /**/ - if (byteswap) { - /* Swap an Elf32_Syminfo */ - SWAP_HALF(t.si_boundto); - SWAP_HALF(t.si_flags); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_SYMINFO64_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Syminfo t, *s; - size_t c; - - (void) dsz; - - s = (Elf64_Syminfo *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf64_Syminfo */ - SWAP_HALF(t.si_boundto); - SWAP_HALF(t.si_flags); - /**/ - } - /* Write an Elf64_Syminfo */ - WRITE_HALF(dst,t.si_boundto); - WRITE_HALF(dst,t.si_flags); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_SYMINFO64_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Syminfo t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf64_fsize(ELF_T_SYMINFO, (size_t) 1, EV_CURRENT); - d = ((Elf64_Syminfo *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf64_Syminfo)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf64_Syminfo */ - READ_HALF(s,t.si_boundto); - READ_HALF(s,t.si_flags); - /**/ - if (byteswap) { - /* Swap an Elf64_Syminfo */ - SWAP_HALF(t.si_boundto); - SWAP_HALF(t.si_flags); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_SYM32_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Sym t, *s; - size_t c; - - (void) dsz; - - s = (Elf32_Sym *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf32_Sym */ - SWAP_WORD(t.st_name); - SWAP_ADDR32(t.st_value); - SWAP_WORD(t.st_size); - SWAP_BYTE(t.st_info); - SWAP_BYTE(t.st_other); - SWAP_HALF(t.st_shndx); - /**/ - } - /* Write an Elf32_Sym */ - WRITE_WORD(dst,t.st_name); - WRITE_ADDR32(dst,t.st_value); - WRITE_WORD(dst,t.st_size); - WRITE_BYTE(dst,t.st_info); - WRITE_BYTE(dst,t.st_other); - WRITE_HALF(dst,t.st_shndx); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_SYM32_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Sym t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf32_fsize(ELF_T_SYM, (size_t) 1, EV_CURRENT); - d = ((Elf32_Sym *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf32_Sym)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf32_Sym */ - READ_WORD(s,t.st_name); - READ_ADDR32(s,t.st_value); - READ_WORD(s,t.st_size); - READ_BYTE(s,t.st_info); - READ_BYTE(s,t.st_other); - READ_HALF(s,t.st_shndx); - /**/ - if (byteswap) { - /* Swap an Elf32_Sym */ - SWAP_WORD(t.st_name); - SWAP_ADDR32(t.st_value); - SWAP_WORD(t.st_size); - SWAP_BYTE(t.st_info); - SWAP_BYTE(t.st_other); - SWAP_HALF(t.st_shndx); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_SYM64_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Sym t, *s; - size_t c; - - (void) dsz; - - s = (Elf64_Sym *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - /* Swap an Elf64_Sym */ - SWAP_WORD(t.st_name); - SWAP_BYTE(t.st_info); - SWAP_BYTE(t.st_other); - SWAP_HALF(t.st_shndx); - SWAP_ADDR64(t.st_value); - SWAP_XWORD(t.st_size); - /**/ - } - /* Write an Elf64_Sym */ - WRITE_WORD(dst,t.st_name); - WRITE_BYTE(dst,t.st_info); - WRITE_BYTE(dst,t.st_other); - WRITE_HALF(dst,t.st_shndx); - WRITE_ADDR64(dst,t.st_value); - WRITE_XWORD(dst,t.st_size); - /**/ - } - - return (1); -} - -static int -_libelf_cvt_SYM64_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Sym t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf64_fsize(ELF_T_SYM, (size_t) 1, EV_CURRENT); - d = ((Elf64_Sym *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf64_Sym)) - return (0); - - while (count--) { - s = s0; - /* Read an Elf64_Sym */ - READ_WORD(s,t.st_name); - READ_BYTE(s,t.st_info); - READ_BYTE(s,t.st_other); - READ_HALF(s,t.st_shndx); - READ_ADDR64(s,t.st_value); - READ_XWORD(s,t.st_size); - /**/ - if (byteswap) { - /* Swap an Elf64_Sym */ - SWAP_WORD(t.st_name); - SWAP_BYTE(t.st_info); - SWAP_BYTE(t.st_other); - SWAP_HALF(t.st_shndx); - SWAP_ADDR64(t.st_value); - SWAP_XWORD(t.st_size); - /**/ - } - *d-- = t; s0 -= fsz; - } - - return (1); -} - -static int -_libelf_cvt_WORD_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Word t, *s = (Elf64_Word *) (uintptr_t) src; - size_t c; - - (void) dsz; - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*s)); - return (1); - } - - for (c = 0; c < count; c++) { - t = *s++; - SWAP_WORD(t); - WRITE_WORD(dst,t); - } - - return (1); -} - -static int -_libelf_cvt_WORD_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Word t, *d = (Elf64_Word *) (uintptr_t) dst; - size_t c; - - if (dsz < count * sizeof(Elf64_Word)) - return (0); - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*d)); - return (1); - } - - for (c = 0; c < count; c++) { - READ_WORD(src,t); - SWAP_WORD(t); - *d++ = t; - } - - return (1); -} - -static int -_libelf_cvt_XWORD_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Xword t, *s = (Elf64_Xword *) (uintptr_t) src; - size_t c; - - (void) dsz; - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*s)); - return (1); - } - - for (c = 0; c < count; c++) { - t = *s++; - SWAP_XWORD(t); - WRITE_XWORD(dst,t); - } - - return (1); -} - -static int -_libelf_cvt_XWORD_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Xword t, *d = (Elf64_Xword *) (uintptr_t) dst; - size_t c; - - if (dsz < count * sizeof(Elf64_Xword)) - return (0); - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*d)); - return (1); - } - - for (c = 0; c < count; c++) { - READ_XWORD(src,t); - SWAP_XWORD(t); - *d++ = t; - } - - return (1); -} - - -static int -_libelf_cvt_VDEF32_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Verdef t; - Elf32_Verdaux a; - const size_t verfsz = 20; - const size_t auxfsz = 8; - const size_t vermsz = sizeof(Elf32_Verdef); - const size_t auxmsz = sizeof(Elf32_Verdaux); - char * const dstend = dst + dsz; - char * const srcend = src + count; - char *dtmp, *dstaux, *srcaux; - Elf32_Word aux, anext, cnt, vnext; - - for (dtmp = dst, vnext = ~0; - vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend; - dtmp += vnext, src += vnext) { - - /* Read in an Elf32_Verdef structure. */ - t = *((Elf32_Verdef *) (uintptr_t) src); - - aux = t.vd_aux; - cnt = t.vd_cnt; - vnext = t.vd_next; - - if (byteswap) { - /* Swap an Elf32_Verdef */ - SWAP_HALF(t.vd_version); - SWAP_HALF(t.vd_flags); - SWAP_HALF(t.vd_ndx); - SWAP_HALF(t.vd_cnt); - SWAP_WORD(t.vd_hash); - SWAP_WORD(t.vd_aux); - SWAP_WORD(t.vd_next); - /**/ - } - - dst = dtmp; - /* Write an Elf32_Verdef */ - WRITE_HALF(dst,t.vd_version); - WRITE_HALF(dst,t.vd_flags); - WRITE_HALF(dst,t.vd_ndx); - WRITE_HALF(dst,t.vd_cnt); - WRITE_WORD(dst,t.vd_hash); - WRITE_WORD(dst,t.vd_aux); - WRITE_WORD(dst,t.vd_next); - /**/ - - if (aux < verfsz) - return (0); - - /* Process AUX entries. */ - for (anext = ~0, dstaux = dtmp + aux, srcaux = src + aux; - cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend && - srcaux + auxmsz <= srcend; - dstaux += anext, srcaux += anext, cnt--) { - - /* Read in an Elf32_Verdaux structure. */ - a = *((Elf32_Verdaux *) (uintptr_t) srcaux); - anext = a.vda_next; - - if (byteswap) { - /* Swap an Elf32_Verdaux */ - SWAP_WORD(a.vda_name); - SWAP_WORD(a.vda_next); - /**/ - } - - dst = dstaux; - /* Write an Elf32_Verdaux */ - WRITE_WORD(dst,a.vda_name); - WRITE_WORD(dst,a.vda_next); - /**/ - } - - if (anext || cnt) - return (0); - } - - if (vnext) - return (0); - - return (1); -} - -static int -_libelf_cvt_VDEF32_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Verdef t, *dp; - Elf32_Verdaux a, *ap; - const size_t verfsz = 20; - const size_t auxfsz = 8; - const size_t vermsz = sizeof(Elf32_Verdef); - const size_t auxmsz = sizeof(Elf32_Verdaux); - char * const dstend = dst + dsz; - char * const srcend = src + count; - char *dstaux, *s, *srcaux, *stmp; - Elf32_Word aux, anext, cnt, vnext; - - for (stmp = src, vnext = ~0; - vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend; - stmp += vnext, dst += vnext) { - - /* Read in a VDEF structure. */ - s = stmp; - /* Read an Elf32_Verdef */ - READ_HALF(s,t.vd_version); - READ_HALF(s,t.vd_flags); - READ_HALF(s,t.vd_ndx); - READ_HALF(s,t.vd_cnt); - READ_WORD(s,t.vd_hash); - READ_WORD(s,t.vd_aux); - READ_WORD(s,t.vd_next); - /**/ - if (byteswap) { - /* Swap an Elf32_Verdef */ - SWAP_HALF(t.vd_version); - SWAP_HALF(t.vd_flags); - SWAP_HALF(t.vd_ndx); - SWAP_HALF(t.vd_cnt); - SWAP_WORD(t.vd_hash); - SWAP_WORD(t.vd_aux); - SWAP_WORD(t.vd_next); - /**/ - } - - dp = (Elf32_Verdef *) (uintptr_t) dst; - *dp = t; - - aux = t.vd_aux; - cnt = t.vd_cnt; - vnext = t.vd_next; - - if (aux < vermsz) - return (0); - - /* Process AUX entries. */ - for (anext = ~0, dstaux = dst + aux, srcaux = stmp + aux; - cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend && - srcaux + auxfsz <= srcend; - dstaux += anext, srcaux += anext, cnt--) { - - s = srcaux; - /* Read an Elf32_Verdaux */ - READ_WORD(s,a.vda_name); - READ_WORD(s,a.vda_next); - /**/ - - if (byteswap) { - /* Swap an Elf32_Verdaux */ - SWAP_WORD(a.vda_name); - SWAP_WORD(a.vda_next); - /**/ - } - - anext = a.vda_next; - - ap = ((Elf32_Verdaux *) (uintptr_t) dstaux); - *ap = a; - } - - if (anext || cnt) - return (0); - } - - if (vnext) - return (0); - - return (1); -} - -static int -_libelf_cvt_VDEF64_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Verdef t; - Elf64_Verdaux a; - const size_t verfsz = 20; - const size_t auxfsz = 8; - const size_t vermsz = sizeof(Elf64_Verdef); - const size_t auxmsz = sizeof(Elf64_Verdaux); - char * const dstend = dst + dsz; - char * const srcend = src + count; - char *dtmp, *dstaux, *srcaux; - Elf64_Word aux, anext, cnt, vnext; - - for (dtmp = dst, vnext = ~0; - vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend; - dtmp += vnext, src += vnext) { - - /* Read in an Elf64_Verdef structure. */ - t = *((Elf64_Verdef *) (uintptr_t) src); - - aux = t.vd_aux; - cnt = t.vd_cnt; - vnext = t.vd_next; - - if (byteswap) { - /* Swap an Elf64_Verdef */ - SWAP_HALF(t.vd_version); - SWAP_HALF(t.vd_flags); - SWAP_HALF(t.vd_ndx); - SWAP_HALF(t.vd_cnt); - SWAP_WORD(t.vd_hash); - SWAP_WORD(t.vd_aux); - SWAP_WORD(t.vd_next); - /**/ - } - - dst = dtmp; - /* Write an Elf64_Verdef */ - WRITE_HALF(dst,t.vd_version); - WRITE_HALF(dst,t.vd_flags); - WRITE_HALF(dst,t.vd_ndx); - WRITE_HALF(dst,t.vd_cnt); - WRITE_WORD(dst,t.vd_hash); - WRITE_WORD(dst,t.vd_aux); - WRITE_WORD(dst,t.vd_next); - /**/ - - if (aux < verfsz) - return (0); - - /* Process AUX entries. */ - for (anext = ~0, dstaux = dtmp + aux, srcaux = src + aux; - cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend && - srcaux + auxmsz <= srcend; - dstaux += anext, srcaux += anext, cnt--) { - - /* Read in an Elf64_Verdaux structure. */ - a = *((Elf64_Verdaux *) (uintptr_t) srcaux); - anext = a.vda_next; - - if (byteswap) { - /* Swap an Elf64_Verdaux */ - SWAP_WORD(a.vda_name); - SWAP_WORD(a.vda_next); - /**/ - } - - dst = dstaux; - /* Write an Elf64_Verdaux */ - WRITE_WORD(dst,a.vda_name); - WRITE_WORD(dst,a.vda_next); - /**/ - } - - if (anext || cnt) - return (0); - } - - if (vnext) - return (0); - - return (1); -} - -static int -_libelf_cvt_VDEF64_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Verdef t, *dp; - Elf64_Verdaux a, *ap; - const size_t verfsz = 20; - const size_t auxfsz = 8; - const size_t vermsz = sizeof(Elf64_Verdef); - const size_t auxmsz = sizeof(Elf64_Verdaux); - char * const dstend = dst + dsz; - char * const srcend = src + count; - char *dstaux, *s, *srcaux, *stmp; - Elf64_Word aux, anext, cnt, vnext; - - for (stmp = src, vnext = ~0; - vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend; - stmp += vnext, dst += vnext) { - - /* Read in a VDEF structure. */ - s = stmp; - /* Read an Elf64_Verdef */ - READ_HALF(s,t.vd_version); - READ_HALF(s,t.vd_flags); - READ_HALF(s,t.vd_ndx); - READ_HALF(s,t.vd_cnt); - READ_WORD(s,t.vd_hash); - READ_WORD(s,t.vd_aux); - READ_WORD(s,t.vd_next); - /**/ - if (byteswap) { - /* Swap an Elf64_Verdef */ - SWAP_HALF(t.vd_version); - SWAP_HALF(t.vd_flags); - SWAP_HALF(t.vd_ndx); - SWAP_HALF(t.vd_cnt); - SWAP_WORD(t.vd_hash); - SWAP_WORD(t.vd_aux); - SWAP_WORD(t.vd_next); - /**/ - } - - dp = (Elf64_Verdef *) (uintptr_t) dst; - *dp = t; - - aux = t.vd_aux; - cnt = t.vd_cnt; - vnext = t.vd_next; - - if (aux < vermsz) - return (0); - - /* Process AUX entries. */ - for (anext = ~0, dstaux = dst + aux, srcaux = stmp + aux; - cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend && - srcaux + auxfsz <= srcend; - dstaux += anext, srcaux += anext, cnt--) { - - s = srcaux; - /* Read an Elf64_Verdaux */ - READ_WORD(s,a.vda_name); - READ_WORD(s,a.vda_next); - /**/ - - if (byteswap) { - /* Swap an Elf64_Verdaux */ - SWAP_WORD(a.vda_name); - SWAP_WORD(a.vda_next); - /**/ - } - - anext = a.vda_next; - - ap = ((Elf64_Verdaux *) (uintptr_t) dstaux); - *ap = a; - } - - if (anext || cnt) - return (0); - } - - if (vnext) - return (0); - - return (1); -} - -static int -_libelf_cvt_VNEED32_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Verneed t; - Elf32_Vernaux a; - const size_t verfsz = 16; - const size_t auxfsz = 16; - const size_t vermsz = sizeof(Elf32_Verneed); - const size_t auxmsz = sizeof(Elf32_Vernaux); - char * const dstend = dst + dsz; - char * const srcend = src + count; - char *dtmp, *dstaux, *srcaux; - Elf32_Word aux, anext, cnt, vnext; - - for (dtmp = dst, vnext = ~0; - vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend; - dtmp += vnext, src += vnext) { - - /* Read in an Elf32_Verneed structure. */ - t = *((Elf32_Verneed *) (uintptr_t) src); - - aux = t.vn_aux; - cnt = t.vn_cnt; - vnext = t.vn_next; - - if (byteswap) { - /* Swap an Elf32_Verneed */ - SWAP_HALF(t.vn_version); - SWAP_HALF(t.vn_cnt); - SWAP_WORD(t.vn_file); - SWAP_WORD(t.vn_aux); - SWAP_WORD(t.vn_next); - /**/ - } - - dst = dtmp; - /* Write an Elf32_Verneed */ - WRITE_HALF(dst,t.vn_version); - WRITE_HALF(dst,t.vn_cnt); - WRITE_WORD(dst,t.vn_file); - WRITE_WORD(dst,t.vn_aux); - WRITE_WORD(dst,t.vn_next); - /**/ - - if (aux < verfsz) - return (0); - - /* Process AUX entries. */ - for (anext = ~0, dstaux = dtmp + aux, srcaux = src + aux; - cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend && - srcaux + auxmsz <= srcend; - dstaux += anext, srcaux += anext, cnt--) { - - /* Read in an Elf32_Vernaux structure. */ - a = *((Elf32_Vernaux *) (uintptr_t) srcaux); - anext = a.vna_next; - - if (byteswap) { - /* Swap an Elf32_Vernaux */ - SWAP_WORD(a.vna_hash); - SWAP_HALF(a.vna_flags); - SWAP_HALF(a.vna_other); - SWAP_WORD(a.vna_name); - SWAP_WORD(a.vna_next); - /**/ - } - - dst = dstaux; - /* Write an Elf32_Vernaux */ - WRITE_WORD(dst,a.vna_hash); - WRITE_HALF(dst,a.vna_flags); - WRITE_HALF(dst,a.vna_other); - WRITE_WORD(dst,a.vna_name); - WRITE_WORD(dst,a.vna_next); - /**/ - } - - if (anext || cnt) - return (0); - } - - if (vnext) - return (0); - - return (1); -} - -static int -_libelf_cvt_VNEED32_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf32_Verneed t, *dp; - Elf32_Vernaux a, *ap; - const size_t verfsz = 16; - const size_t auxfsz = 16; - const size_t vermsz = sizeof(Elf32_Verneed); - const size_t auxmsz = sizeof(Elf32_Vernaux); - char * const dstend = dst + dsz; - char * const srcend = src + count; - char *dstaux, *s, *srcaux, *stmp; - Elf32_Word aux, anext, cnt, vnext; - - for (stmp = src, vnext = ~0; - vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend; - stmp += vnext, dst += vnext) { - - /* Read in a VNEED structure. */ - s = stmp; - /* Read an Elf32_Verneed */ - READ_HALF(s,t.vn_version); - READ_HALF(s,t.vn_cnt); - READ_WORD(s,t.vn_file); - READ_WORD(s,t.vn_aux); - READ_WORD(s,t.vn_next); - /**/ - if (byteswap) { - /* Swap an Elf32_Verneed */ - SWAP_HALF(t.vn_version); - SWAP_HALF(t.vn_cnt); - SWAP_WORD(t.vn_file); - SWAP_WORD(t.vn_aux); - SWAP_WORD(t.vn_next); - /**/ - } - - dp = (Elf32_Verneed *) (uintptr_t) dst; - *dp = t; - - aux = t.vn_aux; - cnt = t.vn_cnt; - vnext = t.vn_next; - - if (aux < vermsz) - return (0); - - /* Process AUX entries. */ - for (anext = ~0, dstaux = dst + aux, srcaux = stmp + aux; - cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend && - srcaux + auxfsz <= srcend; - dstaux += anext, srcaux += anext, cnt--) { - - s = srcaux; - /* Read an Elf32_Vernaux */ - READ_WORD(s,a.vna_hash); - READ_HALF(s,a.vna_flags); - READ_HALF(s,a.vna_other); - READ_WORD(s,a.vna_name); - READ_WORD(s,a.vna_next); - /**/ - - if (byteswap) { - /* Swap an Elf32_Vernaux */ - SWAP_WORD(a.vna_hash); - SWAP_HALF(a.vna_flags); - SWAP_HALF(a.vna_other); - SWAP_WORD(a.vna_name); - SWAP_WORD(a.vna_next); - /**/ - } - - anext = a.vna_next; - - ap = ((Elf32_Vernaux *) (uintptr_t) dstaux); - *ap = a; - } - - if (anext || cnt) - return (0); - } - - if (vnext) - return (0); - - return (1); -} - -static int -_libelf_cvt_VNEED64_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Verneed t; - Elf64_Vernaux a; - const size_t verfsz = 16; - const size_t auxfsz = 16; - const size_t vermsz = sizeof(Elf64_Verneed); - const size_t auxmsz = sizeof(Elf64_Vernaux); - char * const dstend = dst + dsz; - char * const srcend = src + count; - char *dtmp, *dstaux, *srcaux; - Elf64_Word aux, anext, cnt, vnext; - - for (dtmp = dst, vnext = ~0; - vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend; - dtmp += vnext, src += vnext) { - - /* Read in an Elf64_Verneed structure. */ - t = *((Elf64_Verneed *) (uintptr_t) src); - - aux = t.vn_aux; - cnt = t.vn_cnt; - vnext = t.vn_next; - - if (byteswap) { - /* Swap an Elf64_Verneed */ - SWAP_HALF(t.vn_version); - SWAP_HALF(t.vn_cnt); - SWAP_WORD(t.vn_file); - SWAP_WORD(t.vn_aux); - SWAP_WORD(t.vn_next); - /**/ - } - - dst = dtmp; - /* Write an Elf64_Verneed */ - WRITE_HALF(dst,t.vn_version); - WRITE_HALF(dst,t.vn_cnt); - WRITE_WORD(dst,t.vn_file); - WRITE_WORD(dst,t.vn_aux); - WRITE_WORD(dst,t.vn_next); - /**/ - - if (aux < verfsz) - return (0); - - /* Process AUX entries. */ - for (anext = ~0, dstaux = dtmp + aux, srcaux = src + aux; - cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend && - srcaux + auxmsz <= srcend; - dstaux += anext, srcaux += anext, cnt--) { - - /* Read in an Elf64_Vernaux structure. */ - a = *((Elf64_Vernaux *) (uintptr_t) srcaux); - anext = a.vna_next; - - if (byteswap) { - /* Swap an Elf64_Vernaux */ - SWAP_WORD(a.vna_hash); - SWAP_HALF(a.vna_flags); - SWAP_HALF(a.vna_other); - SWAP_WORD(a.vna_name); - SWAP_WORD(a.vna_next); - /**/ - } - - dst = dstaux; - /* Write an Elf64_Vernaux */ - WRITE_WORD(dst,a.vna_hash); - WRITE_HALF(dst,a.vna_flags); - WRITE_HALF(dst,a.vna_other); - WRITE_WORD(dst,a.vna_name); - WRITE_WORD(dst,a.vna_next); - /**/ - } - - if (anext || cnt) - return (0); - } - - if (vnext) - return (0); - - return (1); -} - -static int -_libelf_cvt_VNEED64_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf64_Verneed t, *dp; - Elf64_Vernaux a, *ap; - const size_t verfsz = 16; - const size_t auxfsz = 16; - const size_t vermsz = sizeof(Elf64_Verneed); - const size_t auxmsz = sizeof(Elf64_Vernaux); - char * const dstend = dst + dsz; - char * const srcend = src + count; - char *dstaux, *s, *srcaux, *stmp; - Elf64_Word aux, anext, cnt, vnext; - - for (stmp = src, vnext = ~0; - vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend; - stmp += vnext, dst += vnext) { - - /* Read in a VNEED structure. */ - s = stmp; - /* Read an Elf64_Verneed */ - READ_HALF(s,t.vn_version); - READ_HALF(s,t.vn_cnt); - READ_WORD(s,t.vn_file); - READ_WORD(s,t.vn_aux); - READ_WORD(s,t.vn_next); - /**/ - if (byteswap) { - /* Swap an Elf64_Verneed */ - SWAP_HALF(t.vn_version); - SWAP_HALF(t.vn_cnt); - SWAP_WORD(t.vn_file); - SWAP_WORD(t.vn_aux); - SWAP_WORD(t.vn_next); - /**/ - } - - dp = (Elf64_Verneed *) (uintptr_t) dst; - *dp = t; - - aux = t.vn_aux; - cnt = t.vn_cnt; - vnext = t.vn_next; - - if (aux < vermsz) - return (0); - - /* Process AUX entries. */ - for (anext = ~0, dstaux = dst + aux, srcaux = stmp + aux; - cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend && - srcaux + auxfsz <= srcend; - dstaux += anext, srcaux += anext, cnt--) { - - s = srcaux; - /* Read an Elf64_Vernaux */ - READ_WORD(s,a.vna_hash); - READ_HALF(s,a.vna_flags); - READ_HALF(s,a.vna_other); - READ_WORD(s,a.vna_name); - READ_WORD(s,a.vna_next); - /**/ - - if (byteswap) { - /* Swap an Elf64_Vernaux */ - SWAP_WORD(a.vna_hash); - SWAP_HALF(a.vna_flags); - SWAP_HALF(a.vna_other); - SWAP_WORD(a.vna_name); - SWAP_WORD(a.vna_next); - /**/ - } - - anext = a.vna_next; - - ap = ((Elf64_Vernaux *) (uintptr_t) dstaux); - *ap = a; - } - - if (anext || cnt) - return (0); - } - - if (vnext) - return (0); - - return (1); -} -/*]*/ - -/* - * Sections of type ELF_T_BYTE are never byteswapped, consequently a - * simple memcpy suffices for both directions of conversion. - */ - -static int -_libelf_cvt_BYTE_tox(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - (void) byteswap; - if (dsz < count) - return (0); - if (dst != src) - (void) memcpy(dst, src, count); - return (1); -} - -/* - * Sections of type ELF_T_GNUHASH start with a header containing 4 32-bit - * words. Bloom filter data comes next, followed by hash buckets and the - * hash chain. - * - * Bloom filter words are 64 bit wide on ELFCLASS64 objects and are 32 bit - * wide on ELFCLASS32 objects. The other objects in this section are 32 - * bits wide. - * - * Argument srcsz denotes the number of bytes to be converted. In the - * 32-bit case we need to translate srcsz to a count of 32-bit words. - */ - -static int -_libelf_cvt_GNUHASH32_tom(char *dst, size_t dsz, char *src, size_t srcsz, - int byteswap) -{ - return (_libelf_cvt_WORD_tom(dst, dsz, src, srcsz / sizeof(uint32_t), - byteswap)); -} - -static int -_libelf_cvt_GNUHASH32_tof(char *dst, size_t dsz, char *src, size_t srcsz, - int byteswap) -{ - return (_libelf_cvt_WORD_tof(dst, dsz, src, srcsz / sizeof(uint32_t), - byteswap)); -} - -static int -_libelf_cvt_GNUHASH64_tom(char *dst, size_t dsz, char *src, size_t srcsz, - int byteswap) -{ - size_t sz; - uint64_t t64, *bloom64; - Elf_GNU_Hash_Header *gh; - uint32_t n, nbuckets, nchains, maskwords, shift2, symndx, t32; - uint32_t *buckets, *chains; - - sz = 4 * sizeof(uint32_t); /* File header is 4 words long. */ - if (dsz < sizeof(Elf_GNU_Hash_Header) || srcsz < sz) - return (0); - - /* Read in the section header and byteswap if needed. */ - READ_WORD(src, nbuckets); - READ_WORD(src, symndx); - READ_WORD(src, maskwords); - READ_WORD(src, shift2); - - srcsz -= sz; - - if (byteswap) { - SWAP_WORD(nbuckets); - SWAP_WORD(symndx); - SWAP_WORD(maskwords); - SWAP_WORD(shift2); - } - - /* Check source buffer and destination buffer sizes. */ - sz = nbuckets * sizeof(uint32_t) + maskwords * sizeof(uint64_t); - if (srcsz < sz || dsz < sz + sizeof(Elf_GNU_Hash_Header)) - return (0); - - gh = (Elf_GNU_Hash_Header *) (uintptr_t) dst; - gh->gh_nbuckets = nbuckets; - gh->gh_symndx = symndx; - gh->gh_maskwords = maskwords; - gh->gh_shift2 = shift2; - - dsz -= sizeof(Elf_GNU_Hash_Header); - dst += sizeof(Elf_GNU_Hash_Header); - - bloom64 = (uint64_t *) (uintptr_t) dst; - - /* Copy bloom filter data. */ - for (n = 0; n < maskwords; n++) { - READ_XWORD(src, t64); - if (byteswap) - SWAP_XWORD(t64); - bloom64[n] = t64; - } - - /* The hash buckets follows the bloom filter. */ - dst += maskwords * sizeof(uint64_t); - buckets = (uint32_t *) (uintptr_t) dst; - - for (n = 0; n < nbuckets; n++) { - READ_WORD(src, t32); - if (byteswap) - SWAP_WORD(t32); - buckets[n] = t32; - } - - dst += nbuckets * sizeof(uint32_t); - - /* The hash chain follows the hash buckets. */ - dsz -= sz; - srcsz -= sz; - - if (dsz < srcsz) /* Destination lacks space. */ - return (0); - - nchains = srcsz / sizeof(uint32_t); - chains = (uint32_t *) (uintptr_t) dst; - - for (n = 0; n < nchains; n++) { - READ_WORD(src, t32); - if (byteswap) - SWAP_WORD(t32); - *chains++ = t32; - } - - return (1); -} - -static int -_libelf_cvt_GNUHASH64_tof(char *dst, size_t dsz, char *src, size_t srcsz, - int byteswap) -{ - uint32_t *s32; - size_t sz, hdrsz; - uint64_t *s64, t64; - Elf_GNU_Hash_Header *gh; - uint32_t maskwords, n, nbuckets, nchains, t0, t1, t2, t3, t32; - - hdrsz = 4 * sizeof(uint32_t); /* Header is 4x32 bits. */ - if (dsz < hdrsz || srcsz < sizeof(Elf_GNU_Hash_Header)) - return (0); - - gh = (Elf_GNU_Hash_Header *) (uintptr_t) src; - - t0 = nbuckets = gh->gh_nbuckets; - t1 = gh->gh_symndx; - t2 = maskwords = gh->gh_maskwords; - t3 = gh->gh_shift2; - - src += sizeof(Elf_GNU_Hash_Header); - srcsz -= sizeof(Elf_GNU_Hash_Header); - dsz -= hdrsz; - - sz = gh->gh_nbuckets * sizeof(uint32_t) + gh->gh_maskwords * - sizeof(uint64_t); - - if (srcsz < sz || dsz < sz) - return (0); - - /* Write out the header. */ - if (byteswap) { - SWAP_WORD(t0); - SWAP_WORD(t1); - SWAP_WORD(t2); - SWAP_WORD(t3); - } - - WRITE_WORD(dst, t0); - WRITE_WORD(dst, t1); - WRITE_WORD(dst, t2); - WRITE_WORD(dst, t3); - - /* Copy the bloom filter and the hash table. */ - s64 = (uint64_t *) (uintptr_t) src; - for (n = 0; n < maskwords; n++) { - t64 = *s64++; - if (byteswap) - SWAP_XWORD(t64); - WRITE_WORD64(dst, t64); - } - - s32 = (uint32_t *) s64; - for (n = 0; n < nbuckets; n++) { - t32 = *s32++; - if (byteswap) - SWAP_WORD(t32); - WRITE_WORD(dst, t32); - } - - srcsz -= sz; - dsz -= sz; - - /* Copy out the hash chains. */ - if (dsz < srcsz) - return (0); - - nchains = srcsz / sizeof(uint32_t); - for (n = 0; n < nchains; n++) { - t32 = *s32++; - if (byteswap) - SWAP_WORD(t32); - WRITE_WORD(dst, t32); - } - - return (1); -} - -/* - * Elf_Note structures comprise a fixed size header followed by variable - * length strings. The fixed size header needs to be byte swapped, but - * not the strings. - * - * Argument count denotes the total number of bytes to be converted. - * The destination buffer needs to be at least count bytes in size. - */ -static int -_libelf_cvt_NOTE_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - uint32_t namesz, descsz, type; - Elf_Note *en; - size_t sz, hdrsz; - - if (dsz < count) /* Destination buffer is too small. */ - return (0); - - hdrsz = 3 * sizeof(uint32_t); - if (count < hdrsz) /* Source too small. */ - return (0); - - if (!byteswap) { - (void) memcpy(dst, src, count); - return (1); - } - - /* Process all notes in the section. */ - while (count > hdrsz) { - /* Read the note header. */ - READ_WORD(src, namesz); - READ_WORD(src, descsz); - READ_WORD(src, type); - - /* Translate. */ - SWAP_WORD(namesz); - SWAP_WORD(descsz); - SWAP_WORD(type); - - /* Copy out the translated note header. */ - en = (Elf_Note *) (uintptr_t) dst; - en->n_namesz = namesz; - en->n_descsz = descsz; - en->n_type = type; - - dsz -= sizeof(Elf_Note); - dst += sizeof(Elf_Note); - count -= hdrsz; - - ROUNDUP2(namesz, 4); - ROUNDUP2(descsz, 4); - - sz = namesz + descsz; - - if (count < sz || dsz < sz) /* Buffers are too small. */ - return (0); - - (void) memcpy(dst, src, sz); - - src += sz; - dst += sz; - - count -= sz; - dsz -= sz; - } - - return (1); -} - -static int -_libelf_cvt_NOTE_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - uint32_t namesz, descsz, type; - Elf_Note *en; - size_t sz; - - if (dsz < count) - return (0); - - if (!byteswap) { - (void) memcpy(dst, src, count); - return (1); - } - - while (count > sizeof(Elf_Note)) { - - en = (Elf_Note *) (uintptr_t) src; - namesz = en->n_namesz; - descsz = en->n_descsz; - type = en->n_type; - - SWAP_WORD(namesz); - SWAP_WORD(descsz); - SWAP_WORD(type); - - WRITE_WORD(dst, namesz); - WRITE_WORD(dst, descsz); - WRITE_WORD(dst, type); - - src += sizeof(Elf_Note); - - ROUNDUP2(namesz, 4); - ROUNDUP2(descsz, 4); - - sz = namesz + descsz; - - if (count < sz) - sz = count; - - (void) memcpy(dst, src, sz); - - src += sz; - dst += sz; - count -= sz; - } - - return (1); -} - -struct converters { - int (*tof32)(char *dst, size_t dsz, char *src, size_t cnt, - int byteswap); - int (*tom32)(char *dst, size_t dsz, char *src, size_t cnt, - int byteswap); - int (*tof64)(char *dst, size_t dsz, char *src, size_t cnt, - int byteswap); - int (*tom64)(char *dst, size_t dsz, char *src, size_t cnt, - int byteswap); -}; - - -static struct converters cvt[ELF_T_NUM] = { - /*[*/ - [ELF_T_ADDR] = { - .tof32 = _libelf_cvt_ADDR32_tof, - .tom32 = _libelf_cvt_ADDR32_tom, - .tof64 = _libelf_cvt_ADDR64_tof, - .tom64 = _libelf_cvt_ADDR64_tom - }, - - [ELF_T_CAP] = { - .tof32 = _libelf_cvt_CAP32_tof, - .tom32 = _libelf_cvt_CAP32_tom, - .tof64 = _libelf_cvt_CAP64_tof, - .tom64 = _libelf_cvt_CAP64_tom - }, - - [ELF_T_DYN] = { - .tof32 = _libelf_cvt_DYN32_tof, - .tom32 = _libelf_cvt_DYN32_tom, - .tof64 = _libelf_cvt_DYN64_tof, - .tom64 = _libelf_cvt_DYN64_tom - }, - - [ELF_T_EHDR] = { - .tof32 = _libelf_cvt_EHDR32_tof, - .tom32 = _libelf_cvt_EHDR32_tom, - .tof64 = _libelf_cvt_EHDR64_tof, - .tom64 = _libelf_cvt_EHDR64_tom - }, - - [ELF_T_GNUHASH] = { - .tof32 = _libelf_cvt_GNUHASH32_tof, - .tom32 = _libelf_cvt_GNUHASH32_tom, - .tof64 = _libelf_cvt_GNUHASH64_tof, - .tom64 = _libelf_cvt_GNUHASH64_tom - }, - - [ELF_T_HALF] = { - .tof32 = _libelf_cvt_HALF_tof, - .tom32 = _libelf_cvt_HALF_tom, - .tof64 = _libelf_cvt_HALF_tof, - .tom64 = _libelf_cvt_HALF_tom - }, - - [ELF_T_LWORD] = { - .tof32 = _libelf_cvt_LWORD_tof, - .tom32 = _libelf_cvt_LWORD_tom, - .tof64 = _libelf_cvt_LWORD_tof, - .tom64 = _libelf_cvt_LWORD_tom - }, - - [ELF_T_MOVE] = { - .tof32 = _libelf_cvt_MOVE32_tof, - .tom32 = _libelf_cvt_MOVE32_tom, - .tof64 = _libelf_cvt_MOVE64_tof, - .tom64 = _libelf_cvt_MOVE64_tom - }, - - [ELF_T_OFF] = { - .tof32 = _libelf_cvt_OFF32_tof, - .tom32 = _libelf_cvt_OFF32_tom, - .tof64 = _libelf_cvt_OFF64_tof, - .tom64 = _libelf_cvt_OFF64_tom - }, - - [ELF_T_PHDR] = { - .tof32 = _libelf_cvt_PHDR32_tof, - .tom32 = _libelf_cvt_PHDR32_tom, - .tof64 = _libelf_cvt_PHDR64_tof, - .tom64 = _libelf_cvt_PHDR64_tom - }, - - [ELF_T_REL] = { - .tof32 = _libelf_cvt_REL32_tof, - .tom32 = _libelf_cvt_REL32_tom, - .tof64 = _libelf_cvt_REL64_tof, - .tom64 = _libelf_cvt_REL64_tom - }, - - [ELF_T_RELA] = { - .tof32 = _libelf_cvt_RELA32_tof, - .tom32 = _libelf_cvt_RELA32_tom, - .tof64 = _libelf_cvt_RELA64_tof, - .tom64 = _libelf_cvt_RELA64_tom - }, - - [ELF_T_SHDR] = { - .tof32 = _libelf_cvt_SHDR32_tof, - .tom32 = _libelf_cvt_SHDR32_tom, - .tof64 = _libelf_cvt_SHDR64_tof, - .tom64 = _libelf_cvt_SHDR64_tom - }, - - [ELF_T_SWORD] = { - .tof32 = _libelf_cvt_SWORD_tof, - .tom32 = _libelf_cvt_SWORD_tom, - .tof64 = _libelf_cvt_SWORD_tof, - .tom64 = _libelf_cvt_SWORD_tom - }, - - [ELF_T_SXWORD] = { - .tof32 = NULL, - .tom32 = NULL, - .tof64 = _libelf_cvt_SXWORD_tof, - .tom64 = _libelf_cvt_SXWORD_tom - }, - - [ELF_T_SYMINFO] = { - .tof32 = _libelf_cvt_SYMINFO32_tof, - .tom32 = _libelf_cvt_SYMINFO32_tom, - .tof64 = _libelf_cvt_SYMINFO64_tof, - .tom64 = _libelf_cvt_SYMINFO64_tom - }, - - [ELF_T_SYM] = { - .tof32 = _libelf_cvt_SYM32_tof, - .tom32 = _libelf_cvt_SYM32_tom, - .tof64 = _libelf_cvt_SYM64_tof, - .tom64 = _libelf_cvt_SYM64_tom - }, - - [ELF_T_VDEF] = { - .tof32 = _libelf_cvt_VDEF32_tof, - .tom32 = _libelf_cvt_VDEF32_tom, - .tof64 = _libelf_cvt_VDEF64_tof, - .tom64 = _libelf_cvt_VDEF64_tom - }, - - [ELF_T_VNEED] = { - .tof32 = _libelf_cvt_VNEED32_tof, - .tom32 = _libelf_cvt_VNEED32_tom, - .tof64 = _libelf_cvt_VNEED64_tof, - .tom64 = _libelf_cvt_VNEED64_tom - }, - - [ELF_T_WORD] = { - .tof32 = _libelf_cvt_WORD_tof, - .tom32 = _libelf_cvt_WORD_tom, - .tof64 = _libelf_cvt_WORD_tof, - .tom64 = _libelf_cvt_WORD_tom - }, - - [ELF_T_XWORD] = { - .tof32 = NULL, - .tom32 = NULL, - .tof64 = _libelf_cvt_XWORD_tof, - .tom64 = _libelf_cvt_XWORD_tom - }, - - - /*]*/ - - /* - * Types that need hand-coded converters follow. - */ - - [ELF_T_BYTE] = { - .tof32 = _libelf_cvt_BYTE_tox, - .tom32 = _libelf_cvt_BYTE_tox, - .tof64 = _libelf_cvt_BYTE_tox, - .tom64 = _libelf_cvt_BYTE_tox - }, - - [ELF_T_NOTE] = { - .tof32 = _libelf_cvt_NOTE_tof, - .tom32 = _libelf_cvt_NOTE_tom, - .tof64 = _libelf_cvt_NOTE_tof, - .tom64 = _libelf_cvt_NOTE_tom - } -}; - -int (*_libelf_get_translator(Elf_Type t, int direction, int elfclass)) - (char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap) -{ - assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); - assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY); - - if (t >= ELF_T_NUM || - (elfclass != ELFCLASS32 && elfclass != ELFCLASS64) || - (direction != ELF_TOFILE && direction != ELF_TOMEMORY)) - return (NULL); - - return ((elfclass == ELFCLASS32) ? - (direction == ELF_TOFILE ? cvt[t].tof32 : cvt[t].tom32) : - (direction == ELF_TOFILE ? cvt[t].tof64 : cvt[t].tom64)); -} diff --git a/src/libelf/libelf_data.c b/src/libelf/libelf_data.c deleted file mode 100644 index 809002f..0000000 --- a/src/libelf/libelf_data.c +++ /dev/null @@ -1,88 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: libelf_data.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -int -_libelf_xlate_shtype(uint32_t sht) -{ - switch (sht) { - case SHT_DYNAMIC: - return (ELF_T_DYN); - case SHT_DYNSYM: - return (ELF_T_SYM); - case SHT_FINI_ARRAY: - return (ELF_T_ADDR); - case SHT_GNU_HASH: - return (ELF_T_GNUHASH); - case SHT_GNU_LIBLIST: - return (ELF_T_WORD); - case SHT_GROUP: - return (ELF_T_WORD); - case SHT_HASH: - return (ELF_T_WORD); - case SHT_INIT_ARRAY: - return (ELF_T_ADDR); - case SHT_NOBITS: - return (ELF_T_BYTE); - case SHT_NOTE: - return (ELF_T_NOTE); - case SHT_PREINIT_ARRAY: - return (ELF_T_ADDR); - case SHT_PROGBITS: - return (ELF_T_BYTE); - case SHT_REL: - return (ELF_T_REL); - case SHT_RELA: - return (ELF_T_RELA); - case SHT_STRTAB: - return (ELF_T_BYTE); - case SHT_SYMTAB: - return (ELF_T_SYM); - case SHT_SYMTAB_SHNDX: - return (ELF_T_WORD); - case SHT_SUNW_dof: - return (ELF_T_BYTE); - case SHT_SUNW_move: - return (ELF_T_MOVE); - case SHT_SUNW_syminfo: - return (ELF_T_SYMINFO); - case SHT_SUNW_verdef: /* == SHT_GNU_verdef */ - return (ELF_T_VDEF); - case SHT_SUNW_verneed: /* == SHT_GNU_verneed */ - return (ELF_T_VNEED); - case SHT_SUNW_versym: /* == SHT_GNU_versym */ - return (ELF_T_HALF); - default: - return (-1); - } -} diff --git a/src/libelf/libelf_ehdr.c b/src/libelf/libelf_ehdr.c deleted file mode 100644 index 3125605..0000000 --- a/src/libelf/libelf_ehdr.c +++ /dev/null @@ -1,204 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include "gelf.h" -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: libelf_ehdr.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -/* - * Retrieve counts for sections, phdrs and the section string table index - * from section header #0 of the ELF object. - */ -static int -_libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum, - uint16_t strndx) -{ - Elf_Scn *scn; - size_t fsz; - int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); - uint32_t shtype; - - assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); - - fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, 1); - assert(fsz > 0); - - if (e->e_rawsize < shoff + fsz) { /* raw file too small */ - LIBELF_SET_ERROR(HEADER, 0); - return (0); - } - - if ((scn = _libelf_allocate_scn(e, (size_t) 0)) == NULL) - return (0); - - xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec); - (*xlator)((char *) &scn->s_shdr, sizeof(scn->s_shdr), - e->e_rawfile + shoff, (size_t) 1, - e->e_byteorder != LIBELF_PRIVATE(byteorder)); - -#define GET_SHDR_MEMBER(M) ((ec == ELFCLASS32) ? scn->s_shdr.s_shdr32.M : \ - scn->s_shdr.s_shdr64.M) - - if ((shtype = GET_SHDR_MEMBER(sh_type)) != SHT_NULL) { - LIBELF_SET_ERROR(SECTION, 0); - return (0); - } - - e->e_u.e_elf.e_nscn = GET_SHDR_MEMBER(sh_size); - e->e_u.e_elf.e_nphdr = (phnum != PN_XNUM) ? phnum : - GET_SHDR_MEMBER(sh_info); - e->e_u.e_elf.e_strndx = (strndx != SHN_XINDEX) ? strndx : - GET_SHDR_MEMBER(sh_link); -#undef GET_SHDR_MEMBER - - return (1); -} - -#define EHDR_INIT(E,SZ) do { \ - Elf##SZ##_Ehdr *eh = (E); \ - eh->e_ident[EI_MAG0] = ELFMAG0; \ - eh->e_ident[EI_MAG1] = ELFMAG1; \ - eh->e_ident[EI_MAG2] = ELFMAG2; \ - eh->e_ident[EI_MAG3] = ELFMAG3; \ - eh->e_ident[EI_CLASS] = ELFCLASS##SZ; \ - eh->e_ident[EI_DATA] = ELFDATANONE; \ - eh->e_ident[EI_VERSION] = LIBELF_PRIVATE(version); \ - eh->e_machine = EM_NONE; \ - eh->e_type = ELF_K_NONE; \ - eh->e_version = LIBELF_PRIVATE(version); \ - } while (0) - -void * -_libelf_ehdr(Elf *e, int ec, int allocate) -{ - void *ehdr; - size_t fsz, msz; - uint16_t phnum, shnum, strndx; - uint64_t shoff; - int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); - - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (e == NULL || e->e_kind != ELF_K_ELF) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (e->e_class != ELFCLASSNONE && e->e_class != ec) { - LIBELF_SET_ERROR(CLASS, 0); - return (NULL); - } - - if (e->e_version != EV_CURRENT) { - LIBELF_SET_ERROR(VERSION, 0); - return (NULL); - } - - if (e->e_class == ELFCLASSNONE) - e->e_class = ec; - - if (ec == ELFCLASS32) - ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr32; - else - ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr64; - - if (ehdr != NULL) /* already have a translated ehdr */ - return (ehdr); - - fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1); - assert(fsz > 0); - - if (e->e_cmd != ELF_C_WRITE && e->e_rawsize < fsz) { - LIBELF_SET_ERROR(HEADER, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_EHDR, ec, EV_CURRENT); - - assert(msz > 0); - - if ((ehdr = calloc((size_t) 1, msz)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - e->e_u.e_elf.e_ehdr.e_ehdr32 = ehdr; - EHDR_INIT(ehdr,32); - } else { - e->e_u.e_elf.e_ehdr.e_ehdr64 = ehdr; - EHDR_INIT(ehdr,64); - } - - if (allocate) - e->e_flags |= ELF_F_DIRTY; - - if (e->e_cmd == ELF_C_WRITE) - return (ehdr); - - xlator = _libelf_get_translator(ELF_T_EHDR, ELF_TOMEMORY, ec); - (*xlator)(ehdr, msz, e->e_rawfile, (size_t) 1, - e->e_byteorder != LIBELF_PRIVATE(byteorder)); - - /* - * If extended numbering is being used, read the correct - * number of sections and program header entries. - */ - if (ec == ELFCLASS32) { - phnum = ((Elf32_Ehdr *) ehdr)->e_phnum; - shnum = ((Elf32_Ehdr *) ehdr)->e_shnum; - shoff = ((Elf32_Ehdr *) ehdr)->e_shoff; - strndx = ((Elf32_Ehdr *) ehdr)->e_shstrndx; - } else { - phnum = ((Elf64_Ehdr *) ehdr)->e_phnum; - shnum = ((Elf64_Ehdr *) ehdr)->e_shnum; - shoff = ((Elf64_Ehdr *) ehdr)->e_shoff; - strndx = ((Elf64_Ehdr *) ehdr)->e_shstrndx; - } - - if (shnum >= SHN_LORESERVE || - (shoff == 0LL && (shnum != 0 || phnum == PN_XNUM || - strndx == SHN_XINDEX))) { - LIBELF_SET_ERROR(HEADER, 0); - return (NULL); - } - - if (shnum != 0 || shoff == 0LL) { /* not using extended numbering */ - e->e_u.e_elf.e_nphdr = phnum; - e->e_u.e_elf.e_nscn = shnum; - e->e_u.e_elf.e_strndx = strndx; - } else if (_libelf_load_extended(e, ec, shoff, phnum, strndx) == 0) - return (NULL); - - return (ehdr); -} diff --git a/src/libelf/libelf_extended.c b/src/libelf/libelf_extended.c deleted file mode 100644 index 5343696..0000000 --- a/src/libelf/libelf_extended.c +++ /dev/null @@ -1,136 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: libelf_extended.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -/* - * Retrieve section #0, allocating a new section if needed. - */ -static Elf_Scn * -_libelf_getscn0(Elf *e) -{ - Elf_Scn *s; - - if ((s = STAILQ_FIRST(&e->e_u.e_elf.e_scn)) != NULL) - return (s); - - return (_libelf_allocate_scn(e, (size_t) SHN_UNDEF)); -} - -int -_libelf_setshnum(Elf *e, void *eh, int ec, size_t shnum) -{ - Elf_Scn *scn; - - if (shnum >= SHN_LORESERVE) { - if ((scn = _libelf_getscn0(e)) == NULL) - return (0); - - assert(scn->s_ndx == SHN_UNDEF); - - if (ec == ELFCLASS32) - scn->s_shdr.s_shdr32.sh_size = shnum; - else - scn->s_shdr.s_shdr64.sh_size = shnum; - - (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); - - shnum = 0; - } - - if (ec == ELFCLASS32) - ((Elf32_Ehdr *) eh)->e_shnum = shnum; - else - ((Elf64_Ehdr *) eh)->e_shnum = shnum; - - - return (1); -} - -int -_libelf_setshstrndx(Elf *e, void *eh, int ec, size_t shstrndx) -{ - Elf_Scn *scn; - - if (shstrndx >= SHN_LORESERVE) { - if ((scn = _libelf_getscn0(e)) == NULL) - return (0); - - assert(scn->s_ndx == SHN_UNDEF); - - if (ec == ELFCLASS32) - scn->s_shdr.s_shdr32.sh_link = shstrndx; - else - scn->s_shdr.s_shdr64.sh_link = shstrndx; - - (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); - - shstrndx = SHN_XINDEX; - } - - if (ec == ELFCLASS32) - ((Elf32_Ehdr *) eh)->e_shstrndx = shstrndx; - else - ((Elf64_Ehdr *) eh)->e_shstrndx = shstrndx; - - return (1); -} - -int -_libelf_setphnum(Elf *e, void *eh, int ec, size_t phnum) -{ - Elf_Scn *scn; - - if (phnum >= PN_XNUM) { - if ((scn = _libelf_getscn0(e)) == NULL) - return (0); - - assert(scn->s_ndx == SHN_UNDEF); - - if (ec == ELFCLASS32) - scn->s_shdr.s_shdr32.sh_info = phnum; - else - scn->s_shdr.s_shdr64.sh_info = phnum; - - (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); - - phnum = PN_XNUM; - } - - if (ec == ELFCLASS32) - ((Elf32_Ehdr *) eh)->e_phnum = phnum; - else - ((Elf64_Ehdr *) eh)->e_phnum = phnum; - - return (1); -} diff --git a/src/libelf/libelf_fsize.c b/src/libelf/libelf_fsize.c deleted file mode 100644 index 11ced8c..0000000 --- a/src/libelf/libelf_fsize.c +++ /dev/null @@ -1,197 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: elf_types.m4 321 2009-03-07 16:59:14Z jkoshy $ - */ - -/* - * ELF types, defined in the "enum Elf_Type" API. - * - * The members of the list form a 2-tuple: (name, C-type-suffix). - * + name is an Elf_Type symbol without the ELF_T_ prefix. - * + C-type-suffix is the suffix for Elf32_ and Elf64_ type names. - */ - - - -/* - * DEFINE_STRUCT(NAME,MEMBERLIST...) - * - * Map a type name to its members. - * - * Each member-list element comprises of pairs of (field name, type), - * in the sequence used in the file representation of NAME. - * - * Each member list element comprises a pair containing a field name - * and a basic type. Basic types include IDENT, HALF, WORD, LWORD, - * ADDR{32,64}, OFF{32,64}, SWORD, XWORD, SXWORD. - * - * The last element of a member list is the null element: _,_. - */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -/*- - * Copyright (c) 2006,2008-2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: libelf_fsize.m4 2225 2011-11-26 18:55:54Z jkoshy $"); - -/* WARNING: GENERATED FROM libelf_fsize.m4. */ - -/* - * Create an array of file sizes from the elf_type definitions - */ - - - -struct fsize { - size_t fsz32; - size_t fsz64; -}; - -static struct fsize fsize[ELF_T_NUM] = { -[ELF_T_ADDR] = { .fsz32 = sizeof(Elf32_Addr), .fsz64 = sizeof(Elf64_Addr) }, - -[ELF_T_BYTE] = { .fsz32 = 1, .fsz64 = 1 }, - -[ELF_T_CAP] = { .fsz32 = sizeof(Elf32_Word)+sizeof(Elf32_Word)+0, .fsz64 = sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+0 }, - -[ELF_T_DYN] = { .fsz32 = sizeof(Elf32_Sword)+sizeof(Elf32_Word)+0, .fsz64 = sizeof(Elf64_Sxword)+sizeof(Elf64_Xword)+0 }, - -[ELF_T_EHDR] = { .fsz32 = EI_NIDENT+sizeof(Elf32_Half)+sizeof(Elf32_Half)+sizeof(Elf32_Word)+sizeof(Elf32_Addr)+sizeof(Elf32_Off)+sizeof(Elf32_Off)+sizeof(Elf32_Word)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+0, .fsz64 = EI_NIDENT+sizeof(Elf64_Half)+sizeof(Elf64_Half)+sizeof(Elf64_Word)+sizeof(Elf64_Addr)+sizeof(Elf64_Off)+sizeof(Elf64_Off)+sizeof(Elf64_Word)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+0 }, - -[ELF_T_GNUHASH] = { .fsz32 = 1, .fsz64 = 1 }, - -[ELF_T_HALF] = { .fsz32 = sizeof(Elf32_Half), .fsz64 = sizeof(Elf64_Half) }, - -[ELF_T_LWORD] = { .fsz32 = sizeof(Elf32_Lword), .fsz64 = sizeof(Elf64_Lword) }, - -[ELF_T_MOVE] = { .fsz32 = sizeof(Elf32_Lword)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+0, .fsz64 = sizeof(Elf64_Lword)+sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+0 }, - -[ELF_T_MOVEP] = { .fsz32 = 0, .fsz64 = 0 }, - -[ELF_T_NOTE] = { .fsz32 = 1, .fsz64 = 1 }, - -[ELF_T_OFF] = { .fsz32 = sizeof(Elf32_Off), .fsz64 = sizeof(Elf64_Off) }, - -[ELF_T_PHDR] = { .fsz32 = sizeof(Elf32_Word)+sizeof(Elf32_Off)+sizeof(Elf32_Addr)+sizeof(Elf32_Addr)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+0, .fsz64 = sizeof(Elf64_Word)+sizeof(Elf64_Word)+sizeof(Elf64_Off)+sizeof(Elf64_Addr)+sizeof(Elf64_Addr)+sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+0 }, - -[ELF_T_REL] = { .fsz32 = sizeof(Elf32_Addr)+sizeof(Elf32_Word)+0, .fsz64 = sizeof(Elf64_Addr)+sizeof(Elf64_Xword)+0 }, - -[ELF_T_RELA] = { .fsz32 = sizeof(Elf32_Addr)+sizeof(Elf32_Word)+sizeof(Elf32_Sword)+0, .fsz64 = sizeof(Elf64_Addr)+sizeof(Elf64_Xword)+sizeof(Elf64_Sxword)+0 }, - -[ELF_T_SHDR] = { .fsz32 = sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Addr)+sizeof(Elf32_Off)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+0, .fsz64 = sizeof(Elf64_Word)+sizeof(Elf64_Word)+sizeof(Elf64_Xword)+sizeof(Elf64_Addr)+sizeof(Elf64_Off)+sizeof(Elf64_Xword)+sizeof(Elf64_Word)+sizeof(Elf64_Word)+sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+0 }, - -[ELF_T_SWORD] = { .fsz32 = sizeof(Elf32_Sword), .fsz64 = sizeof(Elf64_Sword) }, - -[ELF_T_SXWORD] = { .fsz32 = 0, .fsz64 = sizeof(Elf64_Sxword) }, - -[ELF_T_SYMINFO] = { .fsz32 = sizeof(Elf32_Half)+sizeof(Elf32_Half)+0, .fsz64 = sizeof(Elf64_Half)+sizeof(Elf64_Half)+0 }, - -[ELF_T_SYM] = { .fsz32 = sizeof(Elf32_Word)+sizeof(Elf32_Addr)+sizeof(Elf32_Word)+1+1+sizeof(Elf32_Half)+0, .fsz64 = sizeof(Elf64_Word)+1+1+sizeof(Elf64_Half)+sizeof(Elf64_Addr)+sizeof(Elf64_Xword)+0 }, - -[ELF_T_VDEF] = { .fsz32 = 1, .fsz64 = 1 }, - -[ELF_T_VNEED] = { .fsz32 = 1, .fsz64 = 1 }, - -[ELF_T_WORD] = { .fsz32 = sizeof(Elf32_Word), .fsz64 = sizeof(Elf64_Word) }, - -[ELF_T_XWORD] = { .fsz32 = 0, .fsz64 = sizeof(Elf64_Xword) }, - - -}; - -size_t -_libelf_fsize(Elf_Type t, int ec, unsigned int v, size_t c) -{ - size_t sz; - - sz = 0; - if (v != EV_CURRENT) - LIBELF_SET_ERROR(VERSION, 0); - else if ((int) t < ELF_T_FIRST || t > ELF_T_LAST) - LIBELF_SET_ERROR(ARGUMENT, 0); - else { - sz = ec == ELFCLASS64 ? fsize[t].fsz64 : fsize[t].fsz32; - if (sz == 0) - LIBELF_SET_ERROR(UNIMPL, 0); - } - - return (sz*c); -} diff --git a/src/libelf/libelf_memory.c b/src/libelf/libelf_memory.c deleted file mode 100644 index 892e909..0000000 --- a/src/libelf/libelf_memory.c +++ /dev/null @@ -1,96 +0,0 @@ -/*- - * Copyright (c) 2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: libelf_memory.c 2368 2011-12-29 06:34:28Z jkoshy $"); - -/* - * Create an ELF descriptor for a memory image, optionally reporting - * parse errors. - */ - -Elf * -_libelf_memory(char *image, size_t sz, int reporterror) -{ - Elf *e; - int e_class; - enum Elf_Error error; - unsigned int e_byteorder, e_version; - - assert(image != NULL); - assert(sz > 0); - - if ((e = _libelf_allocate_elf()) == NULL) - return (NULL); - - e->e_cmd = ELF_C_READ; - e->e_rawfile = image; - e->e_rawsize = sz; - -#undef LIBELF_IS_ELF -#define LIBELF_IS_ELF(P) ((P)[EI_MAG0] == ELFMAG0 && \ - (P)[EI_MAG1] == ELFMAG1 && (P)[EI_MAG2] == ELFMAG2 && \ - (P)[EI_MAG3] == ELFMAG3) - - if (sz > EI_NIDENT && LIBELF_IS_ELF(image)) { - e_byteorder = image[EI_DATA]; - e_class = image[EI_CLASS]; - e_version = image[EI_VERSION]; - - error = ELF_E_NONE; - - if (e_version > EV_CURRENT) - error = ELF_E_VERSION; - else if ((e_byteorder != ELFDATA2LSB && e_byteorder != - ELFDATA2MSB) || (e_class != ELFCLASS32 && e_class != - ELFCLASS64)) - error = ELF_E_HEADER; - - if (error != ELF_E_NONE) { - if (reporterror) { - LIBELF_PRIVATE(error) = LIBELF_ERROR(error, 0); - (void) _libelf_release_elf(e); - return (NULL); - } - } else { - _libelf_init_elf(e, ELF_K_ELF); - - e->e_byteorder = e_byteorder; - e->e_class = e_class; - e->e_version = e_version; - } - } else if (sz >= SARMAG && - strncmp(image, ARMAG, (size_t) SARMAG) == 0) - return (_libelf_ar_open(e, reporterror)); - - return (e); -} diff --git a/src/libelf/libelf_msize.c b/src/libelf/libelf_msize.c deleted file mode 100644 index 029a9e1..0000000 --- a/src/libelf/libelf_msize.c +++ /dev/null @@ -1,196 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: elf_types.m4 321 2009-03-07 16:59:14Z jkoshy $ - */ - -/* - * ELF types, defined in the "enum Elf_Type" API. - * - * The members of the list form a 2-tuple: (name, C-type-suffix). - * + name is an Elf_Type symbol without the ELF_T_ prefix. - * + C-type-suffix is the suffix for Elf32_ and Elf64_ type names. - */ - - - -/* - * DEFINE_STRUCT(NAME,MEMBERLIST...) - * - * Map a type name to its members. - * - * Each member-list element comprises of pairs of (field name, type), - * in the sequence used in the file representation of NAME. - * - * Each member list element comprises a pair containing a field name - * and a basic type. Basic types include IDENT, HALF, WORD, LWORD, - * ADDR{32,64}, OFF{32,64}, SWORD, XWORD, SXWORD. - * - * The last element of a member list is the null element: _,_. - */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -/*- - * Copyright (c) 2006,2008-2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: libelf_msize.m4 2225 2011-11-26 18:55:54Z jkoshy $"); - -/* WARNING: GENERATED FROM libelf_msize.m4. */ - -struct msize { - size_t msz32; - size_t msz64; -}; - - - -static struct msize msize[ELF_T_NUM] = { -[ELF_T_ADDR] = { .msz32 = sizeof(Elf32_Addr), .msz64 = sizeof(Elf64_Addr) }, - -[ELF_T_BYTE] = { .msz32 = 1, .msz64 = 1 }, - -[ELF_T_CAP] = { .msz32 = sizeof(Elf32_Cap), .msz64 = sizeof(Elf64_Cap) }, - -[ELF_T_DYN] = { .msz32 = sizeof(Elf32_Dyn), .msz64 = sizeof(Elf64_Dyn) }, - -[ELF_T_EHDR] = { .msz32 = sizeof(Elf32_Ehdr), .msz64 = sizeof(Elf64_Ehdr) }, - -[ELF_T_GNUHASH] = { .msz32 = 1, .msz64 = 1 }, - -[ELF_T_HALF] = { .msz32 = sizeof(Elf32_Half), .msz64 = sizeof(Elf64_Half) }, - -[ELF_T_LWORD] = { .msz32 = sizeof(Elf32_Lword), .msz64 = sizeof(Elf64_Lword) }, - -[ELF_T_MOVE] = { .msz32 = sizeof(Elf32_Move), .msz64 = sizeof(Elf64_Move) }, - -[ELF_T_MOVEP] = { .msz32 = 0, .msz64 = 0 }, - -[ELF_T_NOTE] = { .msz32 = 1, .msz64 = 1 }, - -[ELF_T_OFF] = { .msz32 = sizeof(Elf32_Off), .msz64 = sizeof(Elf64_Off) }, - -[ELF_T_PHDR] = { .msz32 = sizeof(Elf32_Phdr), .msz64 = sizeof(Elf64_Phdr) }, - -[ELF_T_REL] = { .msz32 = sizeof(Elf32_Rel), .msz64 = sizeof(Elf64_Rel) }, - -[ELF_T_RELA] = { .msz32 = sizeof(Elf32_Rela), .msz64 = sizeof(Elf64_Rela) }, - -[ELF_T_SHDR] = { .msz32 = sizeof(Elf32_Shdr), .msz64 = sizeof(Elf64_Shdr) }, - -[ELF_T_SWORD] = { .msz32 = sizeof(Elf32_Sword), .msz64 = sizeof(Elf64_Sword) }, - -[ELF_T_SXWORD] = { .msz32 = 0, .msz64 = sizeof(Elf64_Sxword) }, - -[ELF_T_SYMINFO] = { .msz32 = sizeof(Elf32_Syminfo), .msz64 = sizeof(Elf64_Syminfo) }, - -[ELF_T_SYM] = { .msz32 = sizeof(Elf32_Sym), .msz64 = sizeof(Elf64_Sym) }, - -[ELF_T_VDEF] = { .msz32 = 1, .msz64 = 1 }, - -[ELF_T_VNEED] = { .msz32 = 1, .msz64 = 1 }, - -[ELF_T_WORD] = { .msz32 = sizeof(Elf32_Word), .msz64 = sizeof(Elf64_Word) }, - -[ELF_T_XWORD] = { .msz32 = 0, .msz64 = sizeof(Elf64_Xword) }, - - -}; - -size_t -_libelf_msize(Elf_Type t, int elfclass, unsigned int version) -{ - size_t sz; - - assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); - assert((signed) t >= ELF_T_FIRST && t <= ELF_T_LAST); - - if (version != EV_CURRENT) { - LIBELF_SET_ERROR(VERSION, 0); - return (0); - } - - sz = (elfclass == ELFCLASS32) ? msize[t].msz32 : msize[t].msz64; - - return (sz); -} diff --git a/src/libelf/libelf_open.c b/src/libelf/libelf_open.c deleted file mode 100644 index 0c60aa0..0000000 --- a/src/libelf/libelf_open.c +++ /dev/null @@ -1,240 +0,0 @@ -/*- - * Copyright (c) 2006,2008-2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include - -#include -#include -#include -#include -#include - -#include "_libelf.h" - -#if ELFTC_HAVE_MMAP -#include -#endif - -ELFTC_VCSID("$Id: libelf_open.c 2364 2011-12-28 17:55:25Z jkoshy $"); - -#define _LIBELF_INITSIZE (64*1024) - -/* - * Read from a device file, pipe or socket. - */ -static void * -_libelf_read_special_file(int fd, size_t *fsz) -{ - ssize_t readsz; - size_t bufsz, datasz; - unsigned char *buf, *t; - - datasz = 0; - readsz = 0; - bufsz = _LIBELF_INITSIZE; - if ((buf = malloc(bufsz)) == NULL) - goto resourceerror; - - /* - * Read data from the file descriptor till we reach EOF, or - * till an error is encountered. - */ - do { - /* Check if we need to expand the data buffer. */ - if (datasz == bufsz) { - bufsz *= 2; - if ((t = realloc(buf, bufsz)) == NULL) - goto resourceerror; - buf = t; - } - - do { - readsz = bufsz - datasz; - t = buf + datasz; - if ((readsz = read(fd, t, readsz)) <= 0) - break; - datasz += readsz; - } while (datasz < bufsz); - - } while (readsz > 0); - - if (readsz < 0) { - LIBELF_SET_ERROR(IO, errno); - goto error; - } - - assert(readsz == 0); - - /* - * Free up extra buffer space. - */ - if (bufsz > datasz) { - if (datasz > 0) { - if ((t = realloc(buf, datasz)) == NULL) - goto resourceerror; - buf = t; - } else { /* Zero bytes read. */ - LIBELF_SET_ERROR(ARGUMENT, 0); - free(buf); - buf = NULL; - } - } - - *fsz = datasz; - return (buf); - -resourceerror: - LIBELF_SET_ERROR(RESOURCE, 0); -error: - if (buf != NULL) - free(buf); - return (NULL); -} - -/* - * Read the contents of the file referenced by the file descriptor - * 'fd'. - */ - -Elf * -_libelf_open_object(int fd, Elf_Cmd c, int reporterror) -{ - Elf *e; - void *m; - mode_t mode; - size_t fsize; - struct stat sb; - unsigned int flags; - - assert(c == ELF_C_READ || c == ELF_C_RDWR || c == ELF_C_WRITE); - - if (fstat(fd, &sb) < 0) { - LIBELF_SET_ERROR(IO, errno); - return (NULL); - } - - mode = sb.st_mode; - fsize = (size_t) sb.st_size; - - /* - * Reject unsupported file types. - */ - if (!S_ISREG(mode) && !S_ISCHR(mode) && !S_ISFIFO(mode) && - !S_ISSOCK(mode)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - /* - * For ELF_C_WRITE mode, allocate and return a descriptor. - */ - if (c == ELF_C_WRITE) { - if ((e = _libelf_allocate_elf()) != NULL) { - _libelf_init_elf(e, ELF_K_ELF); - e->e_byteorder = LIBELF_PRIVATE(byteorder); - e->e_fd = fd; - e->e_cmd = c; - if (!S_ISREG(mode)) - e->e_flags |= LIBELF_F_SPECIAL_FILE; - } - - return (e); - } - - - /* - * ELF_C_READ and ELF_C_RDWR mode. - */ - m = NULL; - flags = 0; - if (S_ISREG(mode)) { -#if ELFTC_HAVE_MMAP - /* - * Always map regular files in with 'PROT_READ' - * permissions. - * - * For objects opened in ELF_C_RDWR mode, when - * elf_update(3) is called, we remove this mapping, - * write file data out using write(2), and map the new - * contents back. - */ - m = mmap(NULL, fsize, PROT_READ, MAP_PRIVATE, fd, (off_t) 0); - - if (m == MAP_FAILED) - m = NULL; - else - flags = LIBELF_F_RAWFILE_MMAP; -#endif - - /* - * Fallback to a read() if the call to mmap() failed, - * or if mmap() is not available. - */ - if (m == NULL) { - if ((m = malloc(fsize)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - if (read(fd, m, fsize) != (ssize_t) fsize) { - LIBELF_SET_ERROR(IO, errno); - free(m); - return (NULL); - } - - flags = LIBELF_F_RAWFILE_MALLOC; - } - } else if ((m = _libelf_read_special_file(fd, &fsize)) != NULL) - flags = LIBELF_F_RAWFILE_MALLOC | LIBELF_F_SPECIAL_FILE; - else - return (NULL); - - if ((e = _libelf_memory(m, fsize, reporterror)) == NULL) { - assert((flags & LIBELF_F_RAWFILE_MALLOC) || - (flags & LIBELF_F_RAWFILE_MMAP)); - if (flags & LIBELF_F_RAWFILE_MALLOC) - free(m); -#if ELFTC_HAVE_MMAP - else - (void) munmap(m, fsize); -#endif - return (NULL); - } - - /* ar(1) archives aren't supported in RDWR mode. */ - if (c == ELF_C_RDWR && e->e_kind == ELF_K_AR) { - (void) elf_end(e); - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - e->e_flags |= flags; - e->e_fd = fd; - e->e_cmd = c; - - return (e); -} diff --git a/src/libelf/libelf_phdr.c b/src/libelf/libelf_phdr.c deleted file mode 100644 index ace37ca..0000000 --- a/src/libelf/libelf_phdr.c +++ /dev/null @@ -1,156 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include "gelf.h" -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: libelf_phdr.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -void * -_libelf_getphdr(Elf *e, int ec) -{ - size_t phnum, phentsize; - size_t fsz, msz; - uint64_t phoff; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - void *ehdr, *phdr; - int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); - - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((phdr = (ec == ELFCLASS32 ? - (void *) e->e_u.e_elf.e_phdr.e_phdr32 : - (void *) e->e_u.e_elf.e_phdr.e_phdr64)) != NULL) - return (phdr); - - /* - * Check the PHDR related fields in the EHDR for sanity. - */ - - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) - return (NULL); - - phnum = e->e_u.e_elf.e_nphdr; - - if (ec == ELFCLASS32) { - eh32 = (Elf32_Ehdr *) ehdr; - phentsize = eh32->e_phentsize; - phoff = (uint64_t) eh32->e_phoff; - } else { - eh64 = (Elf64_Ehdr *) ehdr; - phentsize = eh64->e_phentsize; - phoff = (uint64_t) eh64->e_phoff; - } - - fsz = gelf_fsize(e, ELF_T_PHDR, phnum, e->e_version); - - assert(fsz > 0); - - if ((uint64_t) e->e_rawsize < (phoff + fsz)) { - LIBELF_SET_ERROR(HEADER, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_PHDR, ec, EV_CURRENT); - - assert(msz > 0); - - if ((phdr = calloc(phnum, msz)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - if (ec == ELFCLASS32) - e->e_u.e_elf.e_phdr.e_phdr32 = phdr; - else - e->e_u.e_elf.e_phdr.e_phdr64 = phdr; - - - xlator = _libelf_get_translator(ELF_T_PHDR, ELF_TOMEMORY, ec); - (*xlator)(phdr, phnum * msz, e->e_rawfile + phoff, phnum, - e->e_byteorder != LIBELF_PRIVATE(byteorder)); - - return (phdr); -} - -void * -_libelf_newphdr(Elf *e, int ec, size_t count) -{ - void *ehdr, *newphdr, *oldphdr; - size_t msz; - - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) { - LIBELF_SET_ERROR(SEQUENCE, 0); - return (NULL); - } - - assert(e->e_class == ec); - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - assert(e->e_version == EV_CURRENT); - - msz = _libelf_msize(ELF_T_PHDR, ec, e->e_version); - - assert(msz > 0); - - newphdr = NULL; - if (count > 0 && (newphdr = calloc(count, msz)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - if ((oldphdr = (void *) e->e_u.e_elf.e_phdr.e_phdr32) != NULL) - free(oldphdr); - e->e_u.e_elf.e_phdr.e_phdr32 = (Elf32_Phdr *) newphdr; - } else { - if ((oldphdr = (void *) e->e_u.e_elf.e_phdr.e_phdr64) != NULL) - free(oldphdr); - e->e_u.e_elf.e_phdr.e_phdr64 = (Elf64_Phdr *) newphdr; - } - - e->e_u.e_elf.e_nphdr = count; - - elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY); - - return (newphdr); -} diff --git a/src/libelf/libelf_shdr.c b/src/libelf/libelf_shdr.c deleted file mode 100644 index 582d550..0000000 --- a/src/libelf/libelf_shdr.c +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include "gelf.h" -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: libelf_shdr.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -void * -_libelf_getshdr(Elf_Scn *s, int ec) -{ - Elf *e; - - if (s == NULL || (e = s->s_elf) == NULL || - e->e_kind != ELF_K_ELF) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASSNONE) - ec = e->e_class; - - if (ec != e->e_class) { - LIBELF_SET_ERROR(CLASS, 0); - return (NULL); - } - - return ((void *) &s->s_shdr); -} diff --git a/src/libelf/libelf_xlate.c b/src/libelf/libelf_xlate.c deleted file mode 100644 index eda6df8..0000000 --- a/src/libelf/libelf_xlate.c +++ /dev/null @@ -1,150 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -ELFTC_VCSID("$Id: libelf_xlate.c 2225 2011-11-26 18:55:54Z jkoshy $"); - -/* - * Translate to/from the file representation of ELF objects. - * - * Translation could potentially involve the following - * transformations: - * - * - an endianness conversion, - * - a change of layout, as the file representation of ELF objects - * can differ from their in-memory representation. - * - a change in representation due to a layout version change. - */ - -Elf_Data * -_libelf_xlate(Elf_Data *dst, const Elf_Data *src, unsigned int encoding, - int elfclass, int direction) -{ - int byteswap; - size_t cnt, dsz, fsz, msz; - uintptr_t sb, se, db, de; - - if (encoding == ELFDATANONE) - encoding = LIBELF_PRIVATE(byteorder); - - if ((encoding != ELFDATA2LSB && encoding != ELFDATA2MSB) || - dst == NULL || src == NULL || dst == src) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); - assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY); - - if (dst->d_version != src->d_version) { - LIBELF_SET_ERROR(UNIMPL, 0); - return (NULL); - } - - if (src->d_buf == NULL || dst->d_buf == NULL) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - if ((int) src->d_type < 0 || src->d_type >= ELF_T_NUM) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize) - (src->d_type, (size_t) 1, src->d_version)) == 0) - return (NULL); - - msz = _libelf_msize(src->d_type, elfclass, src->d_version); - - assert(msz > 0); - - if (src->d_size % (direction == ELF_TOMEMORY ? fsz : msz)) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - /* - * Determine the number of objects that need to be converted, and - * the space required for the converted objects in the destination - * buffer. - */ - if (direction == ELF_TOMEMORY) { - cnt = src->d_size / fsz; - dsz = cnt * msz; - } else { - cnt = src->d_size / msz; - dsz = cnt * fsz; - } - - if (dst->d_size < dsz) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - sb = (uintptr_t) src->d_buf; - se = sb + src->d_size; - db = (uintptr_t) dst->d_buf; - de = db + dst->d_size; - - /* - * Check for overlapping buffers. Note that db == sb is - * allowed. - */ - if (db != sb && de > sb && se > db) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - if ((direction == ELF_TOMEMORY ? db : sb) % - _libelf_malign(src->d_type, elfclass)) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - dst->d_type = src->d_type; - dst->d_size = dsz; - - byteswap = encoding != LIBELF_PRIVATE(byteorder); - - if (src->d_size == 0 || - (db == sb && !byteswap && fsz == msz)) - return (dst); /* nothing more to do */ - - if (!(_libelf_get_translator(src->d_type, direction, elfclass)) - (dst->d_buf, dsz, src->d_buf, cnt, byteswap)) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - return (dst); -} diff --git a/src/link.ld b/src/link.ld deleted file mode 100644 index 1e90467..0000000 --- a/src/link.ld +++ /dev/null @@ -1,33 +0,0 @@ -OUTPUT(loader.elf); - -ENTRY(_start); - -SECTIONS { - . = 0x00800000; - .text : { - *(.kernel_code*); - *(.text*); - /* Tell linker to not garbage collect this section as it is not referenced anywhere */ - KEEP(*(.kernel_code*)); - } - .sdata : { - *(.sdata*) - } - .data : { - *(.data*) - } - .rodata : { - *(.rodata*) - } - .sbss : { - *(.sbss*) - } - .bss : { - *(.bss*) - } - /DISCARD/ : { - *(*); - } -} - -ASSERT((SIZEOF(.text) + SIZEOF(.data)) < 0x800000, "Memory overlapping with main elf."); diff --git a/src/memory/memory.cpp b/src/memory/memory.cpp deleted file mode 100644 index 674d645..0000000 --- a/src/memory/memory.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 Dimok - * - * 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 . - ****************************************************************************/ -#include -#include -#include "dynamic_libs/coreinit.h" -#include "memory_mapping.h" -#include "memory.h" - -//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -//! Memory functions -//! This is the only place where those are needed so lets keep them more or less private -//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -extern uint32_t * pMEMAllocFromDefaultHeapEx; -extern uint32_t * pMEMAllocFromDefaultHeap; -extern uint32_t * pMEMFreeToDefaultHeap; - -int32_t memHandle __attribute__((section(".data"))) = -1; - -void initMemory() { - memHandle = MEMCreateExpHeapEx((void*)MemoryMapping::getHeapAddress(), MemoryMapping::getHeapSize(), 0); -} - - - -//!------------------------------------------------------------------------------------------- -//! wraps -//!------------------------------------------------------------------------------------------- -extern "C" void *__wrap_malloc(size_t size) { - if(memHandle == -1) { - return ((void * (*)(size_t))(*pMEMAllocFromDefaultHeap))(size); - } - // pointer to a function resolve - return MEMAllocFromExpHeapEx(memHandle, size, 0x40); -} - -extern "C" void *__wrap_memalign(size_t align, size_t size) { - if(memHandle == -1) { - return ((void * (*)(size_t, size_t))(*pMEMAllocFromDefaultHeapEx))(size, align); - } - if (align < 4) - align = 4; - - // pointer to a function resolve - return MEMAllocFromExpHeapEx(memHandle, size, align); -} - -extern "C" void __wrap_free(void *p) { - if(memHandle == -1) { - //OSFatal("__wrap_free"); - if(p != 0) { - ((void (*)(void *))(*pMEMFreeToDefaultHeap))(p); - } - return; - } - // pointer to a function resolve - if(p != 0) { - MEMFreeToExpHeap(memHandle,p); - } -} - -extern "C" void *__wrap_calloc(size_t n, size_t size) { - void *p = __wrap_malloc(n * size); - if (p != 0) { - memset(p, 0, n * size); - } - return p; -} - -extern "C" size_t __wrap_malloc_usable_size(void *p) { - //! TODO: this is totally wrong and needs to be addressed - return 0x7FFFFFFF; -} - -extern "C" void *__wrap_realloc(void *ptr, size_t size) { - void *newPtr; - - if (!ptr) { - newPtr = __wrap_malloc(size); - if (!newPtr) { - goto error; - } - } else { - newPtr = __wrap_malloc(size); - if (!newPtr) { - goto error; - } - - memcpy(newPtr, ptr, size); - - __wrap_free(ptr); - } - - return newPtr; -error: - return NULL; -} - -//!------------------------------------------------------------------------------------------- -//! reent versions -//!------------------------------------------------------------------------------------------- -extern "C" void *__wrap__malloc_r(struct _reent *r, size_t size) { - return __wrap_malloc(size); -} - -extern "C" void *__wrap__calloc_r(struct _reent *r, size_t n, size_t size) { - return __wrap_calloc(n, size); -} - -extern "C" void *__wrap__memalign_r(struct _reent *r, size_t align, size_t size) { - return __wrap_memalign(align, size); -} - -extern "C" void __wrap__free_r(struct _reent *r, void *p) { - __wrap_free(p); -} - -extern "C" size_t __wrap__malloc_usable_size_r(struct _reent *r, void *p) { - return __wrap_malloc_usable_size(p); -} - -extern "C" void *__wrap__realloc_r(struct _reent *r, void *p, size_t size) { - return __wrap_realloc(p, size); -} diff --git a/src/memory/memory_mapping.cpp b/src/memory/memory_mapping.cpp deleted file mode 100644 index ea75f36..0000000 --- a/src/memory/memory_mapping.cpp +++ /dev/null @@ -1,770 +0,0 @@ -#include "memory_mapping.h" -#include "kernel/kernel_utils.h" - -#include -#include "dynamic_libs/coreinit.h" -#include "system/CThread.h" -#include "memory.h" -#include -#include - -#define DEBUG_FUNCTION_LINE(x,...) - -void runOnAllCores(CThread::Callback callback, void *callbackArg, int32_t iAttr = 0, int32_t iPriority = 16, int32_t iStackSize = 0x8000) { - int32_t aff[] = {CThread::eAttributeAffCore2,CThread::eAttributeAffCore1,CThread::eAttributeAffCore0}; - - for(uint32_t i = 0; i <(sizeof(aff)/sizeof(aff[0])); i++) { - CThread * thread = CThread::create(callback, callbackArg, iAttr | aff[i],iPriority,iStackSize); - thread->resumeThread(); - delete thread; - } -} - -void writeSegmentRegister(CThread *thread, void *arg) { - sr_table_t * table = (sr_table_t *) arg; - uint16_t core = OSGetThreadAffinity(OSGetCurrentThread()); - DEBUG_FUNCTION_LINE("Writing segment register to core %d\n",core); - - DCFlushRange(table,sizeof(sr_table_t)); - SC0x0A_KernelWriteSRs(table); -} - -void readAndPrintSegmentRegister(CThread *thread, void *arg) { - uint16_t core = OSGetThreadAffinity(OSGetCurrentThread()); - DEBUG_FUNCTION_LINE("Reading segment register and page table from core %d\n",core); - sr_table_t srTable; - memset(&srTable,0,sizeof(srTable)); - - SC0x36_KernelReadSRs(&srTable); - DCFlushRange(&srTable,sizeof(srTable)); - - for(int32_t i = 0; i < 16; i++) { - DEBUG_FUNCTION_LINE("[%d] SR[%d]=%08X\n",core,i,srTable.value[i]); - } - - uint32_t pageTable[0x8000]; - - memset(pageTable,0,sizeof(pageTable)); - DEBUG_FUNCTION_LINE("Reading pageTable now.\n"); - KernelReadPTE((uint32_t) pageTable,sizeof(pageTable)); - DCFlushRange(pageTable,sizeof(pageTable)); - DEBUG_FUNCTION_LINE("Reading pageTable done\n"); - - MemoryMapping::printPageTableTranslation(srTable,pageTable); - - DEBUG_FUNCTION_LINE("-----------------------------\n"); -} - -bool MemoryMapping::isMemoryMapped() { - sr_table_t srTable; - memset(&srTable,0,sizeof(srTable)); - - SC0x36_KernelReadSRs(&srTable); - if((srTable.value[MEMORY_START_BASE >> 28] & 0x00FFFFFF) == SEGMENT_UNIQUE_ID) { - return true; - } - return false; -} - -uint32_t MemoryMapping::getHeapAddress() { - return MEMORY_START_PLUGIN_HEAP; -} - -uint32_t MemoryMapping::getHeapSize() { - return getAreaSizeFromPageTable(MEMORY_START_PLUGIN_HEAP,MEMORY_START_PLUGIN_HEAP_END - MEMORY_START_PLUGIN_HEAP); -} - -uint32_t MemoryMapping::getVideoMemoryAddress() { - return MEMORY_START_VIDEO_SPACE; -} - -uint32_t MemoryMapping::getVideoMemorySize() { - return getAreaSizeFromPageTable(MEMORY_START_VIDEO_SPACE,MEMORY_START_VIDEO_SPACE_END - MEMORY_START_VIDEO_SPACE); -} - -uint32_t MemoryMapping::getPluginSpaceMemoryAddress() { - return MEMORY_START_PLUGIN_SPACE; -} - -uint32_t MemoryMapping::getPluginSpaceMemorySize() { - return getAreaSizeFromPageTable(MEMORY_START_PLUGIN_SPACE,MEMORY_START_PLUGIN_SPACE_END - MEMORY_START_PLUGIN_SPACE); -} - -void MemoryMapping::searchEmptyMemoryRegions() { - DEBUG_FUNCTION_LINE("Searching for empty memory.\n"); - - for(int32_t i = 0;; i++) { - if(mem_mapping[i].physical_addresses == NULL) { - break; - } - uint32_t ea_start_address = mem_mapping[i].effective_start_address; - - const memory_values_t * mem_vals = mem_mapping[i].physical_addresses; - - uint32_t ea_size = 0; - for(uint32_t j = 0;; j++) { - uint32_t pa_start_address = mem_vals[j].start_address; - uint32_t pa_end_address = mem_vals[j].end_address; - if(pa_end_address == 0 && pa_start_address == 0) { - break; - } - ea_size += pa_end_address - pa_start_address; - } - - uint32_t* flush_start = (uint32_t*)ea_start_address; - uint32_t flush_size = ea_size; - - DEBUG_FUNCTION_LINE("Flushing %08X (%d kB) at %08X.\n",flush_size,flush_size/1024, flush_start); - DCFlushRange(flush_start,flush_size); - - DEBUG_FUNCTION_LINE("Searching in memory region %d. 0x%08X - 0x%08X. Size 0x%08X (%d KBytes).\n",i+1,ea_start_address,ea_start_address+ea_size,ea_size,ea_size/1024); - bool success = true; - uint32_t * memory_ptr = (uint32_t*) ea_start_address; - bool inFailRange = false; - uint32_t startFailing = 0; - uint32_t startGood = ea_start_address; - for(uint32_t j=0; j < ea_size/4; j++) { - if(memory_ptr[j] != 0) { - success = false; - if(!success && !inFailRange) { - if((((uint32_t)&memory_ptr[j])-(uint32_t)startGood)/1024 > 512) { - uint32_t start_addr = startGood & 0xFFFE0000; - if(start_addr != startGood) { - start_addr += 0x20000; - } - uint32_t end_addr = ((uint32_t)&memory_ptr[j]) - MEMORY_START_BASE; - end_addr = (end_addr & 0xFFFE0000); - DEBUG_FUNCTION_LINE("+ Free between 0x%08X and 0x%08X size: %u kB\n",start_addr - MEMORY_START_BASE,end_addr,(((uint32_t)end_addr)-((uint32_t)startGood - MEMORY_START_BASE))/1024); - } - startFailing = (uint32_t)&memory_ptr[j]; - inFailRange = true; - startGood = 0; - j = ((j & 0xFFFF8000) + 0x00008000)-1; - } - //break; - } else { - if(inFailRange) { - //DEBUG_FUNCTION_LINE("- Error between 0x%08X and 0x%08X size: %u kB\n",startFailing,&memory_ptr[j],(((uint32_t)&memory_ptr[j])-(uint32_t)startFailing)/1024); - startFailing = 0; - startGood = (uint32_t) &memory_ptr[j]; - inFailRange = false; - } - } - } - if(startGood != 0 && (startGood != ea_start_address + ea_size)) { - DEBUG_FUNCTION_LINE("+ Good between 0x%08X and 0x%08X size: %u kB\n",startGood - MEMORY_START_BASE,((uint32_t)(ea_start_address + ea_size) - (uint32_t)MEMORY_START_BASE),((uint32_t)(ea_start_address + ea_size) - (uint32_t)startGood)/1024); - } else if(inFailRange) { - DEBUG_FUNCTION_LINE("- Used between 0x%08X and 0x%08X size: %u kB\n",startFailing,ea_start_address + ea_size,((uint32_t)(ea_start_address + ea_size) - (uint32_t)startFailing)/1024); - } - if(success) { - DEBUG_FUNCTION_LINE("Test %d was successful!\n",i+1); - } - - } - DEBUG_FUNCTION_LINE("All tests done.\n"); -} - -void MemoryMapping::writeTestValuesToMemory() { - //don't smash the stack. - uint32_t chunk_size = 0x1000; - uint32_t testBuffer[chunk_size]; - - for(int32_t i = 0;; i++) { - if(mem_mapping[i].physical_addresses == NULL) { - break; - } - uint32_t cur_ea_start_address = mem_mapping[i].effective_start_address; - - DEBUG_FUNCTION_LINE("Preparing memory test for region %d. Region start at effective address %08X.\n",i+1,cur_ea_start_address); - - const memory_values_t * mem_vals = mem_mapping[i].physical_addresses; - uint32_t counter = 0; - for(uint32_t j = 0;; j++) { - uint32_t pa_start_address = mem_vals[j].start_address; - uint32_t pa_end_address = mem_vals[j].end_address; - if(pa_end_address == 0 && pa_start_address == 0) { - break; - } - uint32_t pa_size = pa_end_address - pa_start_address; - DEBUG_FUNCTION_LINE("Writing region %d of mapping %d. From %08X to %08X Size: %d KBytes...\n",j+1,i+1,pa_start_address,pa_end_address,pa_size/1024); - for(uint32_t k=0; k<=pa_size/4; k++) { - if(k > 0 && (k % chunk_size) == 0) { - DCFlushRange(&testBuffer,sizeof(testBuffer)); - DCInvalidateRange(&testBuffer,sizeof(testBuffer)); - uint32_t destination = pa_start_address + ((k*4) - sizeof(testBuffer)); - KernelCopyData(destination,(uint32_t)OSEffectiveToPhysical((uint32_t)testBuffer),sizeof(testBuffer)); - //DEBUG_FUNCTION_LINE("Copy testBuffer into %08X\n",destination); - } - if(k != pa_size/4) { - testBuffer[k % chunk_size] = counter++; - } - //DEBUG_FUNCTION_LINE("testBuffer[%d] = %d\n",i % chunk_size,i); - } - uint32_t* flush_start = (uint32_t*)cur_ea_start_address; - uint32_t flush_size = pa_size; - - cur_ea_start_address += pa_size; - - DEBUG_FUNCTION_LINE("Flushing %08X (%d kB) at %08X to map memory.\n",flush_size,flush_size/1024, flush_start); - DCFlushRange(flush_start,flush_size); - } - - DEBUG_FUNCTION_LINE("Done writing region %d\n",i+1); - } -} - -void MemoryMapping::readTestValuesFromMemory() { - DEBUG_FUNCTION_LINE("Testing reading the written values.\n"); - - for(int32_t i = 0;; i++) { - if(mem_mapping[i].physical_addresses == NULL) { - break; - } - uint32_t ea_start_address = mem_mapping[i].effective_start_address; - - const memory_values_t * mem_vals = mem_mapping[i].physical_addresses; - //uint32_t counter = 0; - uint32_t ea_size = 0; - for(uint32_t j = 0;; j++) { - uint32_t pa_start_address = mem_vals[j].start_address; - uint32_t pa_end_address = mem_vals[j].end_address; - if(pa_end_address == 0 && pa_start_address == 0) { - break; - } - ea_size += pa_end_address - pa_start_address; - } - - uint32_t* flush_start = (uint32_t*)ea_start_address; - uint32_t flush_size = ea_size; - - DEBUG_FUNCTION_LINE("Flushing %08X (%d kB) at %08X to map memory.\n",flush_size,flush_size/1024, flush_start); - DCFlushRange(flush_start,flush_size); - - DEBUG_FUNCTION_LINE("Testing memory region %d. 0x%08X - 0x%08X. Size 0x%08X (%d KBytes).\n",i+1,ea_start_address,ea_start_address+ea_size,ea_size,ea_size/1024); - bool success = true; - uint32_t * memory_ptr = (uint32_t*) ea_start_address; - bool inFailRange = false; - uint32_t startFailing = 0; - uint32_t startGood = ea_start_address; - for(uint32_t j=0; j < ea_size/4; j++) { - if(memory_ptr[j] != j) { - success = false; - if(!success && !inFailRange) { - DEBUG_FUNCTION_LINE("+ Good between 0x%08X and 0x%08X size: %u kB\n",startGood,&memory_ptr[j],(((uint32_t)&memory_ptr[j])-(uint32_t)startGood)/1024); - startFailing = (uint32_t)&memory_ptr[j]; - inFailRange = true; - startGood = 0; - j = ((j & 0xFFFF8000) + 0x00008000)-1; - } - //break; - } else { - if(inFailRange) { - DEBUG_FUNCTION_LINE("- Error between 0x%08X and 0x%08X size: %u kB\n",startFailing,&memory_ptr[j],(((uint32_t)&memory_ptr[j])-(uint32_t)startFailing)/1024); - startFailing = 0; - startGood = (uint32_t) &memory_ptr[j]; - inFailRange = false; - } - } - } - if(startGood != 0 && (startGood != ea_start_address + ea_size)) { - DEBUG_FUNCTION_LINE("+ Good between 0x%08X and 0x%08X size: %u kB\n",startGood,ea_start_address + ea_size,((uint32_t)(ea_start_address + ea_size) - (uint32_t)startGood)/1024); - } else if(inFailRange) { - DEBUG_FUNCTION_LINE("- Error between 0x%08X and 0x%08X size: %u kB\n",startFailing,ea_start_address + ea_size,((uint32_t)(ea_start_address + ea_size) - (uint32_t)startFailing)/1024); - } - if(success) { - DEBUG_FUNCTION_LINE("Test %d was successful!\n",i+1); - } - - } - DEBUG_FUNCTION_LINE("All tests done.\n"); -} - -void MemoryMapping::memoryMappingForRegions(const memory_mapping_t * memory_mapping, sr_table_t SRTable, uint32_t * translation_table) { - for(int32_t i = 0; /* waiting for a break */; i++) { - DEBUG_FUNCTION_LINE("In loop %d\n",i); - if(memory_mapping[i].physical_addresses == NULL) { - DEBUG_FUNCTION_LINE("break %d\n",i); - break; - } - uint32_t cur_ea_start_address = memory_mapping[i].effective_start_address; - - DEBUG_FUNCTION_LINE("Mapping area %d. effective address %08X...\n",i+1,cur_ea_start_address); - const memory_values_t * mem_vals = memory_mapping[i].physical_addresses; - - for(uint32_t j = 0;; j++) { - DEBUG_FUNCTION_LINE("In inner loop %d\n",j); - uint32_t pa_start_address = mem_vals[j].start_address; - uint32_t pa_end_address = mem_vals[j].end_address; - if(pa_end_address == 0 && pa_start_address == 0) { - DEBUG_FUNCTION_LINE("inner break %d\n",j); - // Break if entry was empty. - break; - } - uint32_t pa_size = pa_end_address - pa_start_address; - DEBUG_FUNCTION_LINE("Adding page table entry %d for mapping area %d. %08X-%08X => %08X-%08X...\n",j+1,i+1,cur_ea_start_address,memory_mapping[i].effective_start_address+pa_size,pa_start_address,pa_end_address); - if(!mapMemory(pa_start_address,pa_end_address,cur_ea_start_address,SRTable,translation_table)) { - //log_print("error =(\n"); - DEBUG_FUNCTION_LINE("Failed to map memory.\n"); - //OSFatal("Failed to map memory."); - return; - break; - } - cur_ea_start_address += pa_size; - //log_print("done\n"); - } - } -} - -void MemoryMapping::setupMemoryMapping() { - //runOnAllCores(readAndPrintSegmentRegister,NULL,0,16,0x80000); - - sr_table_t srTableCpy; - uint32_t pageTableCpy[0x8000]; - - SC0x36_KernelReadSRs(&srTableCpy); - KernelReadPTE((uint32_t) pageTableCpy,sizeof(pageTableCpy)); - - DCFlushRange(&srTableCpy,sizeof(srTableCpy)); - DCFlushRange(pageTableCpy,sizeof(pageTableCpy)); - - for(int32_t i = 0; i < 16; i++) { - DEBUG_FUNCTION_LINE("SR[%d]=%08X\n",i,srTableCpy.value[i]); - } - - //printPageTableTranslation(srTableCpy,pageTableCpy); - - // According to - // http://wiiubrew.org/wiki/Cafe_OS#Virtual_Memory_Map 0x80000000 - // is currently unmapped. - // This is nice because it leads to SR[8] which also seems to be unused (was set to 0x30FFFFFF) - // The content of the segment was chosen randomly. - uint32_t segment_index = MEMORY_START_BASE >> 28; - uint32_t segment_content = 0x00000000 | SEGMENT_UNIQUE_ID; - - DEBUG_FUNCTION_LINE("Setting SR[%d] to %08X\n",segment_index,segment_content); - srTableCpy.value[segment_index] = segment_content; - DCFlushRange(&srTableCpy,sizeof(srTableCpy)); - - DEBUG_FUNCTION_LINE("Writing segment registers...\n",segment_index,segment_content); - // Writing the segment registers to ALL cores. - // - //writeSegmentRegister(NULL, &srTableCpy); - - runOnAllCores(writeSegmentRegister,&srTableCpy); - - memoryMappingForRegions(mem_mapping,srTableCpy,pageTableCpy); - - - - //printPageTableTranslation(srTableCpy,pageTableCpy); - - DEBUG_FUNCTION_LINE("Writing PageTable... "); - DCFlushRange(pageTableCpy,sizeof(pageTableCpy)); - KernelWritePTE((uint32_t) pageTableCpy,sizeof(pageTableCpy)); - DCFlushRange(pageTableCpy,sizeof(pageTableCpy)); - DEBUG_FUNCTION_LINE("done\n"); - - //printPageTableTranslation(srTableCpy,pageTableCpy); - - //runOnAllCores(readAndPrintSegmentRegister,NULL,0,16,0x80000); - - //searchEmptyMemoryRegions(); - - //writeTestValuesToMemory(); - //readTestValuesFromMemory(); - - - //runOnAllCores(writeSegmentRegister,&srTableCpy); -} - - -uint32_t MemoryMapping::getAreaSizeFromPageTable(uint32_t start, uint32_t maxSize) { - sr_table_t srTable; - uint32_t pageTable[0x8000]; - - SC0x36_KernelReadSRs(&srTable); - KernelReadPTE((uint32_t) pageTable,sizeof(pageTable)); - - uint32_t sr_start = start >> 28; - uint32_t sr_end = (start + maxSize) >> 28; - - if(sr_end < sr_start) { - return 0; - } - - uint32_t cur_address = start; - uint32_t end_address = start + maxSize; - - uint32_t memSize = 0; - - for(uint32_t segment = sr_start; segment <= sr_end ; segment++) { - uint32_t sr = srTable.value[segment]; - if(sr >> 31) { - DEBUG_FUNCTION_LINE("Direct access not supported\n"); - } else { - uint32_t vsid = sr & 0xFFFFFF; - - uint32_t pageSize = 1 << PAGE_INDEX_SHIFT; - uint32_t cur_end_addr = 0; - if(segment == sr_end) { - cur_end_addr = end_address; - } else { - cur_end_addr = (segment + 1) * 0x10000000; - } - if(segment != sr_start) { - cur_address = (segment) * 0x10000000; - } - bool success = true; - for(uint32_t addr = cur_address; addr < cur_end_addr; addr += pageSize) { - uint32_t PTEH = 0; - uint32_t PTEL = 0; - if(getPageEntryForAddress(srTable.sdr1, addr, vsid, pageTable, &PTEH, &PTEL, false)) { - memSize += pageSize; - } else { - success = false; - break; - } - } - if(!success) { - break; - } - } - } - return memSize; -} - -bool MemoryMapping::getPageEntryForAddress(uint32_t SDR1,uint32_t addr, uint32_t vsid, uint32_t * translation_table,uint32_t* oPTEH, uint32_t* oPTEL, bool checkSecondHash) { - uint32_t pageMask = SDR1 & 0x1FF; - uint32_t pageIndex = (addr >> PAGE_INDEX_SHIFT) & PAGE_INDEX_MASK; - uint32_t primaryHash = (vsid & 0x7FFFF) ^ pageIndex; - - if(getPageEntryForAddressEx(SDR1, addr, vsid, primaryHash, translation_table, oPTEH, oPTEL, 0)) { - return true; - } - - if(checkSecondHash) { - if(getPageEntryForAddressEx(pageMask, addr, vsid, ~primaryHash, translation_table, oPTEH, oPTEL, 1)) { - return true; - } - } - - return false; -} - -bool MemoryMapping::getPageEntryForAddressEx(uint32_t pageMask, uint32_t addr, uint32_t vsid, uint32_t primaryHash, uint32_t * translation_table,uint32_t* oPTEH, uint32_t* oPTEL,uint32_t H) { - uint32_t maskedHash = primaryHash & ((pageMask << 10) | 0x3FF); - uint32_t api = (addr >> 22) & 0x3F; - - uint32_t pteAddrOffset = (maskedHash << 6); - - for (int32_t j = 0; j < 8; j++, pteAddrOffset += 8) { - uint32_t PTEH = 0; - uint32_t PTEL = 0; - - uint32_t pteh_index = pteAddrOffset / 4; - uint32_t ptel_index = pteh_index + 1; - - PTEH = translation_table[pteh_index]; - PTEL = translation_table[ptel_index]; - - //Check validity - if (!(PTEH >> 31)) { - //printf("PTE is not valid \n"); - continue; - } - //DEBUG_FUNCTION_LINE("in\n"); - // the H bit indicated if the PTE was found using the second hash. - if (((PTEH >> 6) & 1) != H) { - //DEBUG_FUNCTION_LINE("Secondary hash is used\n",((PTEH >> 6) & 1)); - continue; - } - - // Check if the VSID matches, otherwise this is a PTE for another SR - // This is the place where collision could happen. - // Hopefully no collision happen and only the PTEs of the SR will match. - if (((PTEH >> 7) & 0xFFFFFF) != vsid) { - //DEBUG_FUNCTION_LINE("VSID mismatch\n"); - continue; - } - - // Check the API (Abbreviated Page Index) - if ((PTEH & 0x3F) != api) { - //DEBUG_FUNCTION_LINE("API mismatch\n"); - continue; - } - *oPTEH = PTEH; - *oPTEL = PTEL; - - return true; - } - return false; -} - -void MemoryMapping::printPageTableTranslation(sr_table_t srTable, uint32_t * translation_table) { - uint32_t SDR1 = srTable.sdr1; - - pageInformation current; - memset(¤t,0,sizeof(current)); - - std::vector pageInfos; - - for(uint32_t segment = 0; segment < 16 ; segment++) { - uint32_t sr = srTable.value[segment]; - if(sr >> 31) { - DEBUG_FUNCTION_LINE("Direct access not supported\n"); - } else { - uint32_t ks = (sr >> 30) & 1; - uint32_t kp = (sr >> 29) & 1; - uint32_t nx = (sr >> 28) & 1; - uint32_t vsid = sr & 0xFFFFFF; - - DEBUG_FUNCTION_LINE("ks %08X kp %08X nx %08X vsid %08X\n",ks,kp,nx,vsid); - uint32_t pageSize = 1 << PAGE_INDEX_SHIFT; - for(uint32_t addr = segment * 0x10000000; addr < (segment + 1) * 0x10000000; addr += pageSize) { - uint32_t PTEH = 0; - uint32_t PTEL = 0; - if(getPageEntryForAddress(SDR1, addr, vsid, translation_table, &PTEH, &PTEL, false)) { - uint32_t pp = PTEL & 3; - uint32_t phys = PTEL & 0xFFFFF000; - - //DEBUG_FUNCTION_LINE("current.phys == phys - current.size ( %08X %08X)\n",current.phys, phys - current.size); - - if( current.ks == ks && - current.kp == kp && - current.nx == nx && - current.pp == pp && - current.phys == phys - current.size - ) { - current.size += pageSize; - //DEBUG_FUNCTION_LINE("New size of %08X is %08X\n",current.addr,current.size); - } else { - if(current.addr != 0 && current.size != 0) { - /*DEBUG_FUNCTION_LINE("Saving old block from %08X\n",current.addr); - DEBUG_FUNCTION_LINE("ks %08X new %08X\n",current.ks,ks); - DEBUG_FUNCTION_LINE("kp %08X new %08X\n",current.kp,kp); - DEBUG_FUNCTION_LINE("nx %08X new %08X\n",current.nx,nx); - DEBUG_FUNCTION_LINE("pp %08X new %08X\n",current.pp,pp);*/ - pageInfos.push_back(current); - memset(¤t,0,sizeof(current)); - } - //DEBUG_FUNCTION_LINE("Found new block at %08X\n",addr); - current.addr = addr; - current.size = pageSize; - current.kp = kp; - current.ks = ks; - current.nx = nx; - current.pp = pp; - current.phys = phys; - } - } else { - if(current.addr != 0 && current.size != 0) { - pageInfos.push_back(current); - memset(¤t,0,sizeof(current)); - } - } - } - } - } - - const char *access1[] = {"read/write", "read/write", "read/write", "read only"}; - const char *access2[] = {"no access", "read only", "read/write", "read only"}; - - for(std::vector::iterator it = pageInfos.begin(); it != pageInfos.end(); ++it) { - pageInformation cur = *it; - DEBUG_FUNCTION_LINE("%08X %08X -> %08X %08X. user access %s. supervisor access %s. %s\n",cur.addr,cur.addr+cur.size,cur.phys,cur.phys+cur.size,cur.kp ? access2[cur.pp] : access1[cur.pp], - cur.ks ? access2[cur.pp] : access1[cur.pp],cur.nx? "not executable" : "executable"); - } -} - - -bool MemoryMapping::mapMemory(uint32_t pa_start_address,uint32_t pa_end_address,uint32_t ea_start_address, sr_table_t SRTable, uint32_t * translation_table) { - // Based on code from dimok. Thanks! - - //uint32_t byteOffsetMask = (1 << PAGE_INDEX_SHIFT) - 1; - //uint32_t apiShift = 22 - PAGE_INDEX_SHIFT; - - // Information on page 5. - // https://www.nxp.com/docs/en/application-note/AN2794.pdf - uint32_t HTABORG = SRTable.sdr1 >> 16; - uint32_t HTABMASK = SRTable.sdr1 & 0x1FF; - - // Iterate to all possible pages. Each page is 1<<(PAGE_INDEX_SHIFT) big. - - uint32_t pageSize = 1<<(PAGE_INDEX_SHIFT); - for(uint32_t i = 0; i < pa_end_address - pa_start_address; i += pageSize) { - // Calculate the current effective address. - uint32_t ea_addr = ea_start_address + i; - // Calculate the segement. - uint32_t segment = SRTable.value[ea_addr >> 28]; - - // Unique ID from the segment which is the input for the hash function. - // Change it to prevent collisions. - uint32_t VSID = segment & 0x00FFFFFF; - uint32_t V = 1; - - //Indicated if second hash is used. - uint32_t H = 0; - - // Abbreviated Page Index - - // Real page number - uint32_t RPN = (pa_start_address + i) >> 12; - uint32_t RC = 3; - uint32_t WIMG = 0x02; - uint32_t PP = 0x02; - - uint32_t page_index = (ea_addr >> PAGE_INDEX_SHIFT) & PAGE_INDEX_MASK; - uint32_t API = (ea_addr >> 22) & 0x3F; - - uint32_t PTEH = (V << 31) | (VSID << 7) | (H << 6) | API; - uint32_t PTEL = (RPN << 12) | (RC << 7) | (WIMG << 3) | PP; - - //unsigned long long virtual_address = ((unsigned long long)VSID << 28UL) | (page_index << PAGE_INDEX_SHIFT) | (ea_addr & 0xFFF); - - uint32_t primary_hash = (VSID & 0x7FFFF); - - uint32_t hashvalue1 = primary_hash ^ page_index; - - // hashvalue 2 is the complement of the first hash. - uint32_t hashvalue2 = ~hashvalue1; - - //uint32_t pageMask = SRTable.sdr1 & 0x1FF; - - // calculate the address of the PTE groups. - // PTEs are saved in a group of 8 PTEs - // When PTEGaddr1 is full (all 8 PTEs set), PTEGaddr2 is used. - // Then H in PTEH needs to be set to 1. - uint32_t PTEGaddr1 = (HTABORG << 16) | (((hashvalue1 >> 10) & HTABMASK) << 16) | ((hashvalue1 & 0x3FF) << 6); - uint32_t PTEGaddr2 = (HTABORG << 16) | (((hashvalue2 >> 10) & HTABMASK) << 16) | ((hashvalue2 & 0x3FF) << 6); - - //offset of the group inside the PTE Table. - uint32_t PTEGoffset = PTEGaddr1 - (HTABORG << 16); - - bool setSuccessfully = false; - PTEGoffset += 7*8; - // Lets iterate through the PTE group where out PTE should be saved. - for(int32_t j = 7; j>0; PTEGoffset -= 8) { - int32_t index = (PTEGoffset/4); - - uint32_t pteh = translation_table[index]; - // Check if it's already taken. The first bit indicates if the PTE-slot inside - // this group is already taken. - if ((pteh == 0)) { - // If we found a free slot, set the PTEH and PTEL value. - DEBUG_FUNCTION_LINE("Used slot %d. PTEGaddr1 %08X addr %08X\n",j+1,PTEGaddr1 - (HTABORG << 16),PTEGoffset); - translation_table[index] = PTEH; - translation_table[index+1] = PTEL; - setSuccessfully = true; - break; - } else { - //printf("PTEGoffset %08X was taken\n",PTEGoffset); - } - j--; - } - // Check if we already found a slot. - if(!setSuccessfully) { - DEBUG_FUNCTION_LINE("-------------- Using second slot -----------------------\n"); - // We still have a chance to find a slot in the PTEGaddr2 using the complement of the hash. - // We need to set the H flag in PTEH and use PTEGaddr2. - // (Not well tested) - H = 1; - PTEH = (V << 31) | (VSID << 7) | (H << 6) | API; - PTEGoffset = PTEGaddr2 - (HTABORG << 16); - PTEGoffset += 7*8; - // Same as before. - for(int32_t j = 7; j>0; PTEGoffset -= 8) { - int32_t index = (PTEGoffset/4); - uint32_t pteh = translation_table[index]; - //Check if it's already taken. - if ((pteh == 0)) { - translation_table[index] = PTEH; - translation_table[index+1] = PTEL; - setSuccessfully = true; - break; - } else { - //printf("PTEGoffset %08X was taken\n",PTEGoffset); - } - j--; - } - - if(!setSuccessfully) { - // Fail if we couldn't find a free slot. - DEBUG_FUNCTION_LINE("-------------- No more free PTE -----------------------\n"); - return false; - } - } - } - return true; -} - -uint32_t MemoryMapping::PhysicalToEffective(uint32_t phyiscalAddress) { - if(phyiscalAddress >= 0x30800000 && phyiscalAddress < 0x31000000) { - return phyiscalAddress - (0x30800000 - 0x00800000); - } - - uint32_t result = 0; - const memory_values_t * curMemValues = NULL; - int32_t curOffset = 0; - //iterate through all own mapped memory regions - for(int32_t i = 0; true; i++) { - if(mem_mapping[i].physical_addresses == NULL) { - break; - } - - curMemValues = mem_mapping[i].physical_addresses; - uint32_t curOffsetInEA = 0; - // iterate through all memory values of this region - for(int32_t j= 0; true; j++) { - if(curMemValues[j].end_address == 0) { - break; - } - if(phyiscalAddress >= curMemValues[j].start_address && phyiscalAddress < curMemValues[j].end_address) { - // calculate the EA - result = (phyiscalAddress - curMemValues[j].start_address) + (mem_mapping[i].effective_start_address + curOffsetInEA); - return result; - } - curOffsetInEA += curMemValues[j].end_address - curMemValues[j].start_address; - } - } - - return result; -} - -uint32_t MemoryMapping::EffectiveToPhysical(uint32_t effectiveAddress) { - if(effectiveAddress >= 0x00800000 && effectiveAddress < 0x01000000) { - return effectiveAddress + (0x30800000 - 0x00800000); - } - - uint32_t result = 0; - // CAUTION: The data may be fragmented between multiple areas in PA. - const memory_values_t * curMemValues = NULL; - uint32_t curOffset = 0; - - for(int32_t i = 0; true; i++) { - if(mem_mapping[i].physical_addresses == NULL) { - break; - } - if(effectiveAddress >= mem_mapping[i].effective_start_address && effectiveAddress < mem_mapping[i].effective_end_address) { - curMemValues = mem_mapping[i].physical_addresses; - curOffset = mem_mapping[i].effective_start_address; - break; - } - } - - if(curMemValues == NULL) { - return result; - } - - for(int32_t i= 0; true; i++) { - if(curMemValues[i].end_address == 0) { - break; - } - uint32_t curChunkSize = curMemValues[i].end_address - curMemValues[i].start_address; - if(effectiveAddress < (curOffset + curChunkSize)) { - result = (effectiveAddress - curOffset) + curMemValues[i].start_address; - break; - } - curOffset += curChunkSize; - } - return result; -} diff --git a/src/memory/memory_mapping.h b/src/memory/memory_mapping.h deleted file mode 100644 index ca26422..0000000 --- a/src/memory/memory_mapping.h +++ /dev/null @@ -1,207 +0,0 @@ -#ifndef __MEMORY_MAPPING_H_ -#define __MEMORY_MAPPING_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "kernel/kernel_defs.h" - -typedef struct pageInformation_ { - uint32_t addr; - uint32_t size; - uint32_t ks; - uint32_t kp; - uint32_t nx; - uint32_t pp; - uint32_t phys; -} pageInformation; - -typedef struct _memory_values_t { - uint32_t start_address; - uint32_t end_address; -} memory_values_t; - -typedef struct _memory_mapping_t { - uint32_t effective_start_address; - uint32_t effective_end_address; - const memory_values_t* physical_addresses; -} memory_mapping_t; - -#define SEGMENT_UNIQUE_ID 0x00AABBCC // Unique ID. Chosen arbitrary. -#define PAGE_INDEX_SHIFT (32-15) -#define PAGE_INDEX_MASK ((1 << (28 - PAGE_INDEX_SHIFT)) - 1) - -#define MEMORY_START_BASE 0x80000000 - -#define MEMORY_LOADER_SPACE_SIZE 0x00800000 // At most: 8MB for the plugin loader. -#define MEMORY_PLUGIN_SPACE_SIZE 0x04000000 // At most: 64MB for plugins. -#define MEMORY_VIDEO_SPACE_SIZE 0x03600000 // At most: 56MB for video. -#define MEMORY_PLUGIN_HEAP_SIZE 0x08000000 // At most: 128MB for plugins heap. - -#define MEMORY_START_PLUGIN_LOADER MEMORY_START_BASE -#define MEMORY_START_PLUGIN_LOADER_END MEMORY_START_PLUGIN_LOADER + MEMORY_LOADER_SPACE_SIZE - -#define MEMORY_START_PLUGIN_SPACE MEMORY_START_PLUGIN_LOADER_END -#define MEMORY_START_PLUGIN_SPACE_END MEMORY_START_PLUGIN_SPACE + MEMORY_PLUGIN_SPACE_SIZE - -#define MEMORY_START_VIDEO_SPACE MEMORY_START_PLUGIN_SPACE_END -#define MEMORY_START_VIDEO_SPACE_END MEMORY_START_VIDEO_SPACE + MEMORY_VIDEO_SPACE_SIZE - -#define MEMORY_START_PLUGIN_HEAP MEMORY_START_VIDEO_SPACE_END -#define MEMORY_START_PLUGIN_HEAP_END MEMORY_START_PLUGIN_HEAP + MEMORY_PLUGIN_HEAP_SIZE - -const memory_values_t mem_vals_loader[] = { - {0x28000000 + 0x06620000, 0x28000000 + 0x06E20000}, // 8MB 0x80000000 0x80800000 -> 0x2E700000 0x2EF00000 - {0,0} -}; - -const memory_values_t mem_vals_plugins[] = { - {0x28000000 + 0x06E20000, 0x28000000 + 0x07E20000}, // 16MB 0x80800000 0x81800000 -> 0x2EF00000 0x2FF00000 - {0,0} -}; - -const memory_values_t mem_vals_video[] = { - // The GPU doesn't have access to the 0x28000000 - 0x32000000 area, so we need memory from somewhere else. - // From the SharedReadHeap of the loader. - // - // #define TinyHeap_Alloc ((int32_t (*)(void* heap, int32_t size, int32_t align,void ** outPtr))0x0101235C) - // #define TinyHeap_Free ((void (*)(void* heap, void * ptr))0x01012814) - // uint32_t SharedReadHeapTrackingAddr = 0xFA000000 + 0x18 + 0x830 // see https://github.com/decaf-emu/decaf-emu/blob/master/src/libdecaf/src/cafe/loader/cafe_loader_shared.cpp#L490 - // - // Map the area of the heap to somewhere in the user space and test allocation with - // void * heap = (void*) SharedReadHeapTrackingAddr - [delta due mapping e.g (0xF8000000 + 0x80000000)]; - // int size = 0x20000; // value have to be a multiple of 0x20000; - // while(true){ - // void * outPtr = NULL; - // if(TinyHeap_Alloc(heap,size, 0x20000,&outPtr) == 0){ // value have to be a multiple of 0x20000; - // DEBUG_FUNCTION_LINE("Allocated %d kb on heap %08X (PA %08X)\n",size/1024,(uint32_t)outPtr, OSEffectiveToPhysical(outPtr)); - // TinyHeap_Free(heap, outPtr); - // }else{ - // DEBUG_FUNCTION_LINE("Failed %08X\n",(uint32_t)outPtr); - // break; - // } - // size += 0x20000; // value have to be a multiple of 0x20000; - // } - // - {0x1A020000, 0x1A020000 +0xE60000}, // size: 14720 kB - // The following chunk were empty while early tests and are maybe promising. However we can get 15mb from - // a loader heap. Which should be enough for now. - //{0x14000000 + 0x02E00000 , 0x14000000 +0x034E0000}, // size: 7040 kB - //{0x14000000 + 0x02820000 , 0x14000000 +0x02C20000}, // size: 4096 kB - //{0x14000000 + 0x05AE0000 , 0x14000000 +0x06000000}, // size: 5248 kB - //{0x14000000 + 0x08040000 , 0x14000000 +0x08400000}, // size: 3840 kB - //{0x18000000 , 0x18000000 +0x3000000}, // size: 3840 kB - {0,0} -}; - -// Values needs to be aligned to 0x20000 and size needs to be a multiple of 0x20000 -const memory_values_t mem_vals_heap[] = { - // 5.5.2 EUR - {0x28000000 + 0x09000000, 0x28000000 + 0x09E20000}, // size: 14464 kB - {0x28000000 + 0x058E0000, 0x28000000 + 0x06000000}, // size: 7296 kB - {0x28000000 + 0x053C0000, 0x28000000 + 0x05880000}, // size: 4864 kB - //{0x28000000 + 0x08C20000, 0x28000000 + 0x08F20000}, // size: 3072 kB is part of BAT mapping. - {0x28000000 + 0x00900000, 0x28000000 + 0x00B00000}, // size: 2048 kB - {0x28000000 + 0x07E20000, 0x28000000 + 0x07F80000}, // size: 1408 kB - {0x28000000 + 0x02060000, 0x28000000 + 0x021A0000}, // size: 1280 kB - {0x28000000 + 0x083C0000, 0x28000000 + 0x084C0000}, // size: 1024 kB - {0x28000000 + 0x003C0000, 0x28000000 + 0x004C0000}, // size: 1024 kB - {0x28000000 + 0x02BC0000, 0x28000000 + 0x02CA0000}, // size: 896 kB - {0x28000000 + 0x080E0000, 0x28000000 + 0x08180000}, // size: 640 kB - {0x28000000 + 0x000E0000, 0x28000000 + 0x00160000}, // size: 512 kB - {0x28000000 + 0x00E40000, 0x28000000 + 0x00EC0000}, // size: 512 kB - {0x28000000 + 0x00EE0000, 0x28000000 + 0x00F60000}, // size: 512 kB - {0x28000000 + 0x00FA0000, 0x28000000 + 0x01020000}, // size: 512 kB - {0x28000000 + 0x086E0000, 0x28000000 + 0x08760000}, // size: 512 kB - {0x28000000 + 0x04B60000, 0x28000000 + 0x04B80000}, // size: 128 kB - // This chunk was reduced several times, it _might_ be dangerous to use, let's put it right to the end. - {0x28000000 + 0x01040000, 0x28000000 + 0x01340000}, // size: 3072 kB - - // Not usable on 5.5.2 - // - // Used in notifications {0x28000000 + 0x01720000, 0x28000000 + 0x018A0000}, // size: 1536 kB - // {0x28000000 + 0x03820000, 0x28000000 + 0x038C0000}, // size: 640 kB - // {0x28000000 + 0x03920000, 0x28000000 + 0x039A0000}, // size: 512 kB - // Used in notifications {0x28000000 + 0x04B80000, 0x28000000 + 0x051E0000}, // size: 6528 kB - // {0x28000000 + 0x08F20000, 0x28000000 + 0x09000000}, // size: 896 kB - - // {0x28000000 + 0x013A0000, 0x28000000 + 0x013C0000}, // size: 128 kB - - // Porting to other/newer firmware: - // Map this to check for free regions. - // Use MemoryMapper::testFreeMemory() to see regions with are 0x00000000; - // Then map the promising regions, and do the write/read check. - // Writing numbers into the area, open the home menu and all background apps an check if anything was - // overridden. - // {0x28000000 + 0x00000000, 0x28000000 + 0x0A000000}, // - - {0,0} -}; - -const memory_mapping_t mem_mapping[] = { - {MEMORY_START_VIDEO_SPACE, MEMORY_START_VIDEO_SPACE_END, mem_vals_video}, - {MEMORY_START_PLUGIN_LOADER, MEMORY_START_PLUGIN_LOADER_END, mem_vals_loader}, - {MEMORY_START_PLUGIN_SPACE, MEMORY_START_PLUGIN_SPACE_END, mem_vals_plugins}, - {MEMORY_START_PLUGIN_HEAP, MEMORY_START_PLUGIN_HEAP_END, mem_vals_heap}, - {0,0,NULL} -}; - -class MemoryMapping { - -public: - static bool isMemoryMapped(); - - static void setupMemoryMapping(); - - static void printPageTableTranslation(sr_table_t srTable, uint32_t * translation_table); - - static void writeTestValuesToMemory(); - - static void readTestValuesFromMemory(); - - static void searchEmptyMemoryRegions(); - - static uint32_t getHeapAddress(); - - static uint32_t getHeapSize(); - - static uint32_t getVideoMemoryAddress(); - - static uint32_t getVideoMemorySize(); - - static uint32_t getPluginSpaceMemoryAddress(); - - static uint32_t getPluginSpaceMemorySize(); - - static uint32_t getAreaSizeFromPageTable(uint32_t start, uint32_t maxSize); - - // Caution when using the result. A chunk of memory in effective address may be split up - // into several small chunks inside physical space. - static uint32_t PhysicalToEffective(uint32_t phyiscalAddress); - - // Caution when using the result. A chunk of memory in effective address may be split up - // into several small chunks inside physical space. - static uint32_t EffectiveToPhysical(uint32_t effectiveAddress); - -private: - - static void memoryMappingForRegions(const memory_mapping_t * memory_mapping, sr_table_t SRTable, uint32_t * translation_table); - - static bool mapMemory(uint32_t pa_start_address,uint32_t pa_end_address,uint32_t ea_start_address, sr_table_t SRTable, uint32_t * translation_table); - - - static bool getPageEntryForAddress(uint32_t SDR1, uint32_t addr, uint32_t vsid, uint32_t * translation_table,uint32_t* oPTEH, uint32_t* oPTEL, bool checkSecondHash); - - static bool getPageEntryForAddressEx(uint32_t pageMask, uint32_t addr, uint32_t vsid, uint32_t primaryHash, uint32_t * translation_table,uint32_t* oPTEH, uint32_t* oPTEL,uint32_t H) ; -}; - - -#ifdef __cplusplus -} -#endif - -#endif // __KERNEL_DEFS_H_ diff --git a/src/patcher/function_patcher.cpp b/src/patcher/function_patcher.cpp deleted file mode 100644 index 864d10a..0000000 --- a/src/patcher/function_patcher.cpp +++ /dev/null @@ -1,394 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2016-2018 Maschell - * With code from chadderz and dimok - * - * 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 . - ****************************************************************************/ - -#include -#include -#include -#include -#include -#include - -#include "function_patcher.h" -#include -#include -#include -#include -#include - -#define DEBUG_LOG_DYN 0 - -rpl_handling rpl_handles[] __attribute__((section(".data"))) = { - {WUPS_LOADER_LIBRARY_AVM, "avm.rpl", 0}, - {WUPS_LOADER_LIBRARY_CAMERA, "camera.rpl", 0}, - {WUPS_LOADER_LIBRARY_COREINIT, "coreinit.rpl", 0}, - {WUPS_LOADER_LIBRARY_DC, "dc.rpl", 0}, - {WUPS_LOADER_LIBRARY_DMAE, "dmae.rpl", 0}, - {WUPS_LOADER_LIBRARY_DRMAPP, "drmapp.rpl", 0}, - {WUPS_LOADER_LIBRARY_ERREULA, "erreula.rpl", 0}, - {WUPS_LOADER_LIBRARY_GX2, "gx2.rpl", 0}, - {WUPS_LOADER_LIBRARY_H264, "h264.rpl", 0}, - {WUPS_LOADER_LIBRARY_LZMA920, "lzma920.rpl", 0}, - {WUPS_LOADER_LIBRARY_MIC, "mic.rpl", 0}, - {WUPS_LOADER_LIBRARY_NFC, "nfc.rpl", 0}, - {WUPS_LOADER_LIBRARY_NIO_PROF, "nio_prof.rpl", 0}, - {WUPS_LOADER_LIBRARY_NLIBCURL, "nlibcurl.rpl", 0}, - {WUPS_LOADER_LIBRARY_NLIBNSS, "nlibnss.rpl", 0}, - {WUPS_LOADER_LIBRARY_NLIBNSS2, "nlibnss2.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_AC, "nn_ac.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_ACP, "nn_acp.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_ACT, "nn_act.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_AOC, "nn_aoc.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_BOSS, "nn_boss.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_CCR, "nn_ccr.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_CMPT, "nn_cmpt.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_DLP, "nn_dlp.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_EC, "nn_ec.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_FP, "nn_fp.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_HAI, "nn_hai.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_HPAD, "nn_hpad.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_IDBE, "nn_idbe.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_NDM, "nn_ndm.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_NETS2, "nn_nets2.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_NFP, "nn_nfp.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_NIM, "nn_nim.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_OLV, "nn_olv.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_PDM, "nn_pdm.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_SAVE, "nn_save.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_SL, "nn_sl.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_SPM, "nn_spm.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_TEMP, "nn_temp.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_UDS, "nn_uds.rpl", 0}, - {WUPS_LOADER_LIBRARY_NN_VCTL, "nn_vctl.rpl", 0}, - {WUPS_LOADER_LIBRARY_NSYSCCR, "nsysccr.rpl", 0}, - {WUPS_LOADER_LIBRARY_NSYSHID, "nsyshid.rpl", 0}, - {WUPS_LOADER_LIBRARY_NSYSKBD, "nsyskbd.rpl", 0}, - {WUPS_LOADER_LIBRARY_NSYSNET, "nsysnet.rpl", 0}, - {WUPS_LOADER_LIBRARY_NSYSUHS, "nsysuhs.rpl", 0}, - {WUPS_LOADER_LIBRARY_NSYSUVD, "nsysuvd.rpl", 0}, - {WUPS_LOADER_LIBRARY_NTAG, "ntag.rpl", 0}, - {WUPS_LOADER_LIBRARY_PADSCORE, "padscore.rpl", 0}, - {WUPS_LOADER_LIBRARY_PROC_UI, "proc_ui.rpl", 0}, - {WUPS_LOADER_LIBRARY_SNDCORE2, "sndcore2.rpl", 0}, - {WUPS_LOADER_LIBRARY_SNDUSER2, "snduser2.rpl", 0}, - {WUPS_LOADER_LIBRARY_SND_CORE, "snd_core.rpl", 0}, - {WUPS_LOADER_LIBRARY_SND_USER, "snd_user.rpl", 0}, - {WUPS_LOADER_LIBRARY_SWKBD, "swkbd.rpl", 0}, - {WUPS_LOADER_LIBRARY_SYSAPP, "sysapp.rpl", 0}, - {WUPS_LOADER_LIBRARY_TCL, "tcl.rpl", 0}, - {WUPS_LOADER_LIBRARY_TVE, "tve.rpl", 0}, - {WUPS_LOADER_LIBRARY_UAC, "uac.rpl", 0}, - {WUPS_LOADER_LIBRARY_UAC_RPL, "uac_rpl.rpl", 0}, - {WUPS_LOADER_LIBRARY_USB_MIC, "usb_mic.rpl", 0}, - {WUPS_LOADER_LIBRARY_UVC, "uvc.rpl", 0}, - {WUPS_LOADER_LIBRARY_UVD, "uvd.rpl", 0}, - {WUPS_LOADER_LIBRARY_VPAD, "vpad.rpl", 0}, - {WUPS_LOADER_LIBRARY_VPADBASE, "vpadbase.rpl", 0}, - {WUPS_LOADER_LIBRARY_ZLIB125, "zlib125.rpl", 0} -}; - -void new_PatchInvidualMethodHooks(replacement_data_plugin_t * plugin_data) { - InitAcquireOS(); - new_resetLibs(); - - DEBUG_FUNCTION_LINE("Patching %d given functions\n",plugin_data->number_used_functions); - - int32_t method_hooks_count = plugin_data->number_used_functions; - - uint32_t skip_instr = 1; - uint32_t my_instr_len = 6; - uint32_t instr_len = my_instr_len + skip_instr + 6; - uint32_t flush_len = 4*instr_len; - for(int32_t i = 0; i < method_hooks_count; i++) { - replacement_data_function_t * function_data = &plugin_data->functions[i]; - /* Patch branches to it. */ - volatile uint32_t *space = function_data->replace_data; - - DEBUG_FUNCTION_LINE("Patching %s ...\n",function_data->function_name); - - if(function_data->library == WUPS_LOADER_LIBRARY_OTHER) { - DEBUG_FUNCTION_LINE("Oh, using straight PA/VA\n"); - if(function_data->alreadyPatched == 1) { - DEBUG_FUNCTION_LINE("Skipping %s, its already patched\n", function_data->function_name); - continue; - } - } else { - if(function_data->functionType == STATIC_FUNCTION && function_data->alreadyPatched == 1) { - if(new_isDynamicFunction((uint32_t)OSEffectiveToPhysical(function_data->realAddr))) { - DEBUG_FUNCTION_LINE("INFO: The function %s is a dynamic function.\n", function_data->function_name); - function_data->functionType = DYNAMIC_FUNCTION; - } else { - DEBUG_FUNCTION_LINE("Skipping %s, its already patched\n", function_data->function_name); - continue; - } - } - } - - uint32_t physical = function_data->physicalAddr; - uint32_t repl_addr = (uint32_t)function_data->replaceAddr; - uint32_t call_addr = (uint32_t)function_data->replaceCall; - - uint32_t real_addr = function_data->virtualAddr; - if(function_data->library != WUPS_LOADER_LIBRARY_OTHER) { - real_addr = new_GetAddressOfFunction(function_data->function_name,function_data->library); - } - - if(!real_addr) { - log_printf("\n"); - DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s\n", function_data->function_name); - continue; - } - - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("%s is located at %08X!\n", function_data->function_name,real_addr); - } - - if(function_data->library != WUPS_LOADER_LIBRARY_OTHER) { - physical = (uint32_t)OSEffectiveToPhysical(real_addr); - } - - if(!physical) { - log_printf("Error. Something is wrong with the physical address\n"); - continue; - } - - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("%s physical is located at %08X!\n", function_data->function_name,physical); - } - - *(volatile uint32_t *)(call_addr) = (uint32_t)(space); - - uint32_t targetAddr = (uint32_t)space; - if(targetAddr < 0x00800000 || targetAddr >= 0x01000000) { - targetAddr = (uint32_t) OSEffectiveToPhysical(targetAddr); - }else{ - targetAddr = targetAddr + 0x30800000 - 0x00800000; - } - - KernelCopyData(targetAddr, physical, 4); - - ICInvalidateRange((void*)(space), 4); - DCFlushRange((void*)(space), 4); - - space++; - - //Only works if skip_instr == 1 - if(skip_instr == 1) { - // fill the restore instruction section - function_data->realAddr = real_addr; - function_data->restoreInstruction = space[-1]; - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("function_data->realAddr = %08X!\n", function_data->realAddr); - } - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("function_data->restoreInstruction = %08X!\n",function_data->restoreInstruction) ; - } - } else { - log_printf("Error. Can't save %s for restoring!\n", function_data->function_name); - } - - //adding jump to real function thx @ dimok for the assembler code - /* - 90 61 ff e0 stw r3,-32(r1) - 3c 60 12 34 lis r3,4660 - 60 63 56 78 ori r3,r3,22136 - 7c 69 03 a6 mtctr r3 - 80 61 ff e0 lwz r3,-32(r1) - 4e 80 04 20 bctr*/ - *space = 0x9061FFE0; - space++; - *space = 0x3C600000 | (((real_addr + (skip_instr * 4)) >> 16) & 0x0000FFFF); // lis r3, real_addr@h - space++; - *space = 0x60630000 | ((real_addr + (skip_instr * 4)) & 0x0000ffff); // ori r3, r3, real_addr@l - space++; - *space = 0x7C6903A6; // mtctr r3 - space++; - *space = 0x8061FFE0; // lwz r3,-32(r1) - space++; - *space = 0x4E800420; // bctr - space++; - - - uint32_t repl_addr_test = (uint32_t) space; - *space = 0x9061FFE0; - space++; - *space = 0x3C600000 | (((repl_addr) >> 16) & 0x0000FFFF); // lis r3, repl_addr@h - space++; - *space = 0x60630000 | ((repl_addr) & 0x0000ffff); // ori r3, r3, repl_addr@l - space++; - *space = 0x7C6903A6; // mtctr r3 - space++; - *space = 0x8061FFE0; // lwz r3,-32(r1) - space++; - *space = 0x4E800420; // bctr - space++; - DCFlushRange((void*)(((uint32_t) space) - flush_len),flush_len); - ICInvalidateRange((void*)(((uint32_t) space) - flush_len),flush_len); - - //setting jump back - uint32_t replace_instr = 0x48000002 | (repl_addr_test & 0x03fffffc); - ICInvalidateRange(&replace_instr, 4); - DCFlushRange(&replace_instr, 4); - - KernelCopyData(physical, (uint32_t)OSEffectiveToPhysical((uint32_t)&replace_instr), 4); - ICInvalidateRange((void*)(real_addr), 4); - DCFlushRange((void*)(real_addr), 4); - - function_data->alreadyPatched = 1; - DEBUG_FUNCTION_LINE("done with patching %s!\n", function_data->function_name); - - } - DEBUG_FUNCTION_LINE("Done with patching given functions!\n"); -} - -/* ****************************************************************** */ -/* RESTORE ORIGINAL INSTRUCTIONS */ -/* ****************************************************************** */ -void new_RestoreInvidualInstructions(replacement_data_plugin_t * plugin_data) { - InitAcquireOS(); - new_resetLibs(); - DEBUG_FUNCTION_LINE("Restoring given functions!\n"); - - int32_t method_hooks_count = plugin_data->number_used_functions; - - for(int32_t i = 0; i < method_hooks_count; i++) { - replacement_data_function_t * function_data = &plugin_data->functions[i]; - - DEBUG_FUNCTION_LINE("Restoring %s... ",function_data->function_name); - if(function_data->restoreInstruction == 0 || function_data->realAddr == 0) { - log_printf("I dont have the information for the restore =( skip\n"); - continue; - } - - uint32_t real_addr = function_data->virtualAddr; - if(function_data->library != WUPS_LOADER_LIBRARY_OTHER) { - real_addr = new_GetAddressOfFunction(function_data->function_name,function_data->library); - } - if(!real_addr) { - log_printf("OSDynLoad_FindExport failed for %s\n", function_data->function_name); - continue; - } - uint32_t physical = function_data->physicalAddr; - if(function_data->library != WUPS_LOADER_LIBRARY_OTHER) { - physical = (uint32_t)OSEffectiveToPhysical(real_addr); - } - if(!physical) { - log_printf("Something is wrong with the physical address\n"); - continue; - } - if((function_data->library != WUPS_LOADER_LIBRARY_OTHER) && new_isDynamicFunction(physical)) { - log_printf("Its a dynamic function. We don't need to restore it!\n",function_data->function_name); - } else { - if(function_data->library != WUPS_LOADER_LIBRARY_OTHER) { - physical = (uint32_t)OSEffectiveToPhysical(function_data->realAddr); //When its an static function, we need to use the old location - } - - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("Restoring %08X to %08X\n",(uint32_t)function_data->restoreInstruction,physical); - } - uint32_t targetAddr = (uint32_t)&(function_data->restoreInstruction); - if(targetAddr < 0x00800000 || targetAddr >= 0x01000000) { - targetAddr = (uint32_t) OSEffectiveToPhysical(targetAddr); - } else { - targetAddr = targetAddr + 0x30800000 - 0x00800000; - } - - DEBUG_FUNCTION_LINE("Copy %d bytes from %08X to %08x\n", 4,targetAddr, physical); - - KernelCopyData(physical,targetAddr, 4); - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("ICInvalidateRange %08X\n",(void*)function_data->realAddr); - } - - if(function_data->library != WUPS_LOADER_LIBRARY_OTHER) { - ICInvalidateRange((void*)function_data->realAddr, 4); - DCFlushRange((void*)function_data->realAddr, 4); - } - log_printf("done\n"); - } - function_data->alreadyPatched = 0; // In case a - } - - DEBUG_FUNCTION_LINE("Done with restoring given functions!\n"); -} - -int32_t new_isDynamicFunction(uint32_t physicalAddress) { - if((physicalAddress & 0x80000000) == 0x80000000) { - return 1; - } - return 0; -} - -uint32_t new_GetAddressOfFunction(const char * functionName,wups_loader_library_type_t library) { - uint32_t real_addr = 0; - - uint32_t rpl_handle = 0; - - int32_t rpl_handles_size = sizeof rpl_handles / sizeof rpl_handles[0]; - - for(int32_t i = 0; i< rpl_handles_size; i++) { - if(rpl_handles[i].library == library) { - if(rpl_handles[i].handle == 0) { - DEBUG_FUNCTION_LINE("Lets acquire handle for rpl: %s\n",rpl_handles[i].rplname); - OSDynLoad_Acquire((char*) rpl_handles[i].rplname, &rpl_handles[i].handle); - } - if(rpl_handles[i].handle == 0) { - log_printf("%s failed to acquire\n",rpl_handles[i].rplname); - return 0; - } - rpl_handle = rpl_handles[i].handle; - break; - } - } - - if(!rpl_handle) { - DEBUG_FUNCTION_LINE("Failed to find the RPL handle for %s\n", functionName); - return 0; - } - - OSDynLoad_FindExport(rpl_handle, 0, functionName, &real_addr); - - if(!real_addr) { - DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s\n", functionName); - return 0; - } - - if((library == WUPS_LOADER_LIBRARY_NN_ACP) && (uint32_t)(*(volatile uint32_t*)(real_addr) & 0x48000002) == 0x48000000) { - uint32_t address_diff = (uint32_t)(*(volatile uint32_t*)(real_addr) & 0x03FFFFFC); - if((address_diff & 0x03000000) == 0x03000000) { - address_diff |= 0xFC000000; - } - real_addr += (int32_t)address_diff; - if((uint32_t)(*(volatile uint32_t*)(real_addr) & 0x48000002) == 0x48000000) { - return 0; - } - } - - return real_addr; -} - -void new_resetLibs() { - int32_t rpl_handles_size = sizeof rpl_handles / sizeof rpl_handles[0]; - - for(int32_t i = 0; i< rpl_handles_size; i++) { - if(rpl_handles[i].handle != 0) { - DEBUG_FUNCTION_LINE("Resetting handle for rpl: %s\n",rpl_handles[i].rplname); - } - rpl_handles[i].handle = 0; - // Release handle? - } -} diff --git a/src/patcher/function_patcher.h b/src/patcher/function_patcher.h deleted file mode 100644 index ccbd0c8..0000000 --- a/src/patcher/function_patcher.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2016-2018 Maschell - * With code from chadderz and dimok - * - * 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 . - ****************************************************************************/ - -#ifndef _FUNCTION_PATCHER_HOOKS_H_ -#define _FUNCTION_PATCHER_HOOKS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -struct rpl_handling { - wups_loader_library_type_t library; - const char rplname[15]; - uint32_t handle; -}; -#define STATIC_FUNCTION 0 -#define DYNAMIC_FUNCTION 1 - -#define FUNCTION_PATCHER_METHOD_STORE_SIZE 13 -#define MAXIMUM_PLUGIN_PATH_NAME_LENGTH 256 -#define MAXIMUM_PLUGIN_NAME_LENGTH 51 -#define MAXIMUM_FUNCTION_NAME_LENGTH 83 - -struct replacement_data_function_t { - uint32_t physicalAddr; /* [needs to be filled] */ - uint32_t virtualAddr; /* [needs to be filled] */ - uint32_t replaceAddr; /* [needs to be filled] Address of our replacement function */ - uint32_t replaceCall; /* [needs to be filled] Address to access the real_function */ - wups_loader_library_type_t library; /* [needs to be filled] rpl where the function we want to replace is. */ - char function_name[MAXIMUM_FUNCTION_NAME_LENGTH]; /* [needs to be filled] name of the function we want to replace */ - uint32_t realAddr; /* [will be filled] Address of the real function we want to replace. */ - volatile uint32_t replace_data [FUNCTION_PATCHER_METHOD_STORE_SIZE]; /* [will be filled] Space for us to store some jump instructions */ - uint32_t restoreInstruction; /* [will be filled] Copy of the instruction we replaced to jump to our code. */ - uint8_t functionType; /* [will be filled] */ - uint8_t alreadyPatched; /* [will be filled] */ -}; - -struct replacement_data_hook_t { - void * func_pointer = NULL; /* [will be filled] */ - wups_loader_hook_type_t type; /* [will be filled] */ -}; - -#define MAXIMUM_HOOKS_PER_PLUGIN 25 -#define MAXIMUM_FUNCTION_PER_PLUGIN 100 - -struct replacement_data_plugin_t { - char path[MAXIMUM_PLUGIN_PATH_NAME_LENGTH] = ""; // Path where the plugin is stored - char plugin_name[MAXIMUM_PLUGIN_NAME_LENGTH] = ""; // Name of this plugin - int32_t priority; // Priority of this plugin - int32_t number_used_functions; // Number of used function. Maximum is MAXIMUM_FUNCTION_PER_PLUGIN - replacement_data_function_t functions[MAXIMUM_FUNCTION_PER_PLUGIN]; // Replacement information for each function. - - int32_t number_used_hooks; // Number of used hooks. Maximum is MAXIMUM_HOOKS_PER_PLUGIN - replacement_data_hook_t hooks[MAXIMUM_HOOKS_PER_PLUGIN]; // Replacement information for each function. - bool kernel_allowed; // Allow kernel access for the plugin!?!. - bool kernel_init_done; // KernelInit was done - uint32_t bssAddr; - uint32_t bssSize; - uint32_t sbssAddr; - uint32_t sbssSize; -}; - -#define MAXIMUM_PLUGINS 32 - -struct replacement_data_t { - int32_t number_used_plugins = 0; // Number of used function. Maximum is MAXIMUM_FUNCTION_PER_PLUGIN - replacement_data_plugin_t plugin_data[MAXIMUM_PLUGINS]; -}; - -struct to_link_and_load_data_t { - char name[256]; -}; - -void new_PatchInvidualMethodHooks(replacement_data_plugin_t * data); -void new_RestoreInvidualInstructions(replacement_data_plugin_t * plugin_data); -uint32_t new_GetAddressOfFunction(const char * functionName,wups_loader_library_type_t library); -int32_t new_isDynamicFunction(uint32_t physicalAddress); -void new_resetLibs(); - -#ifdef __cplusplus -} -#endif - -#endif /* _FUNCTION_PATCHER_HOOKS_H_ */ diff --git a/src/plugin/DynamicLinkingHelper.cpp b/src/plugin/DynamicLinkingHelper.cpp deleted file mode 100644 index 3186ea4..0000000 --- a/src/plugin/DynamicLinkingHelper.cpp +++ /dev/null @@ -1,207 +0,0 @@ -#include "DynamicLinkingHelper.h" -#include -#include -#include -#include "utils/logger.h" -#include "ElfTools.h" -#include "PluginLoader.h" - -DynamicLinkingHelper * DynamicLinkingHelper::instance = NULL; - -dyn_linking_function_t * DynamicLinkingHelper::getOrAddFunctionEntryByName(const char* functionName) { - if(functionName == NULL) { - return NULL; - } - dyn_linking_function_t * result = NULL; - for(int32_t i = 0; i < DYN_LINK_FUNCTION_LIST_LENGTH; i++) { - dyn_linking_function_t * curEntry = &gbl_dyn_linking_data.functions[i]; - if(strlen(curEntry->functionName) == 0) { - strncpy(curEntry->functionName,functionName,DYN_LINK_FUNCTION_NAME_LENGTH); - result = curEntry; - break; - } - if(strncmp(curEntry->functionName,functionName,DYN_LINK_FUNCTION_NAME_LENGTH) == 0) { - result = curEntry; - break; - } - } - return result; -} - -dyn_linking_import_t * DynamicLinkingHelper::getOrAddFunctionImportByName(const char* importName) { - return getOrAddImport(importName, false); - -} - -dyn_linking_import_t * DynamicLinkingHelper::getOrAddDataImportByName(const char* importName) { - return getOrAddImport(importName, true); - -} - -dyn_linking_import_t * DynamicLinkingHelper::getOrAddImport(const char* importName, bool isData) { - if(importName == NULL) { - return NULL; - } - dyn_linking_import_t * result = NULL; - for(int32_t i = 0; i < DYN_LINK_IMPORT_LIST_LENGTH; i++) { - dyn_linking_import_t * curEntry = &gbl_dyn_linking_data.imports[i]; - if(strlen(curEntry->importName) == 0) { - strncpy(curEntry->importName,importName,DYN_LINK_IMPORT_NAME_LENGTH); - curEntry->isData = isData; - result = curEntry; - break; - } - if(strncmp(curEntry->importName,importName,DYN_LINK_IMPORT_NAME_LENGTH) == 0 && (curEntry->isData == isData)) { - return curEntry; - } - } - return result; -} - -bool DynamicLinkingHelper::addReloationEntry(RelocationData * relocationData) { - return addReloationEntry(relocationData->getType(), relocationData->getOffset(), relocationData->getAddend(), relocationData->getDestination(), relocationData->getName(), relocationData->getImportRPLInformation()); -} - -bool DynamicLinkingHelper::addReloationEntry(char type, size_t offset, int32_t addend, void *destination, std::string name, ImportRPLInformation * rplInfo) { - dyn_linking_import_t * importInfoGbl = DynamicLinkingHelper::getOrAddImport(rplInfo->getName().c_str(),rplInfo->isData()); - if(importInfoGbl == NULL) { - DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d rpl files to import reached.\n",DYN_LINK_IMPORT_LIST_LENGTH); - return false; - } - - dyn_linking_function_t * functionInfo = DynamicLinkingHelper::getOrAddFunctionEntryByName(name.c_str()); - if(functionInfo == NULL) { - DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d function to be relocated reached.\n",DYN_LINK_FUNCTION_LIST_LENGTH); - return false; - } - - return addReloationEntry(type, offset, addend, destination, functionInfo, importInfoGbl); -} - -bool DynamicLinkingHelper::addReloationEntry(char type, size_t offset, int32_t addend, void *destination, dyn_linking_function_t * functionName, dyn_linking_import_t * importInfo) { - for(int32_t i = 0; i < DYN_LINK_RELOCATION_LIST_LENGTH; i++) { - dyn_linking_relocation_entry_t * curEntry = &gbl_dyn_linking_data.entries[i]; - if(curEntry->functionEntry != NULL) { - continue; - } - curEntry->type = type; - curEntry->offset = offset; - curEntry->addend = addend; - curEntry->destination = destination; - curEntry->functionEntry = functionName; - curEntry->importEntry = importInfo; - - return true; - } - return false; -} - -std::vector DynamicLinkingHelper::getAllValidDynamicLinkingRelocations() { - std::vector result; - for(int32_t i = 0; i < DYN_LINK_RELOCATION_LIST_LENGTH; i++) { - if(gbl_dyn_linking_data.entries[i].functionEntry == NULL) { - break; - } - result.push_back(&gbl_dyn_linking_data.entries[i]); - } - return result; -} - -bool DynamicLinkingHelper::fillRelocations(std::vector entries ) { - for(size_t i = 0; i < entries.size(); i++) { - dyn_linking_relocation_entry_t * curEntry = entries[i]; - dyn_linking_function_t * functionEntry = curEntry->functionEntry; - void * destination = curEntry->destination; - if(functionEntry == NULL) { - DEBUG_FUNCTION_LINE("FunctionEntry was NULL\n"); - return false; - } - if(destination == NULL) { - DEBUG_FUNCTION_LINE("destination was NULL\n"); - return false; - } - if(functionEntry->address == NULL) { - dyn_linking_import_t * importEntry = curEntry->importEntry; - - if(importEntry == NULL) { - DEBUG_FUNCTION_LINE("importEntry was NULL\n"); - return false; - } - - if(importEntry->handle != 0) { - //DEBUG_FUNCTION_LINE("We cached import handle for %s\n",importEntry->importName); - } else { - OSDynLoad_Acquire(importEntry->importName, &importEntry->handle); - } - int32_t isData = 0; - if(importEntry->isData) { - isData = 1; - //DEBUG_FUNCTION_LINE("isData\n"); - } - - std::string wrap_str = "__rplwrap_"; - std::string functionNameStr = functionEntry->functionName; - - OSDynLoad_FindExport(importEntry->handle, isData, functionEntry->functionName, &functionEntry->address); - - if(functionNameStr.size() < wrap_str.size()) { - - } else if (std::equal(wrap_str.begin(), wrap_str.end(), functionNameStr.begin())) { - OSDynLoad_FindExport(importEntry->handle, isData, functionNameStr.substr(wrap_str.size()).c_str(), &functionEntry->address); - } - - if(!functionEntry->address) { - DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s on import %s\n", functionEntry->functionName,importEntry->importName); - return false; - } else { - //DEBUG_FUNCTION_LINE("OSDynLoad_FindExport successful for %s on import %s: %08X\n",functionEntry->functionName,importEntry->importName,functionEntry->address); - - /* - 90 61 ff e0 stw r3,-32(r1) - 3c 60 12 34 lis r3,4660 - 60 63 56 78 ori r3,r3,22136 - 7c 69 03 a6 mtctr r3 - 80 61 ff e0 lwz r3,-32(r1) - 4e 80 04 20 bctr*/ - functionEntry->big_jump[0] = 0x9061FFE0; - functionEntry->big_jump[1] = 0x3C600000 | ((((uint32_t) functionEntry->address) >> 16) & 0x0000FFFF); // lis r3, real_addr@h - functionEntry->big_jump[2] = 0x60630000 | (((uint32_t) functionEntry->address) & 0x0000ffff); // ori r3, r3, real_addr@l - functionEntry->big_jump[3] = 0x7C6903A6; // mtctr r3 - functionEntry->big_jump[4] = 0x8061FFE0; // lwz r3,-32(r1) - functionEntry->big_jump[5] = 0x4E800420; // bctr - DCFlushRange((void*)functionEntry->big_jump, sizeof(functionEntry->big_jump)); - ICInvalidateRange((unsigned char*)functionEntry->big_jump, sizeof(functionEntry->big_jump)); - - //DEBUG_FUNCTION_LINE("Created jump code address: %08X big_jump: %08X for %s \n",functionEntry->address,functionEntry->big_jump,functionEntry->functionName); - //dumpHex(functionEntry->big_jump,sizeof(functionEntry->big_jump)); - } - } else { - //DEBUG_FUNCTION_LINE("We cached the address of function %s :%08X\n",functionEntry->functionName,functionEntry->address); - } - - //DEBUG_FUNCTION_LINE("Linking: t: %02X o: %08X a: %d dest: %08X tar: %08X big_j: %08X\n",curEntry->type, curEntry->offset, curEntry->addend, curEntry->destination, functionEntry->address, (uint32_t) functionEntry->big_jump); - - DEBUG_FUNCTION_LINE("Resolving relocation to %s\n",functionEntry->functionName); - - if(!curEntry->importEntry->isData && (uint32_t) functionEntry->address > 0x01FFFFC) { - ElfTools::elfLinkOne(curEntry->type, curEntry->offset, curEntry->addend, curEntry->destination, (uint32_t) functionEntry->big_jump); - } else { - ElfTools::elfLinkOne(curEntry->type, curEntry->offset, curEntry->addend, curEntry->destination, (uint32_t) functionEntry->address); - } - - } - - PluginLoader::flushCache(); - - DEBUG_FUNCTION_LINE("Clearing cache.\n"); - for(size_t i = 0; i < entries.size(); i++) { - dyn_linking_relocation_entry_t * curEntry = entries[i]; - curEntry->functionEntry->address = 0; - curEntry->importEntry->handle = 0; - } - return true; -} - -void DynamicLinkingHelper::clearAll() { - memset((void*)&gbl_dyn_linking_data,0,sizeof(gbl_dyn_linking_data)); -} diff --git a/src/plugin/ElfTools.cpp b/src/plugin/ElfTools.cpp deleted file mode 100644 index bfc1e6c..0000000 --- a/src/plugin/ElfTools.cpp +++ /dev/null @@ -1,501 +0,0 @@ -/* based on module.c - * by Alex Chadwick - * - * Copyright (C) 2014, Alex Chadwick - * Modified 2018, Maschell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "ElfTools.h" -#include "RelocationData.h" -#include "ImportRPLInformation.h" -#include -#include -#include -#include - -bool ElfTools::elfLoadSection(const Elf *elf, Elf_Scn *scn, const Elf32_Shdr *shdr,void *destination) { - if (destination == NULL) { - return false; - } - - switch (shdr->sh_type) { - case SHT_SYMTAB: - case SHT_PROGBITS: { - Elf_Data *data; - size_t n; - - n = 0; - for (data = elf_getdata(scn, NULL); data != NULL; data = elf_getdata(scn, data)) { - memcpy((char *)destination + n, data->d_buf, data->d_size); - n += data->d_size; - } - return true; - } - case SHT_NOBITS: { - memset(destination, 0, shdr->sh_size); - return true; - } - default: - return false; - } -} - -bool ElfTools::loadElfSymtab(Elf *elf, Elf32_Sym **symtab, size_t *symtab_count, size_t *symtab_strndx) { - Elf_Scn *scn; - bool result = false; - - for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) { - - Elf32_Shdr *shdr; - - shdr = elf32_getshdr(scn); - if (shdr == NULL) { - continue; - } - - if (shdr->sh_type == SHT_SYMTAB) { - size_t sym; - - if (*symtab != NULL) { - continue; - } - - *symtab = (Elf32_Sym *)malloc(shdr->sh_size); - if (*symtab == NULL) { - continue; - } - - *symtab_count = shdr->sh_size / sizeof(Elf32_Sym); - *symtab_strndx = shdr->sh_link; - - if (!elfLoadSection(elf, scn, shdr, *symtab)) { - goto exit_error; - } - - for (sym = 0; sym < *symtab_count; sym++) { - (*symtab)[sym].st_other = 0; - } - - break; - } - } - - if (*symtab == NULL) { - goto exit_error; - } - - result = true; -exit_error: - return result; -} - - -void ElfTools::elfLoadSymbols(size_t shndx, const void *destination, Elf32_Sym *symtab, size_t symtab_count) { - size_t i; - - /* use the st_other field (no defined meaning) to indicate whether or not a - * symbol address has been calculated. */ - for (i = 0; i < symtab_count; i++) { - if (symtab[i].st_shndx == shndx && - symtab[i].st_other == 0) { - - symtab[i].st_value += (Elf32_Addr)destination; - symtab[i].st_other = 1; - } - } -} - - -bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *symtab, size_t symtab_count, size_t symtab_strndx, bool allow_globals, PluginData * pluginData) { - Elf_Scn *scn; - - for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) { - Elf32_Shdr *shdr; - - shdr = elf32_getshdr(scn); - if (shdr == NULL) - continue; - - switch (shdr->sh_type) { - case SHT_REL: { - const Elf32_Rel *rel; - Elf_Data *data; - size_t i; - - if (shdr->sh_info != shndx) { - continue; - } - - data = elf_getdata(scn, NULL); - if (data == NULL) { - continue; - } - - rel = (const Elf32_Rel *) data->d_buf; - - for (i = 0; i < shdr->sh_size / sizeof(Elf32_Rel); i++) { - uint32_t symbol_addr; - size_t symbol; - - symbol = ELF32_R_SYM(rel[i].r_info); - - if (symbol > symtab_count) { - DEBUG_FUNCTION_LINE("symbol > symtab_count\n"); - return false; - } - - switch (symtab[symbol].st_shndx) { - case SHN_ABS: { - symbol_addr = symtab[symbol].st_value; - break; - } - case SHN_COMMON: { - DEBUG_FUNCTION_LINE("case SHN_COMMON\n"); - return false; - } - case SHN_UNDEF: { - - if (allow_globals) { - DEBUG_FUNCTION_LINE("The elf still have unresolved relocations. This is not supported."); - /* - Not support and not needed. - - module_unresolved_relocation_t *reloc; - char *name; - - reloc = (module_unresolved_relocation_t *) Module_ListAllocate( - &module_relocations, - sizeof(module_unresolved_relocation_t), 1, - &module_relocations_capacity, - &module_relocations_count, - PLUGIN_RELOCATIONS_CAPCITY_DEFAULT); - if (reloc == NULL) - return false; - - name = elf_strptr( - elf, symtab_strndx, symtab[symbol].st_name); - - if (name == NULL) { - module_relocations_count--; - return false; - } - - reloc->name = strdup(name); - if (reloc->name == NULL) { - module_relocations_count--; - return false; - } - - reloc->module = index; - reloc->address = destination; - reloc->offset = rel[i].r_offset; - reloc->type = ELF32_R_TYPE(rel[i].r_info); - reloc->addend = *(int32_t *)((char *)destination + rel[i].r_offset); - - continue; - */ - return false; - } else { - DEBUG_FUNCTION_LINE("case SHN_UNDEF with !allow_globals\n"); - return false; - } - } - default: { - if (symtab[symbol].st_other != 1) { - - DEBUG_FUNCTION_LINE("symtab[symbol].st_other != 1. it's %d %08X\n",symtab[symbol].st_other,symtab[symbol].st_other); - return false; - } - - symbol_addr = symtab[symbol].st_value; - break; - } - } - - if (!ElfTools::elfLinkOne(ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, *(int32_t *)((char *)destination + rel[i].r_offset), destination, symbol_addr)) { - DEBUG_FUNCTION_LINE("elfLinkOne failed\n"); - return false; - } - } - break; - } - case SHT_RELA: { - const Elf32_Rela *rela; - Elf_Data *data; - size_t i; - - if (shdr->sh_info != shndx) - continue; - - data = elf_getdata(scn, NULL); - if (data == NULL) - continue; - - rela = (const Elf32_Rela *) data->d_buf; - - for (i = 0; i < shdr->sh_size / sizeof(Elf32_Rela); i++) { - uint32_t symbol_addr; - size_t symbol; - - symbol = ELF32_R_SYM(rela[i].r_info); - - if (symbol > symtab_count) { - DEBUG_FUNCTION_LINE("symbol > symtab_count\n"); - return false; - } - - switch (symtab[symbol].st_shndx) { - case SHN_ABS: { - symbol_addr = symtab[symbol].st_value; - break; - } - case SHN_COMMON: { - uint32_t align = symtab[symbol].st_value; - uint32_t size = symtab[symbol].st_size; - - uint32_t address = pluginData->getMemoryForCommonBySymbol(symbol, align, size); - if(address == 0) { - DEBUG_FUNCTION_LINE("Failed to get memory for common relocation\n"); - return false; - } - - if (!ElfTools::elfLinkOne(ELF32_R_TYPE(rela[i].r_info), rela[i].r_offset,rela[i].r_addend, destination, address)) { - DEBUG_FUNCTION_LINE("elfLinkOne failed\n"); - return false; - } - - break; - } - case SHN_UNDEF: { - if (allow_globals) { - char *name = elf_strptr(elf, symtab_strndx, symtab[symbol].st_name); - DEBUG_FUNCTION_LINE("The elf still have unresolved relocations. This is not supported: %s \n",name); - - /* - - char *name = elf_strptr(elf, symtab_strndx, symtab[symbol].st_name); - DEBUG_FUNCTION_LINE("%s %08X\n",name,symtab[symbol].st_value); - - Not support and not needed. - module_unresolved_relocation_t *reloc; - char *name; - - reloc = (module_unresolved_relocation_t *) Module_ListAllocate( - &module_relocations, - sizeof(module_unresolved_relocation_t), 1, - &module_relocations_capacity, - &module_relocations_count, - PLUGIN_RELOCATIONS_CAPCITY_DEFAULT); - if (reloc == NULL) - return false; - - name = elf_strptr( - elf, symtab_strndx, symtab[symbol].st_name); - - if (name == NULL) { - module_relocations_count--; - return false; - } - - reloc->name = strdup(name); - if (reloc->name == NULL) { - module_relocations_count--; - return false; - } - - DEBUG_FUNCTION_LINE("Adding relocation!\n"); - - reloc->module = index; - reloc->address = destination; - reloc->offset = rela[i].r_offset; - reloc->type = ELF32_R_TYPE(rela[i].r_info); - reloc->addend = rela[i].r_addend; - - continue;*/ - continue; - } else { - DEBUG_FUNCTION_LINE("case SHN_UNDEF with !allow_global\n"); - return false; - } - } - default: { - if (symtab[symbol].st_other != 1) { - char *name = elf_strptr(elf, symtab_strndx, symtab[symbol].st_name); - if(pluginData == NULL) { - DEBUG_FUNCTION_LINE("No plugin data provided, but we (probably) need it.\n"); - return false; - } - - ImportRPLInformation * rplInfo = pluginData->getImportRPLInformationBySectionHeaderIndex(symtab[symbol].st_shndx); - if(rplInfo == NULL) { - DEBUG_FUNCTION_LINE("Couldn't find ImportRPLInformation for section header index %d \n", symtab[symbol].st_shndx); - return false; - } - RelocationData * relocationData = new RelocationData(ELF32_R_TYPE(rela[i].r_info), rela[i].r_offset,rela[i].r_addend, destination, name, rplInfo); - pluginData->addRelocationData(relocationData); - - continue; - } - symbol_addr = symtab[symbol].st_value; - break; - } - } - - if (!ElfTools::elfLinkOne(ELF32_R_TYPE(rela[i].r_info), rela[i].r_offset,rela[i].r_addend, destination, symbol_addr)) { - DEBUG_FUNCTION_LINE("elfLinkOne failed\n"); - return false; - } - } - break; - } - } - } - - return true; -} - -bool ElfTools::elfLinkOne(char type, size_t offset, int32_t addend, void *destination, uint32_t symbol_addr) { - int32_t value; - char *target = (char *)destination + offset; - bool result = false; - - switch (type) { - case R_PPC_ADDR32: - case R_PPC_ADDR24: - case R_PPC_ADDR16: - case R_PPC_ADDR16_HI: - case R_PPC_ADDR16_HA: - case R_PPC_ADDR16_LO: - case R_PPC_ADDR14: - case R_PPC_ADDR14_BRTAKEN: - case R_PPC_ADDR14_BRNTAKEN: - case R_PPC_UADDR32: - case R_PPC_UADDR16: { - value = (int32_t)symbol_addr + addend; - break; - } - case R_PPC_REL24: - case R_PPC_PLTREL24: - case R_PPC_LOCAL24PC: - case R_PPC_REL14: - case R_PPC_REL14_BRTAKEN: - case R_PPC_REL14_BRNTAKEN: - case R_PPC_REL32: - case R_PPC_ADDR30: { - value = (int32_t)symbol_addr + addend - (int32_t)target; - break; - } - case R_PPC_SECTOFF: - case R_PPC_SECTOFF_LO: - case R_PPC_SECTOFF_HI: - case R_PPC_SECTOFF_HA: { - value = offset + addend; - break; - } - case R_PPC_EMB_NADDR32: - case R_PPC_EMB_NADDR16: - case R_PPC_EMB_NADDR16_LO: - case R_PPC_EMB_NADDR16_HI: - case R_PPC_EMB_NADDR16_HA: { - value = addend - (int32_t)symbol_addr; - break; - } - default: - DEBUG_FUNCTION_LINE("Unknown relocation type: %02X for offset %08X\n",type,offset); - goto exit_error; - } - - switch (type) { - case R_PPC_ADDR32: - case R_PPC_UADDR32: - case R_PPC_REL32: - case R_PPC_SECTOFF: - case R_PPC_EMB_NADDR32: { - *(int32_t *)target = value; - break; - } - case R_PPC_ADDR24: - case R_PPC_PLTREL24: - case R_PPC_LOCAL24PC: - case R_PPC_REL24: { - *(int32_t *)target = - (*(int32_t *)target & 0xfc000003) | (value & 0x03fffffc); - break; - } - case R_PPC_ADDR16: - case R_PPC_UADDR16: - case R_PPC_EMB_NADDR16: { - *(short *)target = value; - break; - } - case R_PPC_ADDR16_HI: - case R_PPC_SECTOFF_HI: - case R_PPC_EMB_NADDR16_HI: { - *(short *)target = value >> 16; - break; - } - case R_PPC_ADDR16_HA: - case R_PPC_SECTOFF_HA: - case R_PPC_EMB_NADDR16_HA: { - *(short *)target = (((value >> 16) + ((value & 0x8000) ? 1 : 0))) & 0xFFFF; - break; - } - case R_PPC_ADDR16_LO: - case R_PPC_SECTOFF_LO: - case R_PPC_EMB_NADDR16_LO: { - *(short *)target = value & 0xffff; - break; - } - case R_PPC_ADDR14: - case R_PPC_REL14: { - *(int32_t *)target = - (*(int32_t *)target & 0xffff0003) | (value & 0x0000fffc); - break; - } - case R_PPC_ADDR14_BRTAKEN: - case R_PPC_REL14_BRTAKEN: { - *(int32_t *)target = - (*(int32_t *)target & 0xffdf0003) | (value & 0x0000fffc) | - 0x00200000; - break; - } - case R_PPC_ADDR14_BRNTAKEN: - case R_PPC_REL14_BRNTAKEN: { - *(int32_t *)target = - (*(int32_t *)target & 0xffdf0003) | (value & 0x0000fffc); - break; - } - case R_PPC_ADDR30: { - *(int32_t *)target = - (*(int32_t *)target & 0x00000003) | (value & 0xfffffffc); - break; - } - default: - goto exit_error; - } - - result = true; -exit_error: - if (!result) - DEBUG_FUNCTION_LINE("Plugin_ElfLinkOne: exit_error\n"); - return result; -} - diff --git a/src/plugin/ElfTools.h b/src/plugin/ElfTools.h deleted file mode 100644 index e58c473..0000000 --- a/src/plugin/ElfTools.h +++ /dev/null @@ -1,52 +0,0 @@ -/* based on module.c - * by Alex Chadwick - * - * Copyright (C) 2014, Alex Chadwick - * Modified 2018, Maschell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _ELF_TOOLS_H_ -#define _ELF_TOOLS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "libelf/libelf.h" - -#ifdef __cplusplus -} -#endif - - -#include "PluginData.h" - -class ElfTools { - -public: - static bool elfLoadSection(const Elf *elf, Elf_Scn *scn, const Elf32_Shdr *shdr,void *destination); - static bool loadElfSymtab(Elf *elf, Elf32_Sym **symtab, size_t *symtab_count, size_t *symtab_strndx); - static void elfLoadSymbols(size_t shndx, const void *destination, Elf32_Sym *symtab, size_t symtab_count); - static bool elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *symtab, size_t symtab_count, size_t symtab_strndx, bool allow_globals, PluginData * pluginData = NULL); - static bool elfLinkOne(char type, size_t offset, int32_t addend, void *destination, uint32_t symbol_addr); -}; - -#endif diff --git a/src/plugin/ImportRPLInformation.h b/src/plugin/ImportRPLInformation.h deleted file mode 100644 index 17273a5..0000000 --- a/src/plugin/ImportRPLInformation.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** - * 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 . - ****************************************************************************/ - -#ifndef _IMPORT_RPL_INFORMATION_H_ -#define _IMPORT_RPL_INFORMATION_H_ - -#include -#include - -class ImportRPLInformation { - -public: - ImportRPLInformation(int32_t section_header_index, std::string name, bool isData = false) { - this->name = name; - this->section_header_index = section_header_index; - this->_isData = isData; - } - - ~ImportRPLInformation() { - - } - - static ImportRPLInformation * createImportRPLInformation(int32_t section_header_index, std::string rawSectionName) { - std::string fimport = ".fimport_"; - std::string dimport = ".dimport_"; - - bool data = false; - - std::string rplName = ""; - - if(rawSectionName.size() < fimport.size()) { - return NULL; - } else if (std::equal(fimport.begin(), fimport.end(), rawSectionName.begin())) { - rplName = rawSectionName.substr(fimport.size()); - } else if (std::equal(dimport.begin(), dimport.end(), rawSectionName.begin())) { - rplName = rawSectionName.substr(dimport.size()); - data = true; - } else { - DEBUG_FUNCTION_LINE("invalid section name\n"); - return NULL; - } - DEBUG_FUNCTION_LINE("Adding %s of section index %02X. %d\n",rplName.c_str(),section_header_index,data); - return new ImportRPLInformation(section_header_index, rplName, data); - } - - std::string getName() { - return name; - } - - int32_t getSectionHeaderIndex() { - return section_header_index; - } - - bool isData() { - return _isData; - } - -private: - std::string name; - bool _isData = false; - int32_t section_header_index = 0; -}; - - -#endif diff --git a/src/plugin/PluginData.cpp b/src/plugin/PluginData.cpp deleted file mode 100644 index 3fa9544..0000000 --- a/src/plugin/PluginData.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** - * 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 . - ****************************************************************************/ - -#include -#include -#include -#include "PluginData.h" -#include "PluginLoader.h" - -ImportRPLInformation * PluginData::getImportRPLInformationBySectionHeaderIndex(int32_t section_header_index) { - for(size_t i = 0; i< importRPLInformation_list.size(); i++) { - if(importRPLInformation_list[i] != NULL && importRPLInformation_list[i]->getSectionHeaderIndex() == section_header_index) { - return importRPLInformation_list[i]; - } - } - return NULL; -} - -uint32_t PluginData::getMemoryForCommonBySymbol(size_t symbol, size_t align, size_t size) { - std::map::iterator it = memoryBySymbol.find(symbol); - if(it == memoryBySymbol.end()) { - memoryBySymbol[symbol] = PluginLoader::getMemoryFromDataSection(align, size); - DEBUG_FUNCTION_LINE("Setting value %08X\n",memoryBySymbol.find(symbol)->second); - } else { - DEBUG_FUNCTION_LINE("Using cached value %08X\n",memoryBySymbol.find(symbol)->second); - } - - return memoryBySymbol.find(symbol)->second; -} diff --git a/src/plugin/PluginData.h b/src/plugin/PluginData.h deleted file mode 100644 index dd58ea2..0000000 --- a/src/plugin/PluginData.h +++ /dev/null @@ -1,165 +0,0 @@ -/**************************************************************************** - * 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 . - ****************************************************************************/ - -#ifndef _PLUGIN_DATA_H_ -#define _PLUGIN_DATA_H_ - -#include -#include -#include -#include "FunctionData.h" -#include "HookData.h" -#include "PluginInformation.h" -#include "RelocationData.h" -#include "ImportRPLInformation.h" -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#ifdef __cplusplus -} -#endif - -class PluginData { -public: - PluginData(PluginInformation * pluginInformation) { - this->pluginInformation = pluginInformation; - } - - ~PluginData() { - for(size_t i = 0; i< function_data_list.size(); i++) { - if(function_data_list[i] != NULL) { - delete function_data_list[i]; - } - } - - for(size_t i = 0; i< hook_data_list.size(); i++) { - if(hook_data_list[i] != NULL) { - delete hook_data_list[i]; - } - } - - for(size_t i = 0; i< relocation_data_list.size(); i++) { - if(relocation_data_list[i] != NULL) { - delete relocation_data_list[i]; - } - } - - for(size_t i = 0; i< importRPLInformation_list.size(); i++) { - if(importRPLInformation_list[i] != NULL) { - delete importRPLInformation_list[i]; - } - } - } - - void addFunctionData(FunctionData * function_data) { - function_data_list.push_back(function_data); - } - - std::vector getFunctionDataList() { - return function_data_list; - } - - void addHookData(HookData * hook_data) { - hook_data_list.push_back(hook_data); - } - - void setBSSLocation(uint32_t addr, uint32_t size) { - this->bssAddr = addr; - this->bssSize = size; - } - - void setSBSSLocation(uint32_t addr, uint32_t size) { - this->sbssAddr = addr; - this->sbssSize = size; - } - - std::vector getHookDataList() { - return hook_data_list; - } - - void addRelocationData(RelocationData * relocation_data) { - relocation_data_list.push_back(relocation_data); - } - - std::vector getRelocationDataList() { - return relocation_data_list; - } - - void addImportRPLInformation(ImportRPLInformation * importRPLInformation) { - importRPLInformation_list.push_back(importRPLInformation); - } - - std::vector getImportRPLInformationList() { - return importRPLInformation_list; - } - - /** - Returns a ImportRPLInformation for a given section header index. - - \param section_header_index: ID of section in elf, started counting at 1. - - \return A pointer to the corresponding ImportRPLInformation, return NULL if no corresponding information was found. - **/ - ImportRPLInformation * getImportRPLInformationBySectionHeaderIndex(int32_t section_header_index); - - - PluginInformation * getPluginInformation() { - return pluginInformation; - } - - uint32_t getMemoryForCommonBySymbol(size_t symbol, size_t align, size_t size); - - uint32_t getBSSAddr(){ - return bssAddr; - } - - uint32_t getBSSSize(){ - return bssSize; - } - - uint32_t getSBSSAddr(){ - return sbssAddr; - } - - uint32_t getSBSSSize(){ - return sbssSize; - } - -private: - - PluginInformation * pluginInformation; - - std::vector function_data_list; - std::vector hook_data_list; - std::vector relocation_data_list; - std::vector importRPLInformation_list; - - uint32_t bssAddr = 0; - uint32_t bssSize = 0; - uint32_t sbssAddr = 0; - uint32_t sbssSize = 0; - - std::map memoryBySymbol; -}; - - -#endif diff --git a/src/plugin/PluginInformation.cpp b/src/plugin/PluginInformation.cpp deleted file mode 100644 index 791f0ed..0000000 --- a/src/plugin/PluginInformation.cpp +++ /dev/null @@ -1,424 +0,0 @@ -/* based on plugin.c - * by Alex Chadwick - * - * Copyright (C) 2014, Alex Chadwick - * Modified 2018, Maschell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "PluginInformation.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ElfTools.h" - -bool PluginInformation::checkFileExtenstion(const char * path) { - if(path == NULL) { - return false; - } - const char *extension; - - /* find the file extension */ - extension = strrchr(path, '.'); - if (extension == NULL) { - extension = strchr(path, '\0'); - } else { - extension++; - } - - if(extension == NULL) { - return false; - } - - if (strcmp(extension, "mod") == 0 || - strcmp(extension, "o") == 0 || - strcmp(extension, "a") == 0 || - strcmp(extension, "elf") == 0) { - return true; - } - return false; -} - -bool PluginInformation::openAndParseElf() { - bool result = false; - int32_t fd = -1; - Elf *elf = NULL; - - /* check for compile errors */ - if (elf_version(EV_CURRENT) == EV_NONE) { - goto exit_error; - } - - fd = open(getPath().c_str(), O_RDONLY, 0); - - if (fd == -1) { - DEBUG_FUNCTION_LINE("failed to open '%s' \n", getPath().c_str()); - goto exit_error; - } - - elf = elf_begin(fd, ELF_C_READ, NULL); - - if (elf == NULL) { - DEBUG_FUNCTION_LINE("elf was NULL\n"); - goto exit_error; - } - - switch (elf_kind(elf)) { - case ELF_K_AR: - /* TODO */ - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Archives not yet supported.\n", getPath().c_str()); - goto exit_error; - case ELF_K_ELF: - result = this->parseElf(elf); - break; - default: - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Invalid ELF file.\n", getPath().c_str()); - goto exit_error; - } - -exit_error: - if (elf != NULL) { - elf_end(elf); - } - if (fd != -1) { - close(fd); - } - return result; -} - -bool PluginInformation::parseElf( Elf *elf) { - DEBUG_FUNCTION_LINE("Parsing.\n"); - bool res = false; - Elf_Scn *scn; - Elf32_Ehdr *ehdr; - char *ident; - size_t shstrndx, sz, symtab_count, symtab_strndx; - Elf32_Sym *symtab = NULL; - - size_t cur_size = 0; - - const char * path_c = getPath().c_str(); - - if(elf == NULL) { - goto exit_error; - } - if(elf_kind(elf) != ELF_K_ELF) { - goto exit_error; - } - - ident = elf_getident(elf, &sz); - - if (ident == NULL) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Invalid ELF header.\n", path_c); - goto exit_error; - } - if (sz < 7) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Invalid ELF header.\n", path_c); - goto exit_error; - } - if (ident[4] != ELFCLASS32) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Not 32 bit ELF.\n", path_c); - goto exit_error; - } - if (ident[5] != ELFDATA2MSB) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Not Big Endian.\n", path_c); - goto exit_error; - } - if (ident[6] != EV_CURRENT) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Unknown ELF version.\n", path_c); - goto exit_error; - } - - ehdr = elf32_getehdr(elf); - - if (ehdr == NULL) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Invalid ELF header\n", path_c); - goto exit_error; - } - /*if (ehdr->e_type != ET_REL) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Not relocatable ELF.\n", path_c); - goto exit_error; - }*/ - if (ehdr->e_machine != EM_PPC) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Architecture not EM_PPC.\n", path_c); - goto exit_error; - } - if (ehdr->e_version != EV_CURRENT) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Unknown ELF version.\n", path_c); - goto exit_error; - } - - if (!ElfTools::loadElfSymtab(elf, &symtab, &symtab_count, &symtab_strndx)) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Couldn't parse symtab.\n", path_c); - goto exit_error; - } - - if(symtab == NULL) { - goto exit_error; - } - - if(!metadataRead(elf, symtab, symtab_count, symtab_strndx)) { - goto exit_error; - } - - if (elf_getshdrstrndx(elf, &shstrndx) != 0) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Couldn't find shdrstndx.\n", path_c); - goto exit_error; - } - - for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) { - Elf32_Shdr *shdr; - - shdr = elf32_getshdr(scn); - if (shdr == NULL) { - continue; - } - - if ((shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS) && - (shdr->sh_flags & SHF_ALLOC)) { - - const char *name; - - name = elf_strptr(elf, shstrndx, shdr->sh_name); - if (name == NULL) { - continue; - } - - if (strcmp(name, ".wups.meta") == 0) { - continue; - } else if (strcmp(name, ".wups.load") == 0) { - cur_size += - shdr->sh_size / sizeof(wups_loader_entry_t) * 6*4; - } else if (strcmp(name, ".wups.hooks") == 0) { - cur_size += - shdr->sh_size / sizeof(wups_loader_hook_t) * 2*4; - } else { - cur_size += shdr->sh_size; - /* add alignment padding to size */ - if (shdr->sh_addralign > 3) { - /* roundup to multiple of sh_addralign */ - cur_size += (-cur_size & (shdr->sh_addralign - 1)); - } else { - /* roundup to multiple of 4 */ - cur_size += (-cur_size & 3); - } - } - } - } - - /* roundup to multiple of 4 */ - cur_size += (-cur_size & 3); - - this->setSize(cur_size); - - res = true; -exit_error: - if (symtab != NULL) { - free(symtab); - } - - return res; -} - -bool PluginInformation::metadataRead(Elf *elf, Elf32_Sym *symtab, size_t symtab_count, size_t symtab_strndx) { - char *metadata = NULL, *metadata_cur, *metadata_end; - const char *name, *author, *version, *license, *wups, *buildtimestamp, *description; - - Elf_Scn *scn; - size_t shstrndx; - - if (elf_getshdrstrndx(elf, &shstrndx) != 0) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Couldn't find shstrndx\n", path); - goto exit_error; - } - - for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) { - Elf32_Shdr *shdr; - const char *name; - - shdr = elf32_getshdr(scn); - if (shdr == NULL) { - continue; - } - - name = elf_strptr(elf, shstrndx, shdr->sh_name); - if (name == NULL) { - continue; - } - - if (strcmp(name, ".wups.meta") == 0) { - if (shdr->sh_size == 0) { - continue; - } - - if (metadata != NULL) { - continue; - } - - metadata = (char*) malloc(shdr->sh_size); - - if (metadata == NULL) { - continue; - } - - if (!ElfTools::elfLoadSection(elf, scn, shdr, metadata)) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Couldn't load .wups.meta.\n", path); - goto exit_error; - } - - ElfTools::elfLoadSymbols(elf_ndxscn(scn), metadata, symtab, symtab_count); - - if (!ElfTools::elfLink(elf, elf_ndxscn(scn), metadata, symtab, symtab_count, symtab_strndx, false)) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - .wups.meta contains invalid relocations.\n", path); - goto exit_error; - } - - metadata_end = metadata + shdr->sh_size; - metadata_end[-1] = '\0'; - } - } - - if (metadata == NULL) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Not a WUPS plugin file.\n", path); - goto exit_error; - } - - name = NULL; - author = NULL; - version = NULL; - license = NULL; - wups = NULL; - buildtimestamp = NULL; - description = NULL; - - for (metadata_cur = metadata; metadata_cur < metadata_end; metadata_cur = strchr(metadata_cur, '\0') + 1) { - - char *eq; - - if(metadata_cur < metadata || metadata_cur >= metadata_end) { - goto exit_error; - } - - if (*metadata_cur == '\0') { - continue; - } - - eq = strchr(metadata_cur, '='); - if (eq == NULL) { - continue; - } - - if (strncmp(metadata_cur, "name", eq - metadata_cur) == 0) { - if (name != NULL) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Multiple WUPS_PLUGIN_NAME declarations.\n", path); - goto exit_error; - } - name = eq + 1; - } else if (strncmp(metadata_cur, "author", eq - metadata_cur) == 0) { - if (author != NULL) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Multiple WUPS_PLUGIN_AUTHOR declarations.\n", path); - goto exit_error; - } - author = eq + 1; - } else if (strncmp(metadata_cur, "version", eq - metadata_cur) == 0) { - if (version != NULL) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Multiple WUPS_PLUGIN_VERSION declarations.\n", path); - goto exit_error; - } - version = eq + 1; - } else if (strncmp(metadata_cur, "license", eq - metadata_cur) == 0) { - if (license != NULL) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Multiple WUPS_PLUGIN_LICENSE declarations.\n", path); - goto exit_error; - } - license = eq + 1; - } else if (strncmp(metadata_cur, "buildtimestamp", eq - metadata_cur) == 0) { - if (buildtimestamp != NULL) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Multiple WUPS_PLUGIN_TIMESTAMP declarations.\n", path); - goto exit_error; - } - buildtimestamp = eq + 1; - } else if (strncmp(metadata_cur, "description", eq - metadata_cur) == 0) { - if (description != NULL) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Multiple WUPS_PLUGIN_LICENSE declarations.\n", path); - goto exit_error; - } - description = eq + 1; - } else if (strncmp(metadata_cur, "wups", eq - metadata_cur) == 0) { - if (wups != NULL) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Multiple WUPS_PLUGIN_NAME declarations.\n", path); - goto exit_error; - } - wups = eq + 1; - } - } - - if (description == NULL) { - description = ""; - } - - if (wups == NULL || strcmp(wups, "0.2") != 0) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Unrecognised WUPS version.\n", path); - goto exit_error; - } - if (buildtimestamp == NULL) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Couldn't find buildtimestamp.\n", path); - goto exit_error; - } - if (name == NULL) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Missing WUPS_PLUGIN_NAME declaration.\n",path); - goto exit_error; - } - if (author == NULL) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Missing WUPS_PLUGIN_AUTHOR declaration.\n", path); - goto exit_error; - } - if (version == NULL) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Missing WUPS_PLUGIN_VERSION declaration.\n", path); - goto exit_error; - } - if (license == NULL) { - DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Missing WUPS_PLUGIN_LICENSE declaration.\n", path); - goto exit_error; - } - - this->setName(name); - this->setAuthor(author); - this->setVersion(version); - this->setLicense(license); - this->setBuildTimestamp(buildtimestamp); - this->setDescription(description); - - return true; - -exit_error: - - if (metadata != NULL) { - free(metadata); - } - return false; -} diff --git a/src/plugin/PluginInformation.h b/src/plugin/PluginInformation.h deleted file mode 100644 index 67034ce..0000000 --- a/src/plugin/PluginInformation.h +++ /dev/null @@ -1,151 +0,0 @@ -/* based on module.c - * by Alex Chadwick - * - * Copyright (C) 2014, Alex Chadwick - * Modified 2018, Maschell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _PLUGIN_INFORMATION_H_ -#define _PLUGIN_INFORMATION_H_ - -#include -#include -#include "FunctionData.h" -#include "HookData.h" -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#ifdef __cplusplus -} -#endif - -class PluginInformation { -public: - /** - - returns PluginInformation* if a valid plugin was found at the given path. Otherwise returns NULL - **/ - static PluginInformation * loadPluginInformation(std::string path) { - if(PluginInformation::checkFileExtenstion(path.c_str())) { - DEBUG_FUNCTION_LINE("Checkfile successfully, loading now Plugin Information\n"); - PluginInformation * pluginInformation = new PluginInformation(path); - if(pluginInformation->openAndParseElf()) { - return pluginInformation; - } else { - delete pluginInformation; - return NULL; - } - } else { - return NULL; - } - } - - std::string getName() { - return this->name; - } - - std::string getAuthor() { - return this->author; - } - - std::string getVersion() { - return this->version; - } - - std::string getLicense() { - return this->license; - } - - std::string getBuildTimestamp() { - return this->buildtimestamp; - } - - std::string getDescription() { - return this->description; - } - - std::string getPath() { - return path; - } - - size_t getSize() { - return this->size; - } -private: - PluginInformation(std::string path) { - this->path = path; - } - - void setName(const char * name) { - this->name = name; - } - - void setAuthor(const char * author) { - this->author = author; - } - - void setVersion(const char * version) { - this->version = version; - } - - void setLicense(const char * license) { - this->license = license; - } - - void setBuildTimestamp(const char * buildtimestamp) { - this->buildtimestamp = buildtimestamp; - } - - void setDescription(const char * description) { - this->description = description; - } - - void setSize(size_t size) { - this->size = size; - } - - static bool checkFileExtenstion(const char * path); - - bool openAndParseElf(); - - bool parseElf(Elf *elf); - - bool metadataRead(Elf *elf, Elf32_Sym *symtab, size_t symtab_count, size_t symtab_strndx); - - bool loadedSuccessfully = false; - - std::string path; - std::string name; - std::string author; - std::string version; - std::string license; - std::string buildtimestamp; - std::string description; - size_t size; -}; - - -#endif diff --git a/src/plugin/PluginLoader.cpp b/src/plugin/PluginLoader.cpp deleted file mode 100644 index c7b41ec..0000000 --- a/src/plugin/PluginLoader.cpp +++ /dev/null @@ -1,544 +0,0 @@ -/* based on module.c - * by Alex Chadwick - * - * Copyright (C) 2014, Alex Chadwick - * Modified 2018, Maschell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include "ElfTools.h" -#include "PluginData.h" -#include "PluginLoader.h" -#include "DynamicLinkingHelper.h" -#include "utils/StringTools.h" -#include "common/retain_vars.h" - -PluginLoader * PluginLoader::instance = NULL; - -std::vector PluginLoader::getPluginInformation(const char * path) { - std::vector result; - struct dirent *dp; - DIR *dfd = NULL; - - if(path == NULL) { - DEBUG_FUNCTION_LINE("Path was NULL\n"); - return result; - } - - if ((dfd = opendir(path)) == NULL) { - DEBUG_FUNCTION_LINE("Couldn't open dir %s\n",path); - return result; - } - - while ((dp = readdir(dfd)) != NULL) { - struct stat stbuf ; - std::string full_file_path = StringTools::strfmt("%s/%s",path,dp->d_name); - StringTools::RemoveDoubleSlashs(full_file_path); - if( stat(full_file_path.c_str(),&stbuf ) == -1 ) { - DEBUG_FUNCTION_LINE("Unable to stat file: %s\n",full_file_path.c_str()) ; - continue; - } - - if ( ( stbuf.st_mode & S_IFMT ) == S_IFDIR ) { // Skip directories - continue; - } else { - DEBUG_FUNCTION_LINE("Found file: %s\n",full_file_path.c_str()) ; - PluginInformation * plugin = PluginInformation::loadPluginInformation(full_file_path); - if(plugin != NULL) { - DEBUG_FUNCTION_LINE("Found plugin %s by %s. Built on %s Size: %d kb \n",plugin->getName().c_str(),plugin->getAuthor().c_str(),plugin->getBuildTimestamp().c_str(),plugin->getSize()/1024) ; - DEBUG_FUNCTION_LINE("Description: %s \n",plugin->getDescription().c_str()) ; - result.push_back(plugin); - } else { - DEBUG_FUNCTION_LINE("%s is not a valid plugin\n",full_file_path.c_str()) ; - } - } - } - if(dfd != NULL) { - closedir(dfd); - } - - return result; -} - -std::vector PluginLoader::getPluginsLoadedInMemory() { - std::vector pluginInformation; - for(int32_t i = 0; i < gbl_replacement_data.number_used_plugins; i++) { - replacement_data_plugin_t * pluginInfo = &gbl_replacement_data.plugin_data[i]; - PluginInformation * curPlugin = PluginInformation::loadPluginInformation(pluginInfo->path); - if(curPlugin != NULL) { - pluginInformation.push_back(curPlugin); - } - } - return pluginInformation; -} - -bool PluginLoader::loadAndLinkPlugins(std::vector pluginInformation) { - std::vector loadedPlugins; - bool success = true; - for(size_t i = 0; i < pluginInformation.size(); i++) { - PluginInformation * cur_info = pluginInformation[i]; - PluginData * pluginData = loadAndLinkPlugin(cur_info); - if(pluginData == NULL) { - DEBUG_FUNCTION_LINE("loadAndLinkPlugins failed for %d\n",i) ; - success = false; - continue; - } else { - loadedPlugins.push_back(pluginData); - } - } - - PluginLoader::flushCache(); - - if(success) { - copyPluginDataIntoGlobalStruct(loadedPlugins); - } else { - PluginLoader::resetPluginLoader(); - memset((void*)&gbl_replacement_data,0,sizeof(gbl_replacement_data)); - } - - clearPluginData(loadedPlugins); - - return success; -} - -void PluginLoader::clearPluginData(std::vector pluginData) { - for(size_t i = 0; i < pluginData.size(); i++) { - PluginData * curPluginData = pluginData[i]; - if(curPluginData != NULL) { - delete curPluginData; - } - } -} - -void PluginLoader::clearPluginInformation(std::vector pluginInformation) { - for(size_t i = 0; i < pluginInformation.size(); i++) { - PluginInformation * curPluginInformation = pluginInformation[i]; - if(curPluginInformation != NULL) { - delete curPluginInformation; - } - } -} - -PluginData * PluginLoader::loadAndLinkPlugin(PluginInformation * pluginInformation) { - PluginData * result = NULL; - int32_t fd = -1; - Elf *elf = NULL; - - if(pluginInformation == NULL) { - DEBUG_FUNCTION_LINE("pluginInformation was NULL\n"); - goto exit_error; - } - - if(pluginInformation->getSize() > ((uint32_t) getAvailableSpace())) { - DEBUG_FUNCTION_LINE("Not enough space left to loader the plugin into memory %08X %08X\n",pluginInformation->getSize(),getAvailableSpace()); - goto exit_error; - } - - /* check for compile errors */ - if (elf_version(EV_CURRENT) == EV_NONE) { - goto exit_error; - } - - fd = open(pluginInformation->getPath().c_str(), O_RDONLY, 0); - - if (fd == -1) { - DEBUG_FUNCTION_LINE("failed to open '%s' \n", pluginInformation->getPath().c_str()); - goto exit_error; - } - - elf = elf_begin(fd, ELF_C_READ, NULL); - - if (elf == NULL) { - DEBUG_FUNCTION_LINE("elf was NULL\n"); - goto exit_error; - } - - result = new PluginData(pluginInformation); - if(result == NULL) { - DEBUG_FUNCTION_LINE("Failed to create object\n"); - goto exit_error; - } - - if(!this->loadAndLinkElf(result, elf, this->getCurrentStoreAddress())) { - delete result; - result = NULL; - } - -exit_error: - if (elf != NULL) { - elf_end(elf); - } - if (fd != -1) { - close(fd); - } - return result; -} - -bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * startAddress) { - if(pluginData == NULL || elf == NULL || startAddress == NULL) { - return false; - } - - uint32_t curAddress = (uint32_t) startAddress; - uint32_t firstCurAddress = (uint32_t) startAddress; - - Elf_Scn *scn; - size_t symtab_count, section_count, shstrndx, symtab_strndx, entries_count, hooks_count; - Elf32_Sym *symtab = NULL; - uint8_t **destinations = NULL; - wups_loader_entry_t *entries = NULL; - wups_loader_hook_t *hooks = NULL; - bool result = false; - - int32_t i = 1; - - std::vector entry_t_list; - std::vector hook_t_list; - - std::vector function_data_list; - std::vector hook_data_list; - - if (!ElfTools::loadElfSymtab(elf, &symtab, &symtab_count, &symtab_strndx)) { - goto exit_error; - } - - if(symtab == NULL) { - goto exit_error; - } - - if (elf_getshdrnum(elf, §ion_count) != 0) { - goto exit_error; - } - if (elf_getshdrstrndx(elf, &shstrndx) != 0) { - goto exit_error; - } - - destinations = (uint8_t **) malloc(sizeof(uint8_t *) * section_count); - - DEBUG_FUNCTION_LINE("Copy sections\n"); - - for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) { - Elf32_Shdr *shdr; - - shdr = elf32_getshdr(scn); - if (shdr == NULL) { - continue; - } - - if ((shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS) && - (shdr->sh_flags & SHF_ALLOC)) { - - const char *name; - - destinations[elf_ndxscn(scn)] = NULL; - - name = elf_strptr(elf, shstrndx, shdr->sh_name); - if (name == NULL) { - DEBUG_FUNCTION_LINE("name is null\n"); - continue; - } - - if (strcmp(name, ".wups.meta") == 0) { - continue; - } else if (strcmp(name, ".wups.load") == 0) { - if (entries != NULL) { - DEBUG_FUNCTION_LINE("entries != NULL\n"); - goto exit_error; - } - - entries_count = shdr->sh_size / sizeof(wups_loader_entry_t); - entries = (wups_loader_entry_t *) malloc(sizeof(wups_loader_entry_t) * entries_count); - - if (entries == NULL) { - DEBUG_FUNCTION_LINE("entries == NULL\n"); - goto exit_error; - } - - // We need to subtract the sh_addr because it will be added later in the relocations. - destinations[elf_ndxscn(scn)] = (uint8_t *)entries - (shdr->sh_addr); - - if (!ElfTools::elfLoadSection(elf, scn, shdr, entries)) { - DEBUG_FUNCTION_LINE("elfLoadSection failed\n"); - goto exit_error; - } - - ElfTools::elfLoadSymbols(elf_ndxscn(scn), entries- (shdr->sh_addr), symtab, symtab_count); - - for(size_t i = 0; i< entries_count; i++) { - entry_t_list.push_back(&entries[i]); - } - } else if (strcmp(name, ".wups.hooks") == 0) { - if (hooks != NULL) { - DEBUG_FUNCTION_LINE("hooks != NULL\n"); - goto exit_error; - } - - hooks_count = shdr->sh_size / sizeof(wups_loader_hook_t); - hooks = (wups_loader_hook_t *) malloc(sizeof(wups_loader_hook_t) * hooks_count); - - if (hooks == NULL) { - DEBUG_FUNCTION_LINE("hooks == NULL\n"); - goto exit_error; - } - - // We need to subtract the sh_addr because it will be added later in the relocations. - uint32_t destination = (uint32_t)hooks - (shdr->sh_addr); - destinations[elf_ndxscn(scn)] = (uint8_t *)destination; - if (!ElfTools::elfLoadSection(elf, scn, shdr, hooks)) { - DEBUG_FUNCTION_LINE("elfLoadSection failed\n"); - goto exit_error; - } - ElfTools::elfLoadSymbols(elf_ndxscn(scn), (void *) destination, symtab, symtab_count); - - for(size_t i = 0; i< hooks_count; i++) { - hook_t_list.push_back(&hooks[i]); - } - - } else { - uint32_t destination = firstCurAddress + shdr->sh_addr; - destinations[elf_ndxscn(scn)] = (uint8_t *) firstCurAddress; - - if((uint32_t) destination + shdr->sh_size > (uint32_t) this->endAddress) { - DEBUG_FUNCTION_LINE("Not enough space to load function %s into memory at %08X.\n",name,destination); - goto exit_error; - } - - DEBUG_FUNCTION_LINE("Copy section %s to %08X\n",name,destination); - if (!ElfTools::elfLoadSection(elf, scn, shdr, (void*) destination)) { - DEBUG_FUNCTION_LINE("elfLoadSection failed\n"); - goto exit_error; - } - ElfTools::elfLoadSymbols(elf_ndxscn(scn), (void*) firstCurAddress, symtab, symtab_count); - - if(strcmp(name, ".bss") == 0){ - pluginData->setBSSLocation(destination, shdr->sh_size); - DEBUG_FUNCTION_LINE("Saved .bss section info. Location: %08X size: %08X\n", destination, shdr->sh_size); - } - - curAddress = ROUNDUP(destination + shdr->sh_size,0x100); - } - } - } - - for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) { - Elf32_Shdr *shdr; - - shdr = elf32_getshdr(scn); - if (shdr == NULL) { - continue; - } - const char *name; - - name = elf_strptr(elf, shstrndx, shdr->sh_name); - if (name == NULL) { - DEBUG_FUNCTION_LINE("name is null\n"); - continue; - } - if(shdr->sh_type == 0x80000002) { - ImportRPLInformation * info = ImportRPLInformation::createImportRPLInformation(i,name); - if(info != NULL) { - pluginData->addImportRPLInformation(info); - } - } - i++; - } - i = 0; - - for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) { - Elf32_Shdr *shdr; - - shdr = elf32_getshdr(scn); - if (shdr == NULL) { - continue; - } - - const char *name; - - name = elf_strptr(elf, shstrndx, shdr->sh_name); - if (name == NULL) { - DEBUG_FUNCTION_LINE("name is null\n"); - continue; - } - if ((shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS) && - (shdr->sh_flags & SHF_ALLOC) && - destinations[elf_ndxscn(scn)] != NULL) { - - DEBUG_FUNCTION_LINE("Linking (%d)... %s\n",i++,name); - if (!ElfTools::elfLink(elf, elf_ndxscn(scn), destinations[elf_ndxscn(scn)], symtab, symtab_count, symtab_strndx, true, pluginData)) { - DEBUG_FUNCTION_LINE("elfLink failed\n"); - goto exit_error; - } - } - } - DEBUG_FUNCTION_LINE("Linking done \n"); - - for(size_t j=0; jgetPluginInformation()->getName().c_str(),hook->type,(void*) hook->target); - HookData * hook_data = new HookData((void *) hook->target,hook->type); - pluginData->addHookData(hook_data); - } - - for(size_t j=0; j_function.name,pluginData->getPluginInformation()->getName().c_str(),cur_function->_function.physical_address,cur_function->_function.virtual_address, cur_function->_function.library,cur_function->_function.target, (void *) cur_function->_function.call_addr); - FunctionData * function_data = new FunctionData((void *) cur_function->_function.physical_address,(void *) cur_function->_function.virtual_address, cur_function->_function.name, cur_function->_function.library, (void *) cur_function->_function.target, (void *) cur_function->_function.call_addr); - pluginData->addFunctionData(function_data); - } - - this->setCurrentStoreAddress((void *) curAddress); - - result = true; -exit_error: - if (!result) { - DEBUG_FUNCTION_LINE("exit_error\n"); - } - if (destinations != NULL) { - free(destinations); - } - if (symtab != NULL) { - free(symtab); - } - if (hooks != NULL) { - free(hooks); - } - if (entries != NULL) { - free(entries); - } - return result; -} - -void PluginLoader::copyPluginDataIntoGlobalStruct(std::vector plugins) { - // Reset data - memset((void*)&gbl_replacement_data,0,sizeof(gbl_replacement_data)); - DynamicLinkingHelper::getInstance()->clearAll(); - int32_t plugin_index = 0; - // Copy data to global struct. - for(size_t i = 0; i< plugins.size(); i++) { - PluginData * cur_plugin = plugins.at(i); - PluginInformation * cur_pluginInformation = cur_plugin->getPluginInformation(); - - // Relocation - std::vector relocationData = cur_plugin->getRelocationDataList(); - for(size_t j = 0; j < relocationData.size(); j++) { - if(!DynamicLinkingHelper::getInstance()->addReloationEntry(relocationData[j])) { - DEBUG_FUNCTION_LINE("Adding relocation for %s failed. It won't be loaded.\n",cur_pluginInformation->getName().c_str()); - continue; - } else { - //relocationData[j]->printInformation(); - } - } - - // Other - std::vector function_data_list = cur_plugin->getFunctionDataList(); - std::vector hook_data_list = cur_plugin->getHookDataList(); - if(plugin_index >= MAXIMUM_PLUGINS ) { - DEBUG_FUNCTION_LINE("Maximum of %d plugins reached. %s won't be loaded!\n",MAXIMUM_PLUGINS,cur_pluginInformation->getName().c_str()); - continue; - } - if(function_data_list.size() > MAXIMUM_FUNCTION_PER_PLUGIN) { - DEBUG_FUNCTION_LINE("Plugin %s would replace to many function (%d, maximum is %d). It won't be loaded.\n",cur_pluginInformation->getName().c_str(),function_data_list.size(),MAXIMUM_FUNCTION_PER_PLUGIN); - continue; - } - if(hook_data_list.size() > MAXIMUM_HOOKS_PER_PLUGIN) { - DEBUG_FUNCTION_LINE("Plugin %s would set too many hooks (%d, maximum is %d). It won't be loaded.\n",cur_pluginInformation->getName().c_str(),hook_data_list.size(),MAXIMUM_HOOKS_PER_PLUGIN); - continue; - } - - replacement_data_plugin_t * plugin_data = &gbl_replacement_data.plugin_data[plugin_index]; - -#warning TODO: add GUI option to let the user choose - plugin_data->kernel_allowed = true; - plugin_data->kernel_init_done = false; - - plugin_data->bssAddr = cur_plugin->getBSSAddr(); - plugin_data->bssSize = cur_plugin->getBSSSize(); - plugin_data->sbssAddr = cur_plugin->getSBSSAddr(); - plugin_data->sbssSize = cur_plugin->getSBSSSize(); - - strncpy(plugin_data->plugin_name,cur_pluginInformation->getName().c_str(),MAXIMUM_PLUGIN_NAME_LENGTH-1); - strncpy(plugin_data->path,cur_pluginInformation->getPath().c_str(),MAXIMUM_PLUGIN_PATH_NAME_LENGTH-1); - - for(size_t j = 0; j < function_data_list.size(); j++) { - replacement_data_function_t * function_data = &plugin_data->functions[j]; - FunctionData * cur_function = function_data_list[j]; - - if(strlen(cur_function->getName().c_str()) > MAXIMUM_FUNCTION_NAME_LENGTH-1) { - DEBUG_FUNCTION_LINE("Couldn not add function \"%s\" for plugin \"%s\" function name is too long.\n",cur_function->getName().c_str(),plugin_data->plugin_name); - continue; - } - - DEBUG_FUNCTION_LINE("Adding function \"%s\" for plugin \"%s\"\n",cur_function->getName().c_str(),plugin_data->plugin_name); - - //TODO: Warning/Error if string is too long. - - strncpy(function_data->function_name,cur_function->getName().c_str(),MAXIMUM_FUNCTION_NAME_LENGTH-1); - - function_data->library = cur_function->getLibrary(); - function_data->replaceAddr = (uint32_t) cur_function->getReplaceAddress(); - function_data->replaceCall = (uint32_t) cur_function->getReplaceCall(); - function_data->physicalAddr = (uint32_t) cur_function->getPhysicalAddress(); - function_data->virtualAddr = (uint32_t) cur_function->getVirtualAddress(); - - plugin_data->number_used_functions++; - } - - DEBUG_FUNCTION_LINE("Entries for plugin \"%s\": %d\n",plugin_data->plugin_name,plugin_data->number_used_functions); - - for(size_t j = 0; j < hook_data_list.size(); j++) { - replacement_data_hook_t * hook_data = &plugin_data->hooks[j]; - - HookData * hook_entry = hook_data_list[j]; - - DEBUG_FUNCTION_LINE("Set hook for plugin \"%s\" of type %08X to target %08X\n",plugin_data->plugin_name,hook_entry->getType(),(void*) hook_entry->getFunctionPointer()); - hook_data->func_pointer = (void*) hook_entry->getFunctionPointer(); - hook_data->type = hook_entry->getType(); - plugin_data->number_used_hooks++; - } - - DEBUG_FUNCTION_LINE("Hooks for plugin \"%s\": %d\n",plugin_data->plugin_name,plugin_data->number_used_hooks); - - plugin_index++; - gbl_replacement_data.number_used_plugins++; - } - DCFlushRange((void*)&gbl_replacement_data,sizeof(gbl_replacement_data)); - ICInvalidateRange((void*)&gbl_replacement_data,sizeof(gbl_replacement_data)); -} - -uint32_t PluginLoader::getMemoryFromDataSection(size_t align, size_t size) { - uint32_t ptr = (uint32_t)gbl_common_data_ptr; - ptr = (ptr + (align - 1)) & -align; // Round up to align boundary - uint32_t result = ptr; - - if((result + size) >= (ptr + sizeof(gbl_common_data))) { - DEBUG_FUNCTION_LINE("No more space =( %08X > %08X\n",(result + size),(ptr + sizeof(gbl_common_data))); - return 0; - } - ptr += size; - gbl_common_data_ptr = (char *) ptr; - - return result; -} diff --git a/src/plugin/PluginLoader.h b/src/plugin/PluginLoader.h deleted file mode 100644 index ff03985..0000000 --- a/src/plugin/PluginLoader.h +++ /dev/null @@ -1,180 +0,0 @@ -/* based on module.c - * by Alex Chadwick - * - * Copyright (C) 2014, Alex Chadwick - * Modified 2018, Maschell - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _PLUGIN_LOADER_H_ -#define _PLUGIN_LOADER_H_ - -#include -#include "PluginData.h" -#include "PluginInformation.h" -#include "dynamic_libs/coreinit.h" -#include "memory/memory_mapping.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#ifdef __cplusplus -} -#endif - -extern char gbl_common_data[0x20000]; -extern char * gbl_common_data_ptr; - -#define PLUGIN_LOCATION_START_ADDRESS 0x00A00000 -#define PLUGIN_LOCATION_END_ADDRESS 0x01000000 - -class PluginLoader { - -public: - PluginLoader(void * startAddress, void * endAddress) { - // TODO: Check if endAddress > startAddress. - this->startAddress = startAddress; - this->endAddress = endAddress; - this->currentStoreAddress = (void*) ROUNDUP((uint32_t)startAddress, 0x10000); - } - - ~PluginLoader() { - - } - /** - \brief Parses the meta data of all plugins in the given directory. - - \param path the path of the directory which should be scanned. - - \return a list of PluginInformation objects, one for each valid plugin. - **/ - static std::vector getPluginInformation(const char * path); - - /** - \brief Gets plugin information from the global struct. - - \return a list of MetaInformation objects for all plugins currently loaded and linked (relocated). Will only contain - plugin which are still on the sd card. - **/ - static std::vector getPluginsLoadedInMemory(); - - /** - \brief Takes a list of plugins that should be linked (relocated) loaded into the memory. - The function that should be replaced will be replaced in the order of the given plugin list. - So two plugin will override the same function, the plugin first in this list will override the function first. - Also the hooks of the plugins will be called in the order their plugin where passed to this method. - - \param A list of plugin that should be linked (relocated) an loaded into memory - - \return Returns true if all plugins were linked successfully. Returns false if at least one plugin failed while linking. - **/ - bool loadAndLinkPlugins(std::vector pluginInformation); - - - static void flushCache() { - uint32_t startAddress = (uint32_t) PLUGIN_LOCATION_START_ADDRESS; - uint32_t endAddress = (uint32_t) PLUGIN_LOCATION_END_ADDRESS; - - DCFlushRange((void*)startAddress,(uint32_t)endAddress - (uint32_t)startAddress); - ICInvalidateRange((void*)startAddress,(uint32_t)endAddress - (uint32_t)startAddress); - } - - /** - \brief Iterates through the vector and delete all it's elements - - \param A list of PluginInformation* that should be deleted. - **/ - void clearPluginInformation(std::vector PluginInformation); - - size_t getTotalSpace() { - return ((uint32_t) this->endAddress - (uint32_t) this->startAddress); - } - - size_t getAvailableSpace() { - return ((uint32_t) this->endAddress - (uint32_t) this->currentStoreAddress); - } - - size_t getUsedSpace() { - return getTotalSpace() - getAvailableSpace(); - } - - void resetPluginLoader() { - this->currentStoreAddress = (void*) ROUNDUP((uint32_t)startAddress, 0x10000); - } - - static uint32_t getMemoryFromDataSection(size_t align, size_t size); - -private: - - - static PluginLoader *instance; - - /** - \brief Iterates through the vector and delete all it's elements - - \param A list of PluginData* that should be deleted. - **/ - void clearPluginData(std::vector pluginData); - - /** - \brief Load - - \param pluginInformation a PluginInformation object of the plugin that should be linked (relocated) and loaded. - - \return NULL on error. On success it will return a PluginData object. - **/ - PluginData * loadAndLinkPlugin(PluginInformation * pluginInformation); - - /** - \brief Loads a plugin into memory (in the startAddress/endAddress range defined in this loader) and relocates it. - Modifies the pluginData param. Adds loaded functions and hooks. - \param pluginData object where the result should be stored - \param elf source elf from where the sections will be loaded - \param storeAddressEnd the address where the plugin data will be stored in memory. Saving BACKWARD. - - **/ - bool loadAndLinkElf(PluginData * pluginData, Elf *elf, void * storeAddressEnd); - - /** - \brief Copies the needed information into a global, persistent struct. This struct holds information on which - function should be override in which order and which hook should be called. - \param plugins list of plugins that should be used. - - **/ - void copyPluginDataIntoGlobalStruct(std::vector plugins); - - void * getCurrentStoreAddress() { - return this->currentStoreAddress; - } - - void setCurrentStoreAddress(void * addr) { - this->currentStoreAddress = addr; - } - - void * startAddress = NULL; - void * endAddress = NULL; - void * currentStoreAddress = NULL; -}; - - -#endif diff --git a/src/settings/ConfigSettings.cpp b/src/settings/ConfigSettings.cpp deleted file mode 100644 index 75b15e3..0000000 --- a/src/settings/ConfigSettings.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 Dimok - * Modified by Maschell, 2018 for WiiU plugin system loader - * - * 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 . - ****************************************************************************/ -#include -#include -#include - -#include "ConfigSettings.h" -#include -#include -#include -#include -//#include - -#define VERSION_LINE "# WiiUPluginSystem - plugin settings file v" -#define VALID_VERSION 1 - -ConfigSettings::ConfigSettings(std::string configPath, std::string filename, std::map defaultValues, std::map settingsNames) { - bChanged = false; - memset(&nullValue, 0, sizeof(nullValue)); - nullValue.strValue = new std::string(); - - this->configPath = configPath; - this->fileName = filename; - this->defaultValues = defaultValues; - this->settingsNames = settingsNames; - this->Load(); -} - -ConfigSettings::~ConfigSettings() { - for(uint32_t i = 0; i < settingsValues.size(); i++) { - if(settingsValues[i].dataType == TypeString) - delete settingsValues[i].strValue; - } - delete nullValue.strValue; -} - -void ConfigSettings::SetDefault() { - for(uint32_t i = 0; i < settingsValues.size(); i++) { - if(settingsValues[i].dataType == TypeString) { - delete settingsValues[i].strValue; - } - } - - for (auto & kv : settingsNames) { - settingsNames[kv.first] = kv.second; - } - - for (auto & kv : defaultValues) { - SettingValue value; - value.dataType = TypeString; - value.strValue = new std::string(kv.second); - settingsValues[kv.first] = value; - } -} - -bool ConfigSettings::Load() { - //! Reset default path variables to the right device - SetDefault(); - - std::string filepath = configPath + "/"; - filepath += fileName; - - DEBUG_FUNCTION_LINE("Loading Configuration from %s\n",filepath.c_str()); - - CFile file(filepath, CFile::ReadOnly); - if (!file.isOpen()) { - DEBUG_FUNCTION_LINE("Failed to open file\n"); - bChanged = true; - return false; - } - - std::string strBuffer; - strBuffer.resize(file.size()); - file.read((uint8_t *) &strBuffer[0], strBuffer.size()); - file.close(); - - //! remove all windows crap signs - size_t position; - while(1 && !strBuffer.empty()) { - position = strBuffer.find('\r'); - if(position == std::string::npos) - break; - - strBuffer.erase(position, 1); - } - - std::vector lines = StringTools::stringSplit(strBuffer, "\n"); - - if(lines.empty() || !ValidVersion(lines[0])) { - return false; - } - - for(uint32_t i = 0; i < lines.size(); ++i) { - std::vector valueSplit = StringTools::stringSplit(lines[i], "="); - if(valueSplit.size() != 2) { - continue; - } - - while((valueSplit[0].size() > 0) && valueSplit[0][0] == ' ') { - valueSplit[0].erase(0, 1); - } - while((valueSplit[1].size() > 0) && valueSplit[1][ valueSplit[1].size() - 1 ] == ' ') { - valueSplit[1].resize(valueSplit[1].size() - 1); - } - for(uint32_t n = 0; n < settingsNames.size(); n++) { - if(settingsNames.empty()) { - continue; - } - - if(valueSplit[0] == settingsNames[n]) { - switch(settingsValues[n].dataType) { - case TypeBool: - settingsValues[n].bValue = atoi(valueSplit[1].c_str()); - break; - case TypeS8: - settingsValues[n].cValue = atoi(valueSplit[1].c_str()); - break; - case TypeU8: - settingsValues[n].ucValue = atoi(valueSplit[1].c_str()); - break; - case TypeS16: - settingsValues[n].sValue = atoi(valueSplit[1].c_str()); - break; - case TypeU16: - settingsValues[n].usValue = atoi(valueSplit[1].c_str()); - break; - case TypeS32: - settingsValues[n].iValue = atoi(valueSplit[1].c_str()); - break; - case TypeU32: - settingsValues[n].uiValue = strtoul(valueSplit[1].c_str(), 0, 10); - break; - case TypeF32: - settingsValues[n].fValue = atof(valueSplit[1].c_str()); - break; - case TypeString: - if(settingsValues[n].strValue == NULL) - settingsValues[n].strValue = new std::string(); - - *settingsValues[n].strValue = valueSplit[1]; - break; - default: - break; - } - } - } - } - - return true; -} - -bool ConfigSettings::ValidVersion(const std::string & versionString) { - int32_t version = 0; - - if(versionString.find(VERSION_LINE) != 0) { - return false; - } - - version = atoi(versionString.c_str() + strlen(VERSION_LINE)); - - return version == VALID_VERSION; -} - -bool ConfigSettings::Reset() { - this->SetDefault(); - bChanged = true; - - if (this->Save(true)) { - return true; - } - - return false; -} - -int32_t ConfigSettings::getIdByName(std::string configID) { - for (auto & kv : settingsNames) { - if(configID.compare(kv.second) == 0) { - return kv.first; - } - } - return -1; -} - -bool ConfigSettings::Save(bool force) { - if(!force && !bChanged) { - DEBUG_FUNCTION_LINE("Nothing has changed, we can skip\n"); - return true; - } - - FSUtils::CreateSubfolder(configPath.c_str()); - - std::string filepath = configPath + "/"; - filepath += fileName; - - int32_t res = open(filepath.c_str(), O_CREAT | O_TRUNC | O_WRONLY); - close(res); - - CFile file(filepath, CFile::WriteOnly); - if (!file.isOpen()) { - DEBUG_FUNCTION_LINE("failed to open %s\n",filepath.c_str()); - return false; - } - - file.fwrite("%s%i\n", VERSION_LINE, VALID_VERSION); - - for(uint32_t i = 0; i < settingsValues.size(); i++) { - switch(settingsValues[i].dataType) { - case TypeBool: - file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].bValue); - break; - case TypeS8: - file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].cValue); - break; - case TypeU8: - file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].ucValue); - break; - case TypeS16: - file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].sValue); - break; - case TypeU16: - file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].usValue); - break; - case TypeS32: - file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].iValue); - break; - case TypeU32: - file.fwrite("%s=%u\n", settingsNames[i], settingsValues[i].uiValue); - break; - case TypeF32: - file.fwrite("%s=%f\n", settingsNames[i], settingsValues[i].fValue); - break; - case TypeString: - if(settingsValues[i].strValue != NULL) - file.fwrite("%s=%s\n", settingsNames[i].c_str(), settingsValues[i].strValue->c_str()); - break; - default: - break; - } - } - - file.close(); - bChanged = false; - - return true; -} diff --git a/src/settings/ConfigSettings.h b/src/settings/ConfigSettings.h deleted file mode 100644 index effa971..0000000 --- a/src/settings/ConfigSettings.h +++ /dev/null @@ -1,246 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 Dimok - * - * Modified by Maschell, 2018 for WiiU plugin system loader - * - * 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 . - ****************************************************************************/ -#ifndef _CONFIG_SETTINGS_H_ -#define _CONFIG_SETTINGS_H_ - -#include -#include -#include -#include -#include - -class ConfigSettings { -public: - //!Constructor - ConfigSettings(std::string configPath, std::string filename, std::map defaultValues, std::map settingsNames); - //!Destructor - ~ConfigSettings(); - - //!Set Default Settings - void SetDefault(); - //!Load Settings - bool Load(); - //!Save Settings - bool Save(bool force); - //!Reset Settings - bool Reset(); - - enum DataTypes { - TypeNone, - TypeBool, - TypeS8, - TypeU8, - TypeS16, - TypeU16, - TypeS32, - TypeU32, - TypeF32, - TypeString - }; - - const uint8_t & getDataType(int32_t idx) { - if(isValidId(idx)) { - return settingsValues[idx].dataType; - } - return nullValue.dataType; - } - - const bool & getValueAsBool(int32_t idx) { - if(isValidId(idx) && settingsValues[idx].dataType == TypeBool) { - return settingsValues[idx].bValue; - } - return nullValue.bValue; - } - const int8_t & getValueAsS8(int32_t idx) { - if(isValidId(idx) && settingsValues[idx].dataType == TypeS8) { - return settingsValues[idx].cValue; - } - return nullValue.cValue; - } - const uint8_t & getValueAsU8(int32_t idx) { - if(isValidId(idx) && settingsValues[idx].dataType == TypeU8) { - return settingsValues[idx].ucValue; - } - return nullValue.ucValue; - } - const int16_t & getValueAsS16(int32_t idx) { - if(isValidId(idx) && settingsValues[idx].dataType == TypeS16) { - return settingsValues[idx].sValue; - } - return nullValue.sValue; - } - const uint16_t & getValueAsU16(int32_t idx) { - if(isValidId(idx) && settingsValues[idx].dataType == TypeU16) { - return settingsValues[idx].usValue; - } - return nullValue.usValue; - } - const int32_t & getValueAsS32(int32_t idx) { - if(isValidId(idx) && settingsValues[idx].dataType == TypeS32) { - return settingsValues[idx].iValue; - } - return nullValue.iValue; - } - const uint32_t & getValueAsU32(int32_t idx) { - if(isValidId(idx) && settingsValues[idx].dataType == TypeU32) { - return settingsValues[idx].uiValue; - } - return nullValue.uiValue; - } - const float & getValueAsF32(int32_t idx) { - if(isValidId(idx) && settingsValues[idx].dataType == TypeF32) { - return settingsValues[idx].fValue; - } - return nullValue.fValue; - } - const std::string & getValueAsString(int32_t idx) { - if(isValidId(idx) && settingsValues[idx].dataType == TypeString && settingsValues[idx].strValue) { - return *(settingsValues[idx].strValue); - } - return *(nullValue.strValue); - } - - void setValueAsBool(int32_t idx, const bool & val) { - if(isValidId(idx) && settingsValues[idx].dataType == TypeBool) { - if(settingsValues[idx].bValue != val) { - settingsValues[idx].bValue = val; - bChanged = true; - } - } - } - - void setValueAsS8(int32_t idx, const int8_t & val) { - if(isValidId(idx) && settingsValues[idx].dataType == TypeS8) { - if(settingsValues[idx].cValue != val) { - settingsValues[idx].cValue = val; - bChanged = true; - } - } - } - - void setValueAsU8(int32_t idx, const uint8_t & val) { - if(isValidId(idx) && settingsValues[idx].dataType == TypeU8) { - if(settingsValues[idx].ucValue != val) { - settingsValues[idx].ucValue = val; - bChanged = true; - } - } - } - - void setValueAsS16(int32_t idx, const int16_t & val) { - if(isValidId(idx) && settingsValues[idx].dataType == TypeS16) { - if(settingsValues[idx].sValue != val) { - settingsValues[idx].sValue = val; - bChanged = true; - } - } - } - - void setValueAsU16(int32_t idx, const uint16_t & val) { - if(isValidId(idx) && settingsValues[idx].dataType == TypeU16) { - if(settingsValues[idx].usValue != val) { - settingsValues[idx].usValue = val; - bChanged = true; - } - } - } - - void setValueAsS32(int32_t idx, const int32_t & val) { - if(isValidId(idx) && settingsValues[idx].dataType == TypeS32) { - if(settingsValues[idx].iValue != val) { - settingsValues[idx].iValue = val; - bChanged = true; - } - } - } - - void setValueAsU32(int32_t idx, const uint32_t & val) { - if(isValidId(idx) && settingsValues[idx].dataType == TypeU32) { - if(settingsValues[idx].uiValue != val) { - settingsValues[idx].uiValue = val; - bChanged = true; - } - - } - } - - void setValueAsF32(int32_t idx, const float & val) { - if(isValidId(idx) && settingsValues[idx].dataType == TypeF32) { - if(settingsValues[idx].fValue != val) { - settingsValues[idx].fValue = val; - bChanged = true; - } - } - } - - bool setValueAsString(int32_t idx, const std::string & val) { - if(isValidId(idx) && settingsValues[idx].dataType == TypeString && settingsValues[idx].strValue) { - if(val.compare(*(settingsValues[idx].strValue)) != 0) { // Only update if the value changed. - *(settingsValues[idx].strValue) = val; - bChanged = true; - return true; - } - } - return false; - } - - int32_t getIdByName(std::string configID); - - bool hasChanged() { - return bChanged; - } - -protected: - bool ValidVersion(const std::string & versionString); - - bool isValidId(int32_t idx) { - return (settingsValues.count(idx) > 0); - } - - typedef struct { - uint8_t dataType; - - union { - bool bValue; - int8_t cValue; - uint8_t ucValue; - int16_t sValue; - uint16_t usValue; - int32_t iValue; - uint32_t uiValue; - float fValue; - std::string *strValue; - }; - } SettingValue; - - SettingValue nullValue; - - std::string configPath; - std::string fileName; - - std::map settingsValues; - - std::map defaultValues; - std::map settingsNames; - - - bool bChanged; -}; - -#endif diff --git a/src/system/CThread.h b/src/system/CThread.h deleted file mode 100644 index f787f1b..0000000 --- a/src/system/CThread.h +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 Dimok - * - * 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 . - ****************************************************************************/ -#ifndef CTHREAD_H_ -#define CTHREAD_H_ - -#include -#include -#include "dynamic_libs/coreinit.h" -//#include "utils/logger.h" - -class CThread { -public: - typedef void (* Callback)(CThread *thread, void *arg); - - //! constructor - CThread(int32_t iAttr, int32_t iPriority = 16, int32_t iStackSize = 0x8000, CThread::Callback callback = NULL, void *callbackArg = NULL) - : pThread(NULL) - , pThreadStack(NULL) - , pCallback(callback) - , pCallbackArg(callbackArg) { - //! save attribute assignment - iAttributes = iAttr; - //! allocate the thread - pThread = (OSThread*) memalign(8, 0x1000); - //! allocate the stack - pThreadStack = (uint8_t *) memalign(0x20, iStackSize); - //! create the thread - if(pThread && pThreadStack) { - OSCreateThread(pThread, &CThread::threadCallback, 1, this, (uint32_t)pThreadStack+iStackSize, iStackSize, iPriority, iAttributes); - } - } - - //! destructor - virtual ~CThread() { - shutdownThread(); - } - - static CThread *create(CThread::Callback callback, void *callbackArg, int32_t iAttr = eAttributeNone, int32_t iPriority = 16, int32_t iStackSize = 0x8000) { - return ( new CThread(iAttr, iPriority, iStackSize, callback, callbackArg) ); - } - - //! Get thread ID - virtual void* getThread() const { - return pThread; - } - //! Thread entry function - virtual void executeThread(void) { - if(pCallback) - pCallback(this, pCallbackArg); - } - //! Suspend thread - virtual void suspendThread(void) { - if(isThreadSuspended()) return; - if(pThread) OSSuspendThread(pThread); - } - //! Resume thread - virtual void resumeThread(void) { - if(!isThreadSuspended()) return; - if(pThread) OSResumeThread(pThread); - } - //! Set thread priority - virtual void setThreadPriority(int32_t prio) { - if(pThread) OSSetThreadPriority(pThread, prio); - } - //! Check if thread is suspended - virtual bool isThreadSuspended(void) const { - if(pThread) return OSIsThreadSuspended(pThread); - return false; - } - //! Check if thread is terminated - virtual bool isThreadTerminated(void) const { - if(pThread) return OSIsThreadTerminated(pThread); - return false; - } - //! Check if thread is running - virtual bool isThreadRunning(void) const { - return !isThreadSuspended() && !isThreadRunning(); - } - - //! Gets the thread affinity. - virtual uint16_t getThreadAffinity(void) const { - if(pThread) return OSGetThreadAffinity(pThread); - return 0; - } - - //! Shutdown thread - virtual void shutdownThread(void) { - //! wait for thread to finish - if(pThread && !(iAttributes & eAttributeDetach)) { - while(isThreadSuspended()) { - resumeThread(); - } - OSJoinThread(pThread, NULL); - } - //! free the thread stack buffer - if(pThreadStack) { - free(pThreadStack); - } - if(pThread) { - free(pThread); - } - pThread = NULL; - pThreadStack = NULL; - } - //! Thread attributes - enum eCThreadAttributes { - eAttributeNone = 0x07, - eAttributeAffCore0 = 0x01, - eAttributeAffCore1 = 0x02, - eAttributeAffCore2 = 0x04, - eAttributeDetach = 0x08, - eAttributePinnedAff = 0x10 - }; -private: - static int32_t threadCallback(int32_t argc, void *arg) { - //! After call to start() continue with the internal function - ((CThread *) arg)->executeThread(); - return 0; - } - int32_t iAttributes; - OSThread *pThread; - uint8_t *pThreadStack; - Callback pCallback; - void *pCallbackArg; -}; - -#endif diff --git a/src/utils.cpp b/src/utils.cpp deleted file mode 100644 index 6fa8ce4..0000000 --- a/src/utils.cpp +++ /dev/null @@ -1,166 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "utils.h" -#include -#include -#include "common/retain_vars.h" -#include "utils/overlay_helper.h" -#include "utils/mem_utils.h" -#include "kernel/kernel_utils.h" - -void CallHook(wups_loader_hook_type_t hook_type) { - CallHookEx(hook_type,-1); -} - -bool HasHookCallHook(wups_loader_hook_type_t hook_type) { - for(int32_t plugin_index=0; plugin_indexnumber_used_hooks; j++) { - replacement_data_hook_t * hook_data = &plugin_data->hooks[j]; - if(hook_data->type == hook_type) { - return true; - } - } - } - return false; -} - - static const char** hook_names = (const char *[]){ - "WUPS_LOADER_HOOK_INIT_OVERLAY", - "WUPS_LOADER_HOOK_INIT_KERNEL", - "WUPS_LOADER_HOOK_INIT_VID_MEM", - "WUPS_LOADER_HOOK_INIT_WUT_MALLOC", - "WUPS_LOADER_HOOK_FINI_WUT_MALLOC", - "WUPS_LOADER_HOOK_INIT_WUT_DEVOPTAB", - "WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB", - "WUPS_LOADER_HOOK_INIT_WUT_NEWLIB", - "WUPS_LOADER_HOOK_FINI_WUT_NEWLIB", - "WUPS_LOADER_HOOK_INIT_WUT_STDCPP", - "WUPS_LOADER_HOOK_FINI_WUT_STDCPP", - "WUPS_LOADER_HOOK_INIT_PLUGIN", - "WUPS_LOADER_HOOK_DEINIT_PLUGIN", - "WUPS_LOADER_HOOK_APPLICATION_START", - "WUPS_LOADER_HOOK_FUNCTIONS_PATCHED", - "WUPS_LOADER_HOOK_RELEASE_FOREGROUND", - "WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND", - "WUPS_LOADER_HOOK_APPLICATION_END", - "WUPS_LOADER_HOOK_CONFIRM_RELEASE_FOREGROUND", - "WUPS_LOADER_HOOK_SAVES_DONE_READY_TO_RELEASE", - "WUPS_LOADER_HOOK_VSYNC", - "WUPS_LOADER_HOOK_GET_CONFIG", - "WUPS_LOADER_HOOK_VID_DRC_DRAW", - "WUPS_LOADER_HOOK_VID_TV_DRAW", - "WUPS_LOADER_HOOK_APPLET_START"}; - -void CallHookEx(wups_loader_hook_type_t hook_type, int32_t plugin_index_needed) { - for(int32_t plugin_index=0; plugin_indexplugin_name); - //DEBUG_FUNCTION_LINE("Found hooks: %d\n",plugin_data->number_used_hooks); - for(int32_t j=0; jnumber_used_hooks; j++) { - replacement_data_hook_t * hook_data = &plugin_data->hooks[j]; - if(hook_data->type == hook_type) { - DEBUG_FUNCTION_LINE("Calling hook of type %s for plugin %s\n",hook_names[hook_data->type],plugin_data->plugin_name); - void * func_ptr = hook_data->func_pointer; - //TODO: Switch cases depending on arguments etc. - // Adding arguments! - if(func_ptr != NULL) { - //DEBUG_FUNCTION_LINE("function pointer is %08x\n",func_ptr); - if(hook_type == WUPS_LOADER_HOOK_INIT_OVERLAY) { - /*wups_loader_init_overlay_args_t args; - args.overlayfunction_ptr = &overlay_helper; - args.textureconvertfunction_ptr = &TextureUtils::convertImageToTexture; - args.drawtexturefunction_ptr = (void (*)(void*,void*,float,float,int32_t,int32_t,float)) &TextureUtils::drawTexture; - ((void (*)(wups_loader_init_overlay_args_t))((uint32_t*)func_ptr) )(args);*/ - } else if(hook_type == WUPS_LOADER_HOOK_INIT_PLUGIN) { - ((void (*)(void))((uint32_t*)func_ptr) )(); - } else if(hook_type == WUPS_LOADER_HOOK_DEINIT_PLUGIN) { - ((void (*)(void))((uint32_t*)func_ptr) )(); - } else if(hook_type == WUPS_LOADER_HOOK_APPLICATION_START) { - wups_loader_app_started_args_t args; - memset(&args,0,sizeof(args)); - if(plugin_data->kernel_allowed && plugin_data->kernel_init_done) { - args.kernel_access = true; - } - ((void (*)(wups_loader_app_started_args_t))((uint32_t*)func_ptr) )(args); - } else if(hook_type == WUPS_LOADER_HOOK_FUNCTIONS_PATCHED) { - ((void (*)(void))((uint32_t*)func_ptr))(); - } else if(hook_type == WUPS_LOADER_HOOK_APPLICATION_END) { - ((void (*)(void))((uint32_t*)func_ptr))(); - } else if(hook_type == WUPS_LOADER_HOOK_VSYNC) { - ((void (*)(void))((uint32_t*)func_ptr))(); - } else if(hook_type == WUPS_LOADER_HOOK_RELEASE_FOREGROUND) { - ((void (*)(void))((uint32_t*)func_ptr))(); - } else if(hook_type == WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND) { - ((void (*)(void))((uint32_t*)func_ptr))(); - } else if(hook_type == WUPS_LOADER_HOOK_APPLET_START) { - ((void (*)(void))((uint32_t*)func_ptr))(); - } else if(hook_type == WUPS_LOADER_HOOK_INIT_WUT_MALLOC) { - ((void (*)(void))((uint32_t*)func_ptr))(); - } else if(hook_type == WUPS_LOADER_HOOK_FINI_WUT_MALLOC) { - ((void (*)(void))((uint32_t*)func_ptr))(); - } else if(hook_type == WUPS_LOADER_HOOK_INIT_WUT_DEVOPTAB) { - ((void (*)(void))((uint32_t*)func_ptr))(); - } else if(hook_type == WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB) { - ((void (*)(void))((uint32_t*)func_ptr))(); - } else if(hook_type == WUPS_LOADER_HOOK_INIT_WUT_NEWLIB) { - ((void (*)(void))((uint32_t*)func_ptr))(); - } else if(hook_type == WUPS_LOADER_HOOK_FINI_WUT_NEWLIB) { - ((void (*)(void))((uint32_t*)func_ptr))(); - } else if(hook_type == WUPS_LOADER_HOOK_INIT_WUT_STDCPP) { - ((void (*)(void))((uint32_t*)func_ptr))(); - } else if(hook_type == WUPS_LOADER_HOOK_FINI_WUT_STDCPP) { - ((void (*)(void))((uint32_t*)func_ptr))(); - } else if(hook_type == WUPS_LOADER_HOOK_INIT_KERNEL) { - // Only call the hook if kernel is allowed. - if(plugin_data->kernel_allowed) { - wups_loader_init_kernel_args_t args; - args.kern_read_ptr = &kern_read; - args.kern_write_ptr = &kern_write; - args.kern_copy_data_ptr = &KernelCopyData; - ((void (*)(wups_loader_init_kernel_args_t))((uint32_t*)func_ptr) )(args); - plugin_data->kernel_init_done = true; - } - } else if(hook_type == WUPS_LOADER_HOOK_INIT_VID_MEM) { - wups_loader_init_vid_mem_args_t args; - args.vid_mem_alloc_ptr = &MemoryUtils::alloc; - args.vid_mem_free_ptr = &MemoryUtils::free; - ((void (*)(wups_loader_init_vid_mem_args_t))((uint32_t*)func_ptr) )(args); - } else if(hook_type == WUPS_LOADER_HOOK_VID_DRC_DRAW) { - /*wups_loader_vid_buffer_t args; - args.color_buffer_ptr = &g_vid_main_cbuf; - args.tv_texture_ptr = &g_vid_tvTex; - args.drc_texture_ptr = &g_vid_drcTex; - args.sampler_ptr = &g_vid_sampler; - ((void (*)(wups_loader_vid_buffer_t))((uint32_t*)func_ptr) )(args);*/ - } else if(hook_type == WUPS_LOADER_HOOK_VID_TV_DRAW) { - /*wups_loader_vid_buffer_t args; - args.color_buffer_ptr = &g_vid_main_cbuf; - args.tv_texture_ptr = &g_vid_tvTex; - args.drc_texture_ptr = &g_vid_drcTex; - args.sampler_ptr = &g_vid_sampler; - ((void (*)(wups_loader_vid_buffer_t))((uint32_t*)func_ptr) )(args);*/ - } else { - DEBUG_FUNCTION_LINE("ERROR: HOOK TYPE WAS NOT IMPLEMENTED %08X \n",hook_type); - } - } else { - DEBUG_FUNCTION_LINE("Failed to call hook. It was not defined\n"); - } - } - } - } -} diff --git a/src/utils.h b/src/utils.h deleted file mode 100644 index 7842f13..0000000 --- a/src/utils.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _OWN_UTILS_H_ -#define _OWN_UTILS_H_ - -/* Main */ -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -bool HasHookCallHook(wups_loader_hook_type_t hook_type); -void CallHook(wups_loader_hook_type_t hook_type); - -void CallHookEx(wups_loader_hook_type_t hook_type, int32_t plugin_index_needed); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/utils/ConfigInformation.cpp b/src/utils/ConfigInformation.cpp deleted file mode 100644 index e7accf2..0000000 --- a/src/utils/ConfigInformation.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** - * 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 . - ****************************************************************************/ - -#include -#include -#include -#include "ConfigInformation.h" - -ConfigInformation::ConfigInformation(WUPSConfig * config, std::string persistPath, std::string persistFileName) { - this->config = config; - this->persistPath = persistPath; - this->persistFileName = persistFileName; - createConfigSettings(); -} - -ConfigInformation::~ConfigInformation() { - if(configSettings != NULL) { - delete configSettings; - configSettings = NULL; - } - if(config != NULL) { - delete config; - config = NULL; - } -} - -bool ConfigInformation::createConfigSettings() { - if(this->config == NULL) { - return false; - } - - if(this->configSettings != NULL) { - delete this->configSettings; - } - - std::map defaultValues; - std::map settingsNames; - int32_t index = 0; - for (auto & curCat : this->config->getCategories()) { - for (auto & curItem : curCat->getItems()) { - std::string configID = curItem->getConfigID(); - std::string defaultValue = curItem->persistValue(); - - defaultValues[index] = defaultValue; - settingsNames[index] = configID; - index++; - } - } - - configSettings = new ConfigSettings(persistPath, persistFileName, defaultValues, settingsNames); - - return (configSettings != NULL); -} - -bool ConfigInformation::loadValuesFromSD() { - if(this->config == NULL || this->configSettings == NULL) { - return false; - } - - for (auto & curCat : this->config->getCategories()) { - for (auto & curItem : curCat->getItems()) { - std::string configID = curItem->getConfigID(); - std::string prevValue = curItem->persistValue(); - std::string loadedValue = this->configSettings->getValueAsString(this->configSettings->getIdByName(configID)); - //DEBUG_FUNCTION_LINE("Loaded %s(%d) to %s. Previous value was %s \n",configID.c_str(),this->configSettings->getIdByName(configID), loadedValue.c_str(), prevValue.c_str()); - if(prevValue.compare(loadedValue) != 0) { - //DEBUG_FUNCTION_LINE("Call loadValue\n"); - curItem->loadValue(loadedValue); - curItem->callCallback(); - } - } - } - return true; -} - -void ConfigInformation::updateAndSaveSettings(bool forceAll) { - if(this->config == NULL || this->configSettings == NULL) { - return; - } - updateConfigSettings(); - configSettings->Save(forceAll); -} - -bool ConfigInformation::updateConfigSettings() { - if(this->config == NULL || this->configSettings == NULL) { - return false; - } - - for (auto & curCat : this->config->getCategories()) { - for (auto & curItem : curCat->getItems()) { - std::string configID = curItem->getConfigID(); - std::string newValue = curItem->persistValue(); - if(this->configSettings->setValueAsString(this->configSettings->getIdByName(configID), newValue)) { - // When the value has changed, call the callback. - DEBUG_FUNCTION_LINE("Called callback. Reason. Menu was closed and value has changed\n"); - curItem->callCallback(); - } - - //DEBUG_FUNCTION_LINE("Set %s(%d) to %s\n",configID.c_str(),this->configSettings->getIdByName(configID), newValue.c_str()); - } - } - return true; -} diff --git a/src/utils/ConfigInformation.h b/src/utils/ConfigInformation.h deleted file mode 100644 index 880a5f9..0000000 --- a/src/utils/ConfigInformation.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** - * 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 . - ****************************************************************************/ - -#ifndef _CONFIG_INFORMATION_H_ -#define _CONFIG_INFORMATION_H_ - -#include -#include "settings/ConfigSettings.h" -#include -#include - -class ConfigInformation { - -public: - /** - Creates a ConfigInformation object for a given WUPSConfig. - This also is responsible for persisting/loading the configurations to/from the SDCard. - The configuration will be loaded created/loaded at "[persistPath]/[persistFileName]" - **/ - ConfigInformation(WUPSConfig * config, std::string persistPath, std::string persistFileName); - - /** - Deletes the given WUPSConfig - Deletes the created ConfigSettings - **/ - ~ConfigInformation(); - - void updateAndSaveSettings(bool forceAll); - - bool loadValuesFromSD(); - - WUPSConfig * getConfig() { - return config; - } - -private: - bool createConfigSettings(); - bool updateConfigSettings(); - - WUPSConfig * config = NULL; - ConfigSettings * configSettings = NULL; - std::string persistPath; - std::string persistFileName; -}; - - -#endif diff --git a/src/utils/ConfigUtils.cpp b/src/utils/ConfigUtils.cpp deleted file mode 100644 index 30d9f40..0000000 --- a/src/utils/ConfigUtils.cpp +++ /dev/null @@ -1,399 +0,0 @@ -/**************************************************************************** - * 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 . - ****************************************************************************/ -#include -#include -#include -#include -#include - -//#include "common/common.h" -#include "common/retain_vars.h" - -#include "overlay_helper.h" -#include "ScreenUtils.h" -#include "ConfigUtils.h" -//#include - -#include "ConfigInformation.h" - -#define gettext(x) x - -#define PLUGIN_CONFIG_FILE_EXT ".cfg" - -void ConfigUtils::configMenuOpenedCallback(wups_overlay_options_type_t screen, void * args) { - // We close the configuration menu with the home button, but this would also - // trigger the home menu. - // To avoid this (and restore the GX2 buffers properly) we disable the home menu button - // as long we're in the configuration menu. - OSEnableHomeButtonMenu(false); - - std::vector * configList = (std::vector *) args; - - if(configList == NULL) { - DEBUG_FUNCTION_LINE("configList was NULL.\n"); - // Re-enable home button. TODO: Only enable when it was enabled before. - OSEnableHomeButtonMenu(true); - return; - } - - int32_t i = 0; - int32_t x = 0; - int32_t screen_y_pos = 0; - int32_t visible_rows_start = 2; - int32_t visible_rows_end = 16; - int32_t visible_rows_range = visible_rows_end - visible_rows_start; - - WUPSConfig* curConfig = NULL; - - VPADData vpad_data; - int32_t error; - - int32_t maxSelect = 0; - int32_t curSelect = 0; - - int32_t curScreenOffset = 0; - bool firstRun = true; - while(true) { - VPADRead(0, &vpad_data, 1, &error); - if(vpad_data.btns_d == VPAD_BUTTON_HOME) { - break; - } - - int32_t newSelect = curSelect; - bool changed = false; - - if(curConfig == NULL) { - maxSelect = configList->size(); - if(maxSelect > 0) { - maxSelect--; - } - - bool selected = false; - - if(vpad_data.btns_r & VPAD_BUTTON_DOWN) { - newSelect++; - } - if(vpad_data.btns_r & VPAD_BUTTON_UP) { - newSelect--; - } - if(vpad_data.btns_r & VPAD_BUTTON_A) { - selected = true; - changed = true; - } - - if(newSelect < 0) { - newSelect = maxSelect; - } else if(newSelect > maxSelect) { - newSelect = 0; - } - - if(newSelect != curSelect) { - curSelect = newSelect; - changed = true; - } - if(!firstRun) { - if(!changed) { - continue; - } - } - firstRun = false; - - ScreenUtils::OSScreenClear(screen); - screen_y_pos = 0; - ScreenUtils::printTextOnScreen(screen, 0, visible_rows_end + 1, gettext("Press HOME to return to the running application.")); - ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++,gettext("Configurable running plugins:")); - ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++,"=========================="); - - if(configList->size() == 0) { - ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++,gettext("No configurable running plugins found.")); - ScreenUtils::flipBuffers(screen); - continue; - } - - int32_t index = 0; - for (auto & curConfig_ : *configList) { - if(index == curSelect) { - ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++,"> %s",curConfig_->getName().c_str()); - if(selected) { - curConfig = curConfig_; - curSelect = 0; - curScreenOffset = 0; - firstRun = true; - maxSelect = 0; - for (auto & curCat : curConfig_->getCategories()) { - maxSelect += curCat->getItems().size(); - } - if(maxSelect > 0) { - maxSelect--; - } - } - } else { - ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++," %s",curConfig_->getName().c_str()); - } - index++; - } - ScreenUtils::flipBuffers(screen); - continue; - } - - WUPSConfigButtons pressedButtons = WUPS_CONFIG_BUTTON_NONE; - - /* - if(vpad_data.btns_r & VPAD_BUTTON_DOWN) { - pressedButtons |= WUPS_CONFIG_BUTTON_DOWN; - } - if(vpad_data.btns_r & VPAD_BUTTON_UP) { - pressedButtons |= WUPS_CONFIG_BUTTON_UP; - }*/ - if(vpad_data.btns_d & VPAD_BUTTON_A) { - pressedButtons |= WUPS_CONFIG_BUTTON_A; - } - if(vpad_data.btns_d & VPAD_BUTTON_B) { - pressedButtons |= WUPS_CONFIG_BUTTON_B; - } - if(vpad_data.btns_d & VPAD_BUTTON_LEFT) { - pressedButtons |= WUPS_CONFIG_BUTTON_LEFT; - } - if(vpad_data.btns_d & VPAD_BUTTON_RIGHT) { - pressedButtons |= WUPS_CONFIG_BUTTON_RIGHT; - } - if(vpad_data.btns_d & VPAD_BUTTON_L) { - pressedButtons |= WUPS_CONFIG_BUTTON_L; - } - if(vpad_data.btns_d & VPAD_BUTTON_R) { - pressedButtons |= WUPS_CONFIG_BUTTON_R; - } - if(vpad_data.btns_d & VPAD_BUTTON_ZL) { - pressedButtons |= WUPS_CONFIG_BUTTON_ZL; - } - if(vpad_data.btns_d & VPAD_BUTTON_ZR) { - pressedButtons |= WUPS_CONFIG_BUTTON_ZR; - } - - if(vpad_data.btns_r & VPAD_BUTTON_DOWN) { - newSelect++; - } - if(vpad_data.btns_r & VPAD_BUTTON_UP) { - newSelect--; - } - - if(vpad_data.btns_d & VPAD_BUTTON_B) { - curConfig = NULL; - curSelect = 0; - curScreenOffset = 0; - firstRun = true; - continue; - } - if(newSelect < 0) { - newSelect = maxSelect; - } else if(newSelect > maxSelect) { - newSelect = 0; - } - - if(newSelect != curSelect) { - curSelect = newSelect; - changed = true; - } - if(pressedButtons != WUPS_CONFIG_BUTTON_NONE) { - changed = true; - } - - int32_t cur_visible_rows = 0; - if(!firstRun) { - if(!changed) { - continue; - } - } - firstRun = false; - - ScreenUtils::OSScreenClear(screen); - - int32_t inSelect = 0; - - bool ignore = false; - for (auto & curCat : curConfig->getCategories()) { - cur_visible_rows += 2; - for (auto & curItem : curCat->getItems()) { - - cur_visible_rows++; - if(!ignore && curSelect == inSelect) { - if(curSelect == 0) { - curScreenOffset = 0; - } else if(cur_visible_rows + curScreenOffset >= visible_rows_range) { - curScreenOffset -= (cur_visible_rows + curScreenOffset) - visible_rows_range; - } else if(cur_visible_rows + curScreenOffset < visible_rows_range/2 && cur_visible_rows >= visible_rows_range/2) { - curScreenOffset -= (cur_visible_rows + curScreenOffset) - visible_rows_range/2; - } - ignore = true; - } - inSelect++; - } - } - - ScreenUtils::printTextOnScreen(screen, 0, 0, "Configuration for %s:", curConfig->getName().c_str()); - - int32_t arrow_x_offset = 60; - if(curScreenOffset < 0) { - ScreenUtils::printTextOnScreen(screen, arrow_x_offset, visible_rows_start + 1, " ^"); - ScreenUtils::printTextOnScreen(screen, arrow_x_offset, visible_rows_start + 2, " |"); - } - if(curScreenOffset + cur_visible_rows > visible_rows_range) { - ScreenUtils::printTextOnScreen(screen, arrow_x_offset, visible_rows_end - 2, " | "); - ScreenUtils::printTextOnScreen(screen, arrow_x_offset, visible_rows_end - 1, " v"); - } - - ScreenUtils::printTextOnScreen(screen, 0, visible_rows_end + 1, gettext("B = plugin overview, HOME = back to running application.")); - - screen_y_pos = curScreenOffset + visible_rows_start; - - inSelect = 0; - - for (auto & curCat : curConfig->getCategories()) { - if((screen_y_pos + 2) >= visible_rows_end) { - break; - } - if((screen_y_pos - visible_rows_start) < -1) { - screen_y_pos += 2; - } else if((screen_y_pos - visible_rows_start) < 0) { - screen_y_pos++; - ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++,"=========================="); - } else { - ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++,"%s",curCat->getName().c_str()); - ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++,"=========================="); - } - for (auto & curItem : curCat->getItems()) { - if(screen_y_pos >= visible_rows_end) { - break; - } - curItem->visibleOnScreen(screen); - if(curSelect == inSelect) { - if(pressedButtons != WUPS_CONFIG_BUTTON_NONE) { - curItem->onButtonPressed(pressedButtons); - firstRun = true; - } - ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++,"> %-36s %s\n",curItem->getDisplayName().c_str(),curItem->getCurrentValueSelectedDisplay().c_str()); - } else if((screen_y_pos - visible_rows_start) >= 0) { - ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++," %-36s %s\n",curItem->getDisplayName().c_str(),curItem->getCurrentValueDisplay().c_str()); - } else { - screen_y_pos++; - } - inSelect++; - } - - } - - ScreenUtils::flipBuffers(screen); - i++; - } - // Re-enable home button. TODO: Only enable when it was enabled before. - // Currently we can be sure it was enabled, because it's an requirement to enter the configuration menu. - // This might change in the future. - OSEnableHomeButtonMenu(true); -} - -void ConfigUtils::openConfigMenu(std::vector configs) { - overlay_helper(WUPS_OVERLAY_DRC_AND_TV_WITH_DRC_PRIO, configMenuOpenedCallback, (void*) &configs); -} - -std::vector ConfigUtils::getConfigInformation() { - std::vector configs; - for(int32_t plugin_index=0; plugin_indexnumber_used_hooks; j++) { - replacement_data_hook_t * hook_data = &plugin_data->hooks[j]; - if(hook_data->type == WUPS_LOADER_HOOK_GET_CONFIG) { - if(hook_data->func_pointer == NULL) { - break; - } - void * func_ptr = hook_data->func_pointer; - WUPSConfig * cur_config = ((WUPSConfig* (*)(void))((uint32_t*)func_ptr) )(); - DCFlushRange(cur_config, sizeof(WUPSConfig)); - if(cur_config != NULL) { - std::string fullPath(plugin_data->path); - std::string path = fullPath.substr(0, fullPath.find_last_of("/")); - size_t filenamePos = fullPath.find_last_of("/")+1; - std::string filename = fullPath.substr(filenamePos, fullPath.find_last_of(".") - filenamePos); - ConfigInformation * configInfo = new ConfigInformation(cur_config, path, filename.append(PLUGIN_CONFIG_FILE_EXT)); - configs.push_back(configInfo); - } - } - } - } - return configs; -} - -void ConfigUtils::deleteConfigInformation(std::vector configs) { - for (auto & curConfig : configs) { - delete curConfig; - } -} - -void ConfigUtils::loadConfigFromSD() { - std::vector configInfos = getConfigInformation(); - - for (auto & curConfig : configInfos) { - curConfig->loadValuesFromSD(); - } - - deleteConfigInformation(configInfos); -} - -void ConfigUtils::saveConfigToSD() { - std::vector configInfos = getConfigInformation(); - - for (auto & curConfig : configInfos) { - curConfig->updateAndSaveSettings(true); - } - - deleteConfigInformation(configInfos); -} - -void ConfigUtils::openConfigMenu() { - std::vector configInfos = getConfigInformation(); - - // We rely on the default values here. - //if(loadFromSD){ - // for (auto & curConfig : configInfos) { - // configs.loadValuesFromSD(); - // } - //} - - std::vector configs; - - for (auto & curConfig : configInfos) { - configs.push_back(curConfig->getConfig()); - } - - for (auto & curConfig : configs) { - DCFlushRange(curConfig, sizeof(WUPSConfig)); - } - - ConfigUtils::openConfigMenu(configs); - - for (auto & curConfig : configs) { - DCFlushRange(curConfig, sizeof(WUPSConfig)); - } - - for (auto & curConfig : configInfos) { - curConfig->updateAndSaveSettings(false); - } - - deleteConfigInformation(configInfos); -} diff --git a/src/utils/ConfigUtils.h b/src/utils/ConfigUtils.h deleted file mode 100644 index daea4f3..0000000 --- a/src/utils/ConfigUtils.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** - * 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 . - ****************************************************************************/ -#ifndef __CONFIG_UTILS_H_ -#define __CONFIG_UTILS_H_ - -#include -#include -#include "ConfigInformation.h" - -class ConfigUtils { - -public: - /** - Loads the configuration files of all loaded plugins from the SDCard - and triggers the "callback" if they differ the default/current value. - **/ - static void loadConfigFromSD(); - - /** - Get the current values from all plugins via the WUPS_GET_CONFIG() hook and - save them to the SD Card. - **/ - static void saveConfigToSD(); - - /** - Opens the configuration menu where plugins can be configured. - Plugins need to implement the WUPS_GET_CONFIG() hook to show up in the menu. - The menu will be rendered on the TV and DRC screen, with optimization for the DRC. - If the memory is low, the menu may be only rendered to the DRC. - **/ - static void openConfigMenu(); - -private: - ConfigUtils() {} - ~ConfigUtils() {} - - /** - Opens the configuration menu for a list of WUPSConfig. - If a configuration menu context could be created successfully, "configMenuOpenedCallback" - will be called, with the configs as an argument. - **/ - static void openConfigMenu(std::vector configs); - - /** - The callback that renders the configuration menu. - The args parameter expects a "std::vector *". - Depending on the screen - **/ - static void configMenuOpenedCallback(wups_overlay_options_type_t screen, void * args); - - /** - Gets the ConfigInformation for all loaded plugin that have implemented - the WUPS_GET_CONFIG() hook. - - This triggers creating ConfigInformation objects. - ConfigInformation objects load the corresponding configuration file for a plugin - from the sd card. It also calls the "loadValue" function if a loaded value differs from the - default value. This behaviour may change in the future. - See the ConfigInformation class for more information. - **/ - static std::vector getConfigInformation(); - - /** - Delete a list of ConfigInformation. - The destructor of "ConfigInformation" causes the configuration files for the plugin - to be written to the sd card (if the value have changed). This behaviour may change - in the future. See the ConfigInformation class for more information. - **/ - static void deleteConfigInformation(std::vector configs); - -}; - -#endif diff --git a/src/utils/ScreenUtils.cpp b/src/utils/ScreenUtils.cpp deleted file mode 100644 index bb24fb0..0000000 --- a/src/utils/ScreenUtils.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** - * 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 . - ****************************************************************************/ -#include -#include -#include -#include -#include -#include "dynamic_libs/coreinit.h" -#include "ScreenUtils.h" - -void ScreenUtils::printTextOnScreen(wups_overlay_options_type_t screen, int x,int y, const char * msg, ...) { - if(screen == WUPS_OVERLAY_NONE) { - return; - } - - char * tmp = NULL; - - va_list va; - va_start(va, msg); - if((vasprintf(&tmp, msg, va) >= 0) && tmp) { - if(screen != WUPS_OVERLAY_DRC_ONLY) { // Draw TV if it's not DRC exclusive. - OSScreenPutFontEx(0, x, y, tmp); - } - if(screen != WUPS_OVERLAY_TV_ONLY) { // Draw DRC if it's not TV exclusive. - OSScreenPutFontEx(1, x, y, tmp); - } - } - va_end(va); - - if(tmp) { - free(tmp); - } -} - -void ScreenUtils::OSScreenClear(wups_overlay_options_type_t screen) { - if(screen == WUPS_OVERLAY_NONE) { - return; - } - if(screen != WUPS_OVERLAY_DRC_ONLY) { // Clear TV if it's not DRC exclusive. - OSScreenClearBufferEx(0, 0); - } - if(screen != WUPS_OVERLAY_TV_ONLY) { // Clear DRC if it's not TV exclusive. - OSScreenClearBufferEx(1, 0); - } -} - -void ScreenUtils::flipBuffers(wups_overlay_options_type_t screen) { - if(screen == WUPS_OVERLAY_NONE) { - return; - } - if(screen != WUPS_OVERLAY_DRC_ONLY) { // Flip TV buffer if it's not DRC exclusive. - OSScreenFlipBuffersEx(0); - } - if(screen != WUPS_OVERLAY_TV_ONLY) { // Flip DRC buffer if it's not TV exclusive. - OSScreenFlipBuffersEx(1); - } -} diff --git a/src/utils/ScreenUtils.h b/src/utils/ScreenUtils.h deleted file mode 100644 index b6fc82b..0000000 --- a/src/utils/ScreenUtils.h +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** - * 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 . - ****************************************************************************/ -#ifndef __SCREEN_UTILS_H_ -#define __SCREEN_UTILS_H_ - -class ScreenUtils { -public: - /** - Clears the screen for the given screens - \param screen defines on which screens should be printed - \param x defines the x position (character position) where the text should be printed - \param y defines on which line the text should be printed - \param msg C string that contains the text to be printed. - It can optionally contain embedded format specifiers that are replaced by the values specified in subsequent additional arguments and formatted as requested. - See printf for more information - \param ... Depending on the format string, the function may expect a sequence of additional arguments, each containing a value to be used to replace a format specifier in the format string - **/ - static void printTextOnScreen(wups_overlay_options_type_t screen, int x,int y, const char * msg, ...); - - /** - Clears the screen for the given screens - \param screen defines which screens should be cleared - **/ - static void OSScreenClear(wups_overlay_options_type_t screen); - - /** - Flips the buffer for the given screens - \param screen defines which screens should be flipped. - **/ - static void flipBuffers(wups_overlay_options_type_t screen); -private: - ScreenUtils() {} - ~ScreenUtils() {} - -}; -#endif diff --git a/src/utils/StringTools.h b/src/utils/StringTools.h deleted file mode 100644 index e17eb27..0000000 --- a/src/utils/StringTools.h +++ /dev/null @@ -1,82 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - * - * for WiiXplorer 2010 - ***************************************************************************/ -#ifndef __STRING_TOOLS_H -#define __STRING_TOOLS_H - -#include -#include -#include - -class StringTools{ - public: - static bool EndsWith(const std::string& a, const std::string& b); - static const char * byte_to_binary(int32_t x); - static std::string removeCharFromString(std::string& input,char toBeRemoved); - static const char * fmt(const char * format, ...); - static const wchar_t * wfmt(const char * format, ...); - static int32_t strprintf(std::string &str, const char * format, ...); - static std::string strfmt(const char * format, ...); - static bool char2wchar_t(const char * src, wchar_t * dest); - static int32_t strtokcmp(const char * string, const char * compare, const char * separator); - static int32_t strextcmp(const char * string, const char * extension, char seperator); - - static const char * FullpathToFilename(const char *path){ - if(!path) return path; - - const char * ptr = path; - const char * Filename = ptr; - - while(*ptr != '\0') - { - if(ptr[0] == '/' && ptr[1] != '\0') - Filename = ptr+1; - - ++ptr; - } - - return Filename; - } - - static void RemoveDoubleSlashs(std::string &str){ - uint32_t length = str.size(); - - //! clear path of double slashes - for(uint32_t i = 1; i < length; ++i) - { - if(str[i-1] == '/' && str[i] == '/') - { - str.erase(i, 1); - i--; - length--; - } - } - } - - static std::vector stringSplit(const std::string & value, const std::string & splitter); -}; - -#endif /* __STRING_TOOLS_H */ - diff --git a/src/utils/ipc.cpp b/src/utils/ipc.cpp deleted file mode 100644 index d502b3e..0000000 --- a/src/utils/ipc.cpp +++ /dev/null @@ -1,291 +0,0 @@ -#include -#include -#include -#include "ipc.h" -#include "common/retain_vars.h" - -extern void RestoreEverything(); -extern void afterLoadAndLink(); - -int ipc_ioctl(ipcmessage *message) { - int res = 0; - - switch(message->command) { - case IOCTL_OPEN_PLUGIN_LOADER: { - DEBUG_FUNCTION_LINE("IOCTL_OPEN_PLUGIN_LOADER\n"); - if(message->ioctl.length_in != 8 || message->ioctl.length_io < 4) { - //DEBUG_FUNCTION_LINE("IPC_ERROR_INVALID_SIZE\n"); - res = IPC_ERROR_INVALID_SIZE; - } else { - uint32_t startAddress = message->ioctl.buffer_in[0]; - uint32_t endAddress = message->ioctl.buffer_in[1]; - - - PluginLoader * pluginLoader = new PluginLoader((void*)startAddress, (void*)endAddress); - if(pluginLoader == NULL) { - //DEBUG_FUNCTION_LINE("Creating plugin loader for %08X %08X failed \n",startAddress, endAddress); - res = IPC_ERROR_FAILED_ALLOC; - } else { - //DEBUG_FUNCTION_LINE("Creating plugin loader %08X %08X: %08X\n",startAddress, endAddress, pluginLoader); - message->ioctl.buffer_io[0] = (uint32_t) pluginLoader; - } - } - break; - } - case IOCTL_CLOSE_PLUGIN_LOADER: { - DEBUG_FUNCTION_LINE("IOCTL_CLOSE_PLUGIN_LOADER\n"); - if(message->ioctl.length_in != 4) { - DEBUG_FUNCTION_LINE("IPC_ERROR_INVALID_SIZE\n"); - res = IPC_ERROR_INVALID_SIZE; - } else { - void * ptr = (void *) message->ioctl.buffer_in[0]; - - //DEBUG_FUNCTION_LINE("Closing %08X\n", ptr); - - if(ptr != NULL/* && (PluginLoader* pluginLoader = dynamic_cast(ptr))*/) { - PluginLoader* pluginLoader = (PluginLoader * )ptr; - delete pluginLoader; - } else { - res = IPC_ERROR_INVALID_ARG; - } - } - - break; - } - case IOCTL_PLUGIN_LOADER_GET_INFORMATION_FOR_PATH: { - DEBUG_FUNCTION_LINE("IOCTL_PLUGIN_LOADER_GET_INFORMATION_FOR_PATH\n"); - if(message->ioctl.length_in != 4 || message->ioctl.length_io < 4) { - DEBUG_FUNCTION_LINE("IPC_ERROR_INVALID_SIZE\n"); - res = IPC_ERROR_INVALID_SIZE; - } else { - char * path = (char *) message->ioctl.buffer_in[0]; - uint32_t * filledCount = (uint32_t *)message->ioctl.buffer_io; - plugin_information_handle * io_handles = (plugin_information_handle *) &(message->ioctl.buffer_io[1]); - uint32_t lengthIo = message->ioctl.length_io - 4; - - *filledCount = 0; - - //DEBUG_FUNCTION_LINE("path %08X %s, filledcount_ptr %08X io_handles%08X lengthio%d\n", path,path, filledCount,io_handles,lengthIo); - - std::vector pluginList = PluginLoader::getPluginInformation(path); - uint32_t pluginInfoSpace = lengthIo / sizeof(plugin_information_handle); - - //DEBUG_FUNCTION_LINE("pluginInfoSpace %d\n", pluginInfoSpace); - - uint32_t cur = 0; - - for (std::vector::iterator it = pluginList.begin() ; it != pluginList.end(); ++it) { - - PluginInformation * curPlugin = *it; - //DEBUG_FUNCTION_LINE("cur %d filledCount %d curPlugin %08X\n", cur, *filledCount,curPlugin); - if(cur >= pluginInfoSpace) { - //DEBUG_FUNCTION_LINE("deleted plugins because they don't fit in buffer..\n"); - // delete all that don't fit into the target list. - delete curPlugin; - continue; - } - io_handles[cur] = (plugin_information_handle) curPlugin; - //DEBUG_FUNCTION_LINE("%08X = %08X\n", &(io_handles[cur]), io_handles[cur]); - cur++; - (*filledCount)++; - } - - DCFlushRange(message->ioctl.buffer_io,message->ioctl.length_io); - ICInvalidateRange(message->ioctl.buffer_io,message->ioctl.length_io); - - } - break; - } - case IOCTL_PLUGIN_LOADER_GET_INFORMATION_LOADED: { - if(message->ioctl.length_in != 0 || message->ioctl.length_io < 4) { - res = IPC_ERROR_INVALID_SIZE; - } else { - uint32_t * filledCount = (uint32_t *)message->ioctl.buffer_io; - plugin_information_handle * io_handles = (plugin_information_handle *) &(message->ioctl.buffer_io[1]); - uint32_t lengthIo = message->ioctl.length_io - 4; - - *filledCount = 0; - - std::vector pluginList = PluginLoader::getPluginsLoadedInMemory(); - uint32_t pluginInfoSpace = lengthIo / sizeof(plugin_information_handle); - - uint32_t cur = 0; - - if(pluginInfoSpace > 0) { - for (std::vector::iterator it = pluginList.begin() ; it != pluginList.end(); ++it) { - PluginInformation * curPlugin = *it; - if(cur >= pluginInfoSpace) { - // delete all that don't fit into the target list. - delete curPlugin; - continue; - } - io_handles[cur] = (plugin_information_handle) curPlugin; - cur++; - (*filledCount)++; - } - } - DCFlushRange(message->ioctl.buffer_io,message->ioctl.length_io); - ICInvalidateRange(message->ioctl.buffer_io,message->ioctl.length_io); - - } - break; - } - - case IOCTL_PLUGIN_LOADER_DELETE_INFORMATION: { - DEBUG_FUNCTION_LINE("IOCTL_PLUGIN_LOADER_DELETE_INFORMATION\n"); - if(message->ioctl.length_in != 4) { - res = IPC_ERROR_INVALID_SIZE; - } else { - plugin_information_handle * plugin_handle = (plugin_information_handle *) message->ioctl.buffer_in[0]; - - if(plugin_handle != NULL/* && (PluginLoader* pluginLoader = dynamic_cast(ptr))*/) { - PluginInformation* curInformation = (PluginInformation *)plugin_handle; - //DEBUG_FUNCTION_LINE("Deleting %08X\n", curInformation); - delete curInformation; - } else { - res = IPC_ERROR_INVALID_ARG; - } - } - break; - } - - case IOCTL_PLUGIN_LOADER_GET_INFORMATION_DETAILS: { - DEBUG_FUNCTION_LINE("IOCTL_PLUGIN_LOADER_GET_INFORMATION_DETAILS\n"); - if(message->ioctl.length_in != 8) { - DEBUG_FUNCTION_LINE("IPC_ERROR_INVALID_SIZE\n"); - res = IPC_ERROR_INVALID_SIZE; - } else { - plugin_information_handle * plugin_information_handle_list = (plugin_information_handle *) message->ioctl.buffer_in[0]; - uint32_t plugin_information_handle_list_size = (uint32_t) message->ioctl.buffer_in[1]; - - //DEBUG_FUNCTION_LINE("plugin_information_handle_list %08X plugin_information_handle_list_size %d\n",plugin_information_handle_list,plugin_information_handle_list_size); - - plugin_information * plugin_information_list = (plugin_information *) message->ioctl.buffer_io; - - if(message->ioctl.length_io < plugin_information_handle_list_size * sizeof(plugin_information)) { - res = IPC_ERROR_INVALID_SIZE; - } else { - if(plugin_information_handle_list != NULL && plugin_information_handle_list_size != 0) { - for(uint32_t i = 0; i < plugin_information_handle_list_size; i++ ) { - PluginInformation* curHandle = (PluginInformation * )plugin_information_handle_list[i]; - if(curHandle == NULL){ - continue; - } - plugin_information_list[i].handle = plugin_information_handle_list[i]; - strncpy(plugin_information_list[i].path, curHandle->getPath().c_str(),255); - strncpy(plugin_information_list[i].name, curHandle->getName().c_str(),255); - strncpy(plugin_information_list[i].author, curHandle->getAuthor().c_str(),255); - } - } else { - res = IPC_ERROR_INVALID_ARG; - } - } - DCFlushRange(message->ioctl.buffer_io,message->ioctl.length_io); - ICInvalidateRange(message->ioctl.buffer_io,message->ioctl.length_io); - } - break; - } - - case IOCTL_PLUGIN_LOADER_LINK_VIA_INFORMATION: { - DEBUG_FUNCTION_LINE("IOCTL_PLUGIN_LOADER_LINK_VIA_INFORMATION\n"); - if(message->ioctl.length_in != 12 || message->ioctl.length_io < 4) { - res = IPC_ERROR_INVALID_SIZE; - } else { - void * ptr = (void *) message->ioctl.buffer_in[0]; - plugin_information_handle * plugin_handle_list = (plugin_information_handle *) message->ioctl.buffer_in[1]; - uint32_t plugin_handle_list_size = (uint32_t) message->ioctl.buffer_in[2]; - //DEBUG_FUNCTION_LINE("ptr %08X plugin_handle_list %08X size %d\n",ptr,plugin_handle_list,plugin_handle_list_size); - uint32_t * linkedCount = (uint32_t *)message->ioctl.buffer_io; - *linkedCount = 0; - - if(ptr != NULL/* && (PluginLoader* pluginLoader = dynamic_cast(ptr))*/) { - PluginLoader* pluginLoader = (PluginLoader * )ptr; - std::vector willBeLoaded; - for(uint32_t i = 0; i < plugin_handle_list_size; i++ ) { - - plugin_information_handle curHandle = plugin_handle_list[i]; - //DEBUG_FUNCTION_LINE("Adding handle %08X\n",curHandle); - if(curHandle != 0/* && (PluginInformation* curInformation = dynamic_cast(curHandle))*/) { - PluginInformation* curInformation = (PluginInformation *)curHandle; - willBeLoaded.push_back(curInformation); - } - } - - //DEBUG_FUNCTION_LINE("willBeLoaded size is %d\n",willBeLoaded.size()); - - - RestoreEverything(); - pluginLoader->loadAndLinkPlugins(willBeLoaded); - afterLoadAndLink(); - - - *linkedCount = willBeLoaded.size(); - } else { - res = IPC_ERROR_INVALID_ARG; - } - } - break; - } - case IOCTL_PLUGIN_LOADER_LINK_VIA_INFORMATION_ON_RESTART: { - DEBUG_FUNCTION_LINE("IOCTL_PLUGIN_LOADER_LINK_VIA_INFORMATION_ON_RESTART\n"); - if(message->ioctl.length_in != 8 || message->ioctl.length_io < 4) { - res = IPC_ERROR_INVALID_SIZE; - } else { - plugin_information_handle * plugin_handle_list = (plugin_information_handle *) message->ioctl.buffer_in[0]; - uint32_t plugin_handle_list_size = (uint32_t) message->ioctl.buffer_in[1]; - - //DEBUG_FUNCTION_LINE("plugin_handle_list %08X size %d\n",plugin_handle_list,plugin_handle_list_size); - - uint32_t * linkedCount = (uint32_t *)message->ioctl.buffer_io; - *linkedCount = 0; - - int inGlobal = 0; - for(uint32_t i = 0; i < plugin_handle_list_size; i++ ) { - plugin_information_handle curHandle = plugin_handle_list[i]; - //DEBUG_FUNCTION_LINE("Adding handle %08X\n",curHandle); - if(curHandle != 0/* && (PluginInformation* curInformation = dynamic_cast(curHandle))*/) { - PluginInformation* curInformation = (PluginInformation *)curHandle; - if(inGlobal<=31){ - strncpy(gbl_to_link_and_load_data[inGlobal].name, curInformation->getPath().c_str(), 256); - inGlobal++; - } - } - } - - for(int i = 0; gbl_to_link_and_load_data[i].name[0] != 0; i++) { - //DEBUG_FUNCTION_LINE("%s\n",gbl_to_link_and_load_data[i].name); - } - - //DEBUG_FUNCTION_LINE("inGlobal size is %d\n",inGlobal); - gInBackground = false; - - *linkedCount = inGlobal; - } - break; - } - case IOCTL_PLUGIN_INFORMATION_GET_INFORMATION_FOR_FILEPATH: { - DEBUG_FUNCTION_LINE("IOCTL_PLUGIN_INFORMATION_GET_INFORMATION_FOR_FILEPATH\n"); - if(message->ioctl.length_in != 4 || message->ioctl.length_io != 4) { - DEBUG_FUNCTION_LINE("IPC_ERROR_INVALID_SIZE\n"); - res = IPC_ERROR_INVALID_SIZE; - } else { - char * path = (char *) message->ioctl.buffer_in[0]; - plugin_information_handle * io_handle = (plugin_information_handle *) &(message->ioctl.buffer_io[0]); - - //DEBUG_FUNCTION_LINE("filepath %08X %s\n", path,path); - - PluginInformation * plugin= PluginInformation::loadPluginInformation(path); - *io_handle = (plugin_information_handle) plugin; - - DCFlushRange(message->ioctl.buffer_io,message->ioctl.length_io); - ICInvalidateRange(message->ioctl.buffer_io,message->ioctl.length_io); - } - break; - } - default: - res = IPC_ERROR_INVALID_ARG; - break; - } - - return res; -} diff --git a/src/utils/ipc.h b/src/utils/ipc.h deleted file mode 100644 index fb3186a..0000000 --- a/src/utils/ipc.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef __IPC_UTILS_H_ -#define __IPC_UTILS_H_ - - - -#include "plugin/PluginLoader.h" -#include "plugin/PluginInformation.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -#define IPC_ERROR_INVALID_NONE 0 -#define IPC_ERROR_INVALID_SIZE 0xFFFFFFFF -#define IPC_ERROR_INVALID_ARG 0xFFFFFFFE -#define IPC_ERROR_FAILED_ALLOC 0xFFFFFFFD - -#define IOCTL_OPEN_PLUGIN_LOADER 0x01 -#define IOCTL_CLOSE_PLUGIN_LOADER 0x02 -#define IOCTL_PLUGIN_LOADER_GET_INFORMATION_FOR_PATH 0x03 -#define IOCTL_PLUGIN_LOADER_GET_INFORMATION_LOADED 0x04 -#define IOCTL_PLUGIN_LOADER_GET_INFORMATION_DETAILS 0x05 -#define IOCTL_PLUGIN_LOADER_DELETE_INFORMATION 0x06 -#define IOCTL_PLUGIN_LOADER_LINK_VIA_INFORMATION 0x07 -#define IOCTL_PLUGIN_LOADER_LINK_VIA_INFORMATION_ON_RESTART 0x08 -#define IOCTL_PLUGIN_INFORMATION_GET_INFORMATION_FOR_FILEPATH 0x09 - -/* IPC message */ -typedef struct ipcmessage { - uint32_t command; - union { - struct { - uint32_t *buffer_in; - uint32_t length_in; - uint32_t *buffer_io; - uint32_t length_io; - } ioctl; - }; -} __attribute__((packed)) ipcmessage; - -typedef uint32_t plugin_information_handle; - -/* plugin_information message */ -typedef struct plugin_information { - plugin_information_handle handle; - char path[256]; - char name[256]; - char author[256]; -} plugin_information; - -int ipc_ioctl(ipcmessage *message); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/utils/overlay_helper.cpp b/src/utils/overlay_helper.cpp deleted file mode 100644 index 9020b93..0000000 --- a/src/utils/overlay_helper.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#include -#include -#include -#include "common/retain_vars.h" -#include "overlay_helper.h" -#include "dynamic_libs/gx2_functions.h" - -uint32_t * getFromGX2Buffer(struct buffer_store store, uint32_t size) { - if(store.buffer != NULL) { - DEBUG_FUNCTION_LINE("We try to use the GX2 buffer. Needed space %08X (%d kb), available %08X (%d kb).\n",size,size/1024,store.buffer_size,store.buffer_size/1024); - if(store.buffer_size >= size) { - memset(store.buffer,0,store.buffer_size); - GX2Invalidate(GX2_INVALIDATE_CPU, store.buffer, store.buffer_size); - return (uint32_t*) store.buffer; - } - } - return NULL; -} - -void overlay_helper(wups_overlay_options_type_t screen, overlay_callback callback, void * args) { - if(callback == NULL) { - return; - } - if(!OSIsHomeButtonMenuEnabled()) { - return; // This pauses the game. Make sure to only do it when the home button is allowed. - } - - //TODO: Make sure this actually pauses the game (Hook on GX2VSync?) . Currently only tested from VPADRead which also pauses the game. - - OSScreenInit(); - - uint32_t * screenbuffer0 = NULL; - uint32_t * screenbuffer1 = NULL; - - bool allocated_tv = false; - bool allocated_drc = false; - - if(screen == WUPS_OVERLAY_DRC_ONLY) { - uint32_t screen_buf1_size = OSScreenGetBufferSizeEx(1); - screenbuffer1 = getFromGX2Buffer(tv_store,screen_buf1_size); - if(screenbuffer1 == NULL) { - DEBUG_FUNCTION_LINE("We need to try to allocate buffer for the DRC.\n"); - screenbuffer1 = (uint32_t*)memalign(0x100, screen_buf1_size); - if(screenbuffer1 != NULL) { - memset(screenbuffer1,0,screen_buf1_size); - DEBUG_FUNCTION_LINE("Successfully allocated DRC buffer!.\n"); - allocated_drc = true; - } - } - } else if(screen == WUPS_OVERLAY_TV_ONLY) { - uint32_t screen_buf0_size = OSScreenGetBufferSizeEx(0); - screenbuffer0 = getFromGX2Buffer(tv_store,screen_buf0_size); - - if(screenbuffer0 == NULL) { - DEBUG_FUNCTION_LINE("We need to try to allocate buffer for the TV.\n"); - screenbuffer0 = (uint32_t*)memalign(0x100, screen_buf0_size); - if(screenbuffer0 != NULL) { - memset(screenbuffer0,0,screen_buf0_size); - DEBUG_FUNCTION_LINE("Successfully allocated TV buffer!.\n"); - allocated_tv = true; - } - } - } else if( screen == WUPS_OVERLAY_DRC_AND_TV || screen == WUPS_OVERLAY_DRC_AND_TV_WITH_DRC_PRIO) { - // TV Buffer init. - uint32_t screen_buf0_size = OSScreenGetBufferSizeEx(0); - screenbuffer0 = getFromGX2Buffer(tv_store,screen_buf0_size); - if(screenbuffer0 == NULL) { - DEBUG_FUNCTION_LINE("We need to try to allocate buffer for the TV.\n"); - screenbuffer0 = (uint32_t*)memalign(0x100, screen_buf0_size); - if(screenbuffer0 != NULL) { - memset(screenbuffer0,0,screen_buf0_size); - DEBUG_FUNCTION_LINE("Successfully allocated TV buffer!.\n"); - allocated_tv = true; - } - } - - // DRC Buffer init. - uint32_t screen_buf1_size = OSScreenGetBufferSizeEx(1); - - // Doesn't fit in the GX2 DRC buffer, we don't need to check it. - DEBUG_FUNCTION_LINE("We need to try to allocate buffer for the DRC.\n"); - screenbuffer1 = (uint32_t*)memalign(0x100, screen_buf1_size); - if(screenbuffer1 != NULL) { - DEBUG_FUNCTION_LINE("Successfully allocated DRC buffer!.\n"); - allocated_drc = true; - } - - if(screenbuffer1 == NULL) { // FAILED to allocate, - if(screen == WUPS_OVERLAY_DRC_AND_TV_WITH_DRC_PRIO) { - DEBUG_FUNCTION_LINE("Successfully allocated DRC buffer!.\n"); - //but we can use the TV buffer from GX2. - if(!allocated_tv) { // Make sure it's not allocated - screenbuffer0 = NULL; // Bye bye - } - screenbuffer1 = getFromGX2Buffer(tv_store,screen_buf1_size); // Use it! Hopefully this works. - } - } - } - - if(screenbuffer0 == NULL && screenbuffer1 == NULL) { - goto error_exit; - } - - - if(screenbuffer0 != NULL) { - OSScreenSetBufferEx(0, (void *)screenbuffer0); - } - if(screenbuffer1 != NULL) { - OSScreenSetBufferEx(1, (void *)screenbuffer1); - } - - if(screenbuffer0 != NULL) { - OSScreenEnableEx(0, 1); - } - if(screenbuffer1 != NULL) { - OSScreenEnableEx(1, 1); - } - - // Clear screens - if(screenbuffer0 != NULL) { - OSScreenClearBufferEx(0, 0); - } - if(screenbuffer1 != NULL) { - OSScreenClearBufferEx(1, 0); - } - - // Flip buffers - if(screenbuffer0 != NULL) { - OSScreenFlipBuffersEx(0); - } - if(screenbuffer1 != NULL) { - OSScreenFlipBuffersEx(1); - } - - wups_overlay_options_type_t real_screen_type; - - if(screenbuffer0 != NULL) { - if(screenbuffer1 != NULL) { - real_screen_type = WUPS_OVERLAY_DRC_AND_TV; - } else { - real_screen_type = WUPS_OVERLAY_TV_ONLY; - } - } else if(screenbuffer1 != NULL) { - real_screen_type = WUPS_OVERLAY_DRC_ONLY; - } else { - real_screen_type = WUPS_OVERLAY_NONE; - } - - // call the callback. - if(real_screen_type != WUPS_OVERLAY_NONE) { - callback(real_screen_type, args); - } - - if(tv_store.buffer != NULL) { - GX2SetTVBuffer(tv_store.buffer,tv_store.buffer_size,tv_store.mode,tv_store.surface_format,tv_store.buffering_mode); - } - - if(drc_store.buffer != NULL) { - GX2SetDRCBuffer(drc_store.buffer,drc_store.buffer_size,drc_store.mode,drc_store.surface_format,drc_store.buffering_mode); - } - -error_exit: - if(allocated_tv) { - free(screenbuffer0); - screenbuffer0 = NULL; - } - - if(allocated_drc) { - free(screenbuffer1); - screenbuffer1 = NULL; - } - - return; -} diff --git a/src/utils/overlay_helper.h b/src/utils/overlay_helper.h deleted file mode 100644 index 62ddfd4..0000000 --- a/src/utils/overlay_helper.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __OVERLAY_HELPER_H_ -#define __OVERLAY_HELPER_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct buffer_store { - void * buffer; - int32_t buffer_size; - int32_t mode; - int32_t surface_format; - volatile int32_t buffering_mode; -}; - -#ifdef __cplusplus -} -#endif - -void overlay_helper(wups_overlay_options_type_t screen, overlay_callback callback, void * args); - -#endif diff --git a/src/utils/utils.h b/src/utils/utils.h deleted file mode 100644 index 39324ed..0000000 --- a/src/utils/utils.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef __UTILS_H_ -#define __UTILS_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define FlushBlock(addr) asm volatile("dcbf %0, %1\n" \ - "icbi %0, %1\n" \ - "sync\n" \ - "eieio\n" \ - "isync\n" \ - : \ - :"r"(0), "r"(((addr) & ~31)) \ - :"memory", "ctr", "lr", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" \ - ); - -#define LIMIT(x, min, max) \ - ({ \ - typeof( x ) _x = x; \ - typeof( min ) _min = min; \ - typeof( max ) _max = max; \ - ( ( ( _x ) < ( _min ) ) ? ( _min ) : ( ( _x ) > ( _max ) ) ? ( _max) : ( _x ) ); \ - }) - -#define DegToRad(a) ( (a) * 0.01745329252f ) -#define RadToDeg(a) ( (a) * 57.29577951f ) - -#define ALIGN4(x) (((x) + 3) & ~3) -#define ALIGN32(x) (((x) + 31) & ~31) - -// those work only in powers of 2 -#define ROUNDDOWN(val, align) ((val) & ~(align-1)) -#define ROUNDUP(val, align) ROUNDDOWN(((val) + (align-1)), align) - -#define le16(i) ((((u16) ((i) & 0xFF)) << 8) | ((u16) (((i) & 0xFF00) >> 8))) -#define le32(i) ((((u32)le16((i) & 0xFFFF)) << 16) | ((u32)le16(((i) & 0xFFFF0000) >> 16))) -#define le64(i) ((((u64)le32((i) & 0xFFFFFFFFLL)) << 32) | ((u64)le32(((i) & 0xFFFFFFFF00000000LL) >> 32))) - -unsigned int getApplicationEndAddr(void); - -//Need to have log_init() called beforehand. -void dumpHex(const void* data, size_t size); - -#ifdef __cplusplus -} -#endif - -#endif // __UTILS_H_