From 9bef4145102856f446faf5cc4e0c1ddad818bc03 Mon Sep 17 00:00:00 2001 From: jakcron Date: Thu, 6 Sep 2018 21:12:15 +0800 Subject: [PATCH] [nstool|fnd|hac] Fixed bugs in elf symbol processing (NSO|NRO handling). --- lib/libfnd/include/fnd/elf.h | 624 +++++++++++++------ lib/libhac/include/nn/hac/elf.h | 70 --- programs/nstool/source/ElfSymbolParser.cpp | 27 +- programs/nstool/source/ElfSymbolParser.h | 9 +- programs/nstool/source/RoMetadataProcess.cpp | 52 +- programs/nstool/source/RoMetadataProcess.h | 6 +- programs/nstool/source/version.h | 2 +- 7 files changed, 482 insertions(+), 308 deletions(-) delete mode 100644 lib/libhac/include/nn/hac/elf.h diff --git a/lib/libfnd/include/fnd/elf.h b/lib/libfnd/include/fnd/elf.h index d46d20d..0f32ccd 100644 --- a/lib/libfnd/include/fnd/elf.h +++ b/lib/libfnd/include/fnd/elf.h @@ -1,216 +1,458 @@ #pragma once #include "types.h" -typedef byte_t Elf_Byte; -typedef word_t Elf32_Addr; -typedef word_t Elf32_Off; -typedef long_t Elf32_Sword; // lol "sword" -typedef word_t Elf32_Word; -typedef hword_t Elf32_Half; - -enum +namespace fnd { - EI_MAG0 = 0, // 0x7F - EI_MAG1 = 1, // 'E' - EI_MAG2 = 2, // 'L' - EI_MAG3 = 3, // 'F' - EI_CLASS = 4, // File class - EI_DATA = 5, // Data encoding - EI_VERSION = 6, // File version - EI_PAD = 7, // Start of padding bytes - EI_NIDENT = 16 // Size of e_ident[] -}; + namespace elf + { + /* These constants are for the segment types stored in the image headers */ + enum SegmentType + { + PT_NULL = 0, + PT_LOAD = 1, + PT_DYNAMIC = 2, + PT_INTERP = 3, + PT_NOTE = 4, + PT_SHLIB = 5, + PT_PHDR = 6, + PT_TLS = 7, /* Thread local storage segment */ + PT_LOOS = 0x60000000, /* OS-specific */ + PT_HIOS = 0x6fffffff, /* OS-specific */ + PT_LOPROC = 0x70000000, + PT_HIPROC = 0x7fffffff + }; -typedef struct -{ - unsigned char e_ident[EI_NIDENT]; // Identification bytes - Elf32_Half e_type; // Object file type - Elf32_Half e_machine; // Object architecture - Elf32_Word e_version; // Object file version - Elf32_Addr e_entry; // Object entry point - Elf32_Off e_phoff; // Program header file offset - Elf32_Off e_shoff; // Section header file offset - Elf32_Word e_flags; // Processor-specific flags - Elf32_Half e_ehsize; // ELF header size - Elf32_Half e_phentsize; // Program header entry size - Elf32_Half e_phnum; // Program header entries - Elf32_Half e_shentsize; // Section header entry size - Elf32_Half e_shnum; // Section header entries - Elf32_Half e_shstrndx; // String table index -} Elf32_Ehdr; + /* These constants define the different elf file types */ + enum ElfType + { + ET_NONE = 0, + ET_REL = 1, + ET_EXEC = 2, + ET_DYN = 3, + ET_CORE = 4, + ET_LOPROC = 0xff00, + ET_HIPROC = 0xffff + }; -typedef struct -{ - Elf32_Word p_type; // Segment type - Elf32_Off p_offset; // File offset - Elf32_Addr p_vaddr; // Virtual address - Elf32_Addr p_paddr; // Physical address - Elf32_Word p_filesz; // File image size - Elf32_Word p_memsz; // Memory image size - Elf32_Word p_flags; // Segment flags - Elf32_Word p_align; // Alignment value -} Elf32_Phdr; + /* This is the info that is needed to parse the dynamic section of the file */ + enum DynamicSectionType + { + DT_NULL = 0, + DT_NEEDED = 1, + DT_PLTRELSZ = 2, + DT_PLTGOT = 3, + DT_HASH = 4, + DT_STRTAB = 5, + DT_SYMTAB = 6, + DT_RELA = 7, + DT_RELASZ = 8, + DT_RELAENT = 9, + DT_STRSZ = 10, + DT_SYMENT = 11, + DT_INIT = 12, + DT_FINI = 13, + DT_SONAME = 14, + DT_RPATH = 15, + DT_SYMBOLIC = 16, + DT_REL = 17, + DT_RELSZ = 18, + DT_RELENT = 19, + DT_PLTREL = 20, + DT_DEBUG = 21, + DT_TEXTREL = 22, + DT_JMPREL = 23, + DT_ENCODING = 32, + OLD_DT_LOOS = 0x60000000, + DT_LOOS = 0x6000000d, + DT_HIOS = 0x6ffff000, + DT_VALRNGLO = 0x6ffffd00, + DT_VALRNGHI = 0x6ffffdff, + DT_ADDRRNGLO = 0x6ffffe00, + DT_ADDRRNGHI = 0x6ffffeff, + DT_VERSYM = 0x6ffffff0, + DT_RELACOUNT = 0x6ffffff9, + DT_RELCOUNT = 0x6ffffffa, + DT_FLAGS_1 = 0x6ffffffb, + DT_VERDEF = 0x6ffffffc, + DT_VERDEFNUM = 0x6ffffffd, + DT_VERNEED = 0x6ffffffe, + DT_VERNEEDNUM = 0x6fffffff, + OLD_DT_HIOS = 0x6fffffff, + DT_LOPROC = 0x70000000, + DT_HIPROC = 0x7fffffff + }; -typedef struct -{ - Elf32_Word sh_name; // Name (index into section header string table section) - Elf32_Word sh_type; // Type - Elf32_Word sh_flags; // Flags - Elf32_Addr sh_addr; // Address - Elf32_Off sh_offset; // File offset - Elf32_Word sh_size; // Section size - Elf32_Word sh_link; // Section header table index link - Elf32_Word sh_info; // Extra information - Elf32_Word sh_addralign; // Address alignment - Elf32_Word sh_entsize; // Section entry size -} Elf32_Shdr; + /* This info is needed when parsing the symbol table */ + enum SymbolBinding + { + STB_LOCAL = 0, + STB_GLOBAL = 1, + STB_WEAK = 2, + STB_LOOS = 10, + STB_HIOS = 12, + STB_LOPROC, + STB_HIPROC = 0xf + }; -typedef struct -{ - Elf32_Addr r_offset; // Offset of relocation - Elf32_Word r_info; // Symbol table index and type -} Elf32_Rel; + enum SymbolType + { + STT_NOTYPE = 0, + STT_OBJECT = 1, + STT_FUNC = 2, + STT_SECTION = 3, + STT_FILE = 4, + STT_COMMON = 5, + STT_TLS = 6, + STT_LOOS = 10, + STT_HIOS = 12, + STT_LOPROC, + STT_HIPROC = 0xf + }; -typedef struct -{ - Elf32_Word st_name; // Name - index into string table - Elf32_Addr st_value; // Symbol value - Elf32_Word st_size; // Symbol size - unsigned char st_info; // Type and binding - unsigned char st_other; // Visibility - Elf32_Half st_shndx; // Section header index -} Elf32_Sym; + /* These constants define the permissions on sections in the program + header, p_flags. */ + enum PermissionFlag + { + PF_R = 0x4, + PF_W = 0x2, + PF_X = 0x1 + }; -enum -{ - ET_NONE = 0, // No file type - ET_REL = 1, // Relocatable file - ET_EXEC = 2, // Executable file - ET_DYN = 3, // Shared object file - ET_CORE = 4, // Core file -}; + /* sh_type */ + enum SectionHeaderType + { + SHT_NULL = 0, + SHT_PROGBITS = 1, + SHT_SYMTAB = 2, + SHT_STRTAB = 3, + SHT_RELA = 4, + SHT_HASH = 5, + SHT_DYNAMIC = 6, + SHT_NOTE = 7, + SHT_NOBITS = 8, + SHT_REL = 9, + SHT_SHLIB = 10, + SHT_DYNSYM = 11, + SHT_NUM = 12, + SHT_LOPROC = 0x70000000, + SHT_HIPROC = 0x7fffffff, + SHT_LOUSER = 0x80000000, + SHT_HIUSER = 0xffffffff + }; + + /* sh_flags */ + enum SectionHeaderFlag + { + SHF_WRITE = 0x1, + SHF_ALLOC = 0x2, + SHF_EXECINSTR = 0x4, + SHF_RELA_LIVEPATCH = 0x00100000, + SHF_RO_AFTER_INIT = 0x00200000, + SHF_MASKPROC = 0xf0000000 + }; + + /* special section indexes */ + enum SpecialSectionIndex + { + SHN_UNDEF = 0, + SHN_LORESERVE = 0xff00, + SHN_LOPROC = 0xff00, + SHN_HIPROC = 0xff1f, + SHN_LOOS = 0xff20, + SHN_HIOS = 0xff3f, + SHN_ABS = 0xfff1, + SHN_COMMON = 0xfff2, + SHN_HIRESERVE = 0xffff + }; -enum -{ - ET_ARM = 40 // ARM architecture -}; + enum ElfIdentIndex + { + EI_MAG0 = 0, /* e_ident[] indexes */ + EI_MAG1 = 1, + EI_MAG2 = 2, + EI_MAG3 = 3, + EI_CLASS = 4, + EI_DATA = 5, + EI_VERSION = 6, + EI_OSABI = 7, + EI_PAD = 8 + }; -enum -{ - EV_NONE = 0, // Invalid version - EV_CURRENT = 1 // Current version -}; + enum ElfClass + { + ELFCLASSNONE = 0, /* EI_CLASS */ + ELFCLASS32 = 1, + ELFCLASS64 = 2, + ELFCLASSNUM = 3 + }; + + enum ElfData + { + ELFDATANONE = 0, /* e_ident[EI_DATA] */ + ELFDATA2LSB = 1, + ELFDATA2MSB = 2 + }; + + enum ElfVersion + { + EV_NONE = 0, /* e_version, EI_VERSION */ + EV_CURRENT = 1, + EV_NUM = 2, + }; + + enum ElfOsAbi + { + ELFOSABI_NONE = 0, + ELFOSABI_LINUX =3 + }; + -#define ELF_MAGIC "\177ELF" + /* + * Notes used in ET_CORE. Architectures export some of the arch register sets + * using the corresponding note types via the PTRACE_GETREGSET and + * PTRACE_SETREGSET requests. + */ + enum NoteType + { + NT_PRSTATUS = 1, + NT_PRFPREG = 2, + NT_PRPSINFO = 3, + NT_TASKSTRUCT = 4, + NT_AUXV = 6, + /* + * Note to userspace developers: size of NT_SIGINFO note may increase + * in the future to accomodate more fields, don't assume it is fixed! + */ + NT_SIGINFO = 0x53494749, + NT_FILE = 0x46494c45, + NT_PRXFPREG = 0x46e62b7f, /* copied from gdb5.1/include/elf/common.h */ + NT_PPC_VMX = 0x100, /* PowerPC Altivec/VMX registers */ + NT_PPC_SPE = 0x101, /* PowerPC SPE/EVR registers */ + NT_PPC_VSX = 0x102, /* PowerPC VSX registers */ + NT_PPC_TAR = 0x103, /* Target Address Register */ + NT_PPC_PPR = 0x104, /* Program Priority Register */ + NT_PPC_DSCR = 0x105, /* Data Stream Control Register */ + NT_PPC_EBB = 0x106, /* Event Based Branch Registers */ + NT_PPC_PMU = 0x107, /* Performance Monitor Registers */ + NT_PPC_TM_CGPR = 0x108, /* TM checkpointed GPR Registers */ + NT_PPC_TM_CFPR = 0x109, /* TM checkpointed FPR Registers */ + NT_PPC_TM_CVMX = 0x10a, /* TM checkpointed VMX Registers */ + NT_PPC_TM_CVSX = 0x10b, /* TM checkpointed VSX Registers */ + NT_PPC_TM_SPR = 0x10c, /* TM Special Purpose Registers */ + NT_PPC_TM_CTAR = 0x10d, /* TM checkpointed Target Address Register */ + NT_PPC_TM_CPPR = 0x10e, /* TM checkpointed Program Priority Register */ + NT_PPC_TM_CDSCR = 0x10f, /* TM checkpointed Data Stream Control Register */ + NT_PPC_PKEY = 0x110, /* Memory Protection Keys registers */ + NT_386_TLS = 0x200, /* i386 TLS slots (struct user_desc) */ + NT_386_IOPERM = 0x201, /* x86 io permission bitmap (1=deny) */ + NT_X86_XSTATE = 0x202, /* x86 extended state using xsave */ + NT_S390_HIGH_GPRS = 0x300, /* s390 upper register halves */ + NT_S390_TIMER = 0x301, /* s390 timer register */ + NT_S390_TODCMP = 0x302, /* s390 TOD clock comparator register */ + NT_S390_TODPREG = 0x303, /* s390 TOD programmable register */ + NT_S390_CTRS = 0x304, /* s390 control registers */ + NT_S390_PREFIX = 0x305, /* s390 prefix register */ + NT_S390_LAST_BREAK = 0x306, /* s390 breaking event address */ + NT_S390_SYSTEM_CALL = 0x307, /* s390 system call restart data */ + NT_S390_TDB = 0x308, /* s390 transaction diagnostic block */ + NT_S390_VXRS_LOW = 0x309, /* s390 vector registers 0-15 upper half */ + NT_S390_VXRS_HIGH = 0x30a, /* s390 vector registers 16-31 */ + NT_S390_GS_CB = 0x30b, /* s390 guarded storage registers */ + NT_S390_GS_BC = 0x30c, /* s390 guarded storage broadcast control block */ + NT_S390_RI_CB = 0x30d, /* s390 runtime instrumentation */ + NT_ARM_VFP = 0x400, /* ARM VFP/NEON registers */ + NT_ARM_TLS = 0x401, /* ARM TLS register */ + NT_ARM_HW_BREAK = 0x402, /* ARM hardware breakpoint registers */ + NT_ARM_HW_WATCH = 0x403, /* ARM hardware watchpoint registers */ + NT_ARM_SYSTEM_CALL = 0x404, /* ARM system call number */ + NT_ARM_SVE = 0x405, /* ARM Scalable Vector Extension registers */ + NT_ARC_V2 = 0x600, /* ARCv2 accumulator/extra registers */ + NT_VMCOREDD = 0x700, /* Vmcore Device Dump Note */ + NT_MIPS_DSP = 0x800, /* MIPS DSP ASE registers */ + NT_MIPS_FP_MODE = 0x801, /* MIPS floating-point mode */ + }; + + static const size_t kEIdentSize = 0x10; + static const byte_t kElfMagic[sizeof(uint32_t)] = {0x7f, 'E', 'L', 'F'}; -enum -{ - ELFDATANONE = 0, // Invalid data encoding - ELFDATA2LSB = 1, // Little endian - ELFDATA2MSB = 2, // Big endian -}; -enum -{ - PT_NULL = 0, // Unused - PT_LOAD = 1, // Loadable segment - PT_DYNAMIC = 2, // Dynamic linking information - PT_INTERP = 3, // Interpreter - PT_NOTE = 4, // Auxiliary information - PT_SHLIB = 5, // Reserved - PT_PHDR = 6 // Program header table -}; + inline byte_t get_elf_st_bind(byte_t st_info) { return st_info >> 4; } + inline byte_t get_elf_st_type(byte_t st_info) { return st_info & 0xf; } + inline byte_t get_elf_st_info(byte_t st_bind, byte_t st_type) { return (st_type & 0xf) | ((st_bind & 0xf) << 4);} -enum -{ - PF_R = 4, // Read flag - PF_W = 2, // Write flag - PF_X = 1, // Execute flag - PF_OS_SHARED = 0x100000, // OS-specific - PF_CTRSDK = 0x80000000, // Set in CTRSDK ELF Text segments -}; + /* The following are used with relocations */ + #define ELF32_R_SYM(x) ((x) >> 8) + #define ELF32_R_TYPE(x) ((x) & 0xff) -enum -{ - SHN_LORESERVE = 0xFF00, - SHN_HIRESERVE = 0xFFFF -}; + #define ELF64_R_SYM(i) ((i) >> 32) + #define ELF64_R_TYPE(i) ((i) & 0xffffffff) + } -enum -{ - SHT_NULL = 0, // Inactive - SHT_PROGBITS = 1, // Program defined information - SHT_SYMTAB = 2, // Symbol table section - SHT_STRTAB = 3, // String table section - SHT_RELA = 4, // Relocation section with addends - SHT_HASH = 5, // Symbol hash table section - SHT_DYNAMIC = 6, // Dynamic section - SHT_NOTE = 7, // Note section - SHT_NOBITS = 8, // No space section - SHT_REL = 9, // Relation section without addends - SHT_SHLIB = 10, // Reserved - SHT_DYNSYM = 11, // Dynamic symbol table section - SHT_NUM = 12, // Number of section types - SHT_LOPROC = 0x70000000, // Reserved range for processor - SHT_ARM_EXIDX = 0x70000001, // ARM exception index table - SHT_HIPROC = 0x7fffffff, // Specific section header types - SHT_LOUSER = 0x80000000, // Reserved range for application - SHT_HIUSER = 0xffffffff // Specific indexes -}; + struct Elf32_Dyn + { + int32_t d_tag; + union{ + int32_t d_val; + uint32_t d_ptr; + } d_un; + }; -enum -{ - SHF_WRITE = 1, // Writable section - SHF_ALLOC = 2, // Loadable section - SHF_EXECINSTR = 4, // Executable section - SHF_MASKPROC = 0xf0000000, // Processor-specific -}; + struct Elf64_Dyn + { + int64_t d_tag; /* entry tag value */ + union { + uint64_t d_val; + uint64_t d_ptr; + } d_un; + }; -#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)) + struct Elf32_Rel + { + uint32_t r_offset; + uint32_t r_info; + }; -enum -{ - R_ARM_NONE = 0, - R_ARM_PC24 = 1, - R_ARM_ABS32 = 2, - R_ARM_REL32 = 3, - R_ARM_THM_CALL = 10, - R_ARM_PLT32 = 27, - R_ARM_CALL = 28, - R_ARM_JUMP24 = 29, - R_ARM_TARGET1 = 38, - R_ARM_TARGET2 = 41, - R_ARM_PREL31 = 42, - R_ARM_THM_JUMP11 = 102, - R_ARM_THM_JUMP8 = 103 -}; + struct Elf64_Rel + { + uint64_t r_offset; /* Location at which to apply the action */ + uint64_t r_info; /* index and type of relocation */ + }; -// Symbol scope -enum -{ - STB_LOCAL = 0, - STB_GLOBAL = 1, - STB_WEAK = 2 -}; + struct Elf32_Rela + { + uint32_t r_offset; + uint32_t r_info; + int32_t r_addend; + }; -#define ELF32_ST_BIND(i) (((unsigned char)(i)) >> 4) -#define ELF32_ST_TYPE(val) ((val) & 0xf) + struct Elf64_Rela + { + uint64_t r_offset; /* Location at which to apply the action */ + uint64_t r_info; /* index and type of relocation */ + int64_t r_addend; /* Constant addend used to compute value */ + }; -// Symbol type -enum -{ - STT_NOTYPE = 0, - STT_OBJECT = 1, - STT_FUNC = 2 -}; + struct Elf32_Sym + { + uint32_t st_name; + uint32_t st_value; + uint32_t st_size; + byte_t st_info; + byte_t st_other; + uint16_t st_shndx; + }; -// Symbol visibility -enum -{ - STV_DEFAULT = 0, - STV_INTERNAL = 1, - STV_HIDDEN = 2, - STV_PROTECTED = 3 -}; + struct Elf64_Sym + { + uint32_t st_name; /* Symbol name, index in string tbl */ + byte_t st_info; /* Type and binding attributes */ + byte_t st_other; /* No defined meaning, 0 */ + uint16_t st_shndx; /* Associated section index */ + uint64_t st_value; /* Value of the symbol */ + uint64_t st_size; /* Associated symbol size */ + }; + + struct Elf32_Ehdr + { + byte_t e_ident[elf::kEIdentSize]; + uint16_t e_type; + uint16_t e_machine; + uint32_t e_version; + uint32_t e_entry; /* Entry point */ + uint32_t e_phoff; + uint32_t e_shoff; + uint32_t e_flags; + uint16_t e_ehsize; + uint16_t e_phentsize; + uint16_t e_phnum; + uint16_t e_shentsize; + uint16_t e_shnum; + uint16_t e_shstrndx; + }; + + struct Elf64_Ehdr + { + byte_t e_ident[elf::kEIdentSize]; /* ELF "magic number" */ + uint16_t e_type; + uint16_t e_machine; + uint32_t e_version; + uint64_t e_entry; /* Entry point virtual address */ + uint64_t e_phoff; /* Program header table file offset */ + uint64_t e_shoff; /* Section header table file offset */ + uint32_t e_flags; + uint16_t e_ehsize; + uint16_t e_phentsize; + uint16_t e_phnum; + uint16_t e_shentsize; + uint16_t e_shnum; + uint16_t e_shstrndx; + }; + + struct Elf32_Phdr + { + uint32_t p_type; + uint32_t p_offset; + uint32_t p_vaddr; + uint32_t p_paddr; + uint32_t p_filesz; + uint32_t p_memsz; + uint32_t p_flags; + uint32_t p_align; + }; + + struct Elf64_Phdr + { + uint32_t p_type; + uint32_t p_flags; + uint64_t p_offset; /* Segment file offset */ + uint64_t p_vaddr; /* Segment virtual address */ + uint64_t p_paddr; /* Segment physical address */ + uint64_t p_filesz; /* Segment size in file */ + uint64_t p_memsz; /* Segment size in memory */ + uint64_t p_align; /* Segment alignment, file & memory */ + }; + + struct Elf32_Shdr + { + uint32_t sh_name; + uint32_t sh_type; + uint32_t sh_flags; + uint32_t sh_addr; + uint32_t sh_offset; + uint32_t sh_size; + uint32_t sh_link; + uint32_t sh_info; + uint32_t sh_addralign; + uint32_t sh_entsize; + }; + + struct Elf64_Shdr + { + uint32_t sh_name; /* Section name, index in string tbl */ + uint32_t sh_type; /* Type of section */ + uint64_t sh_flags; /* Miscellaneous section attributes */ + uint64_t sh_addr; /* Section virtual addr at execution */ + uint64_t sh_offset; /* Section file offset */ + uint64_t sh_size; /* Size of section in bytes */ + uint32_t sh_link; /* Index of another section */ + uint32_t sh_info; /* Additional section information */ + uint64_t sh_addralign; /* Section alignment */ + uint64_t sh_entsize; /* Entry size if section holds table */ + }; + + /* Note header in a PT_NOTE section */ + struct Elf32_Nhdr + { + uint32_t n_namesz; /* Name size */ + uint32_t n_descsz; /* Content size */ + uint32_t n_type; /* Content type */ + }; + + /* Note header in a PT_NOTE section */ + struct Elf64_Nhdr + { + uint32_t n_namesz; /* Name size */ + uint32_t n_descsz; /* Content size */ + uint32_t n_type; /* Content type */ + }; +} \ No newline at end of file diff --git a/lib/libhac/include/nn/hac/elf.h b/lib/libhac/include/nn/hac/elf.h deleted file mode 100644 index 2083238..0000000 --- a/lib/libhac/include/nn/hac/elf.h +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once -#include - -namespace nn -{ -namespace hac -{ - namespace elf - { - enum SpecialSectionIndex - { - SHN_UNDEF, - SHN_LORESERVE = 0xFF00, - SHN_LOPROC = 0xFF00, - SHN_HIPROC = 0xFF1F, - SHN_LOOS, - SHN_HIOS = 0xFF3F, - SHN_ABS = 0xFFF1, - SHN_COMMON, - SHN_HIRESERVE = 0xFFFF - }; - - enum SymbolType - { - STT_NOTYPE, - STT_OBJECT, - STT_FUNC, - STT_SECTION, - STT_FILE, - STT_LOOS = 10, - STT_HIOS = 12, - STT_LOPROC, - STT_HIPROC = 0xF - }; - - enum SymbolBinding - { - STB_LOCAL, - STB_GLOBAL, - STB_WEAK, - STB_LOOS = 10, - STB_HIOS = 12, - STB_LOPROC, - STB_HIPROC = 0xF - }; - } - -#pragma pack(push,1) - struct sElfSymbol32Bit - { - le_uint32_t name; - le_uint32_t value; - le_uint32_t size; - le_uint32_t info; - le_uint32_t other; - le_uint32_t special_section_index; - }; - - struct sElfSymbol64Bit - { - le_uint32_t name; - byte_t info; - byte_t other; - le_uint16_t special_section_index; - le_uint64_t value; - le_uint64_t size; - }; -#pragma pack(pop) -} -} \ No newline at end of file diff --git a/programs/nstool/source/ElfSymbolParser.cpp b/programs/nstool/source/ElfSymbolParser.cpp index acac3d0..9f4bed9 100644 --- a/programs/nstool/source/ElfSymbolParser.cpp +++ b/programs/nstool/source/ElfSymbolParser.cpp @@ -23,37 +23,38 @@ bool ElfSymbolParser::operator!=(const ElfSymbolParser& other) const void ElfSymbolParser::parseData(const byte_t *dyn_sym, size_t dyn_sym_size, const byte_t *dyn_str, size_t dyn_str_size, bool is64Bit) { //printf("ElfSymbolParser::parseData()"); - size_t dynSymSize = is64Bit ? sizeof(nn::hac::sElfSymbol64Bit) : sizeof(nn::hac::sElfSymbol32Bit); + size_t dynSymSize = is64Bit ? sizeof(fnd::Elf64_Sym) : sizeof(fnd::Elf32_Sym); sElfSymbol symbol; for (size_t i = 0; i < dyn_sym_size; i += dynSymSize) { - //printf("pos %x\n", i); - uint32_t name_pos; if (is64Bit) { - name_pos = ((nn::hac::sElfSymbol64Bit*)(dyn_sym + i))->name.get(); - symbol.shn_index = (nn::hac::elf::SpecialSectionIndex)((nn::hac::sElfSymbol64Bit*)(dyn_sym + i))->special_section_index.get(); - symbol.symbol_type = (nn::hac::elf::SymbolType)((((nn::hac::sElfSymbol64Bit*)(dyn_sym + i))->info) & nn::hac::elf::STT_HIPROC); - symbol.symbol_binding = (nn::hac::elf::SymbolBinding)(((((nn::hac::sElfSymbol64Bit*)(dyn_sym + i))->info) >> 4) & nn::hac::elf::STB_HIPROC); + name_pos = le_word(((fnd::Elf64_Sym*)(dyn_sym + i))->st_name); + symbol.shn_index = le_hword(((fnd::Elf64_Sym*)(dyn_sym + i))->st_shndx); + symbol.symbol_type = fnd::elf::get_elf_st_type(((fnd::Elf64_Sym*)(dyn_sym + i))->st_info); + symbol.symbol_binding = fnd::elf::get_elf_st_bind(((fnd::Elf64_Sym*)(dyn_sym + i))->st_info); } else { - name_pos = ((nn::hac::sElfSymbol64Bit*)(dyn_sym + i))->name.get(); - symbol.shn_index = (nn::hac::elf::SpecialSectionIndex)((nn::hac::sElfSymbol32Bit*)(dyn_sym + i))->special_section_index.get(); - symbol.symbol_type = (nn::hac::elf::SymbolType)((((nn::hac::sElfSymbol32Bit*)(dyn_sym + i))->info.get()) & nn::hac::elf::STT_HIPROC); - symbol.symbol_binding = (nn::hac::elf::SymbolBinding)(((((nn::hac::sElfSymbol32Bit*)(dyn_sym + i))->info.get()) >> 4) & nn::hac::elf::STB_HIPROC); + name_pos = le_word(((fnd::Elf32_Sym*)(dyn_sym + i))->st_name); + symbol.shn_index = le_hword(((fnd::Elf32_Sym*)(dyn_sym + i))->st_shndx); + symbol.symbol_type = fnd::elf::get_elf_st_type(((fnd::Elf32_Sym*)(dyn_sym + i))->st_info); + symbol.symbol_binding = fnd::elf::get_elf_st_bind(((fnd::Elf32_Sym*)(dyn_sym + i))->st_info); + } + + if (name_pos >= dyn_str_size) + { + throw fnd::Exception(kModuleName, "Out of bounds symbol name offset"); } for (; dyn_str[name_pos] == 0x00 && name_pos < dyn_str_size; name_pos++); - //printf("name_pos = 0x%x\n", name_pos); symbol.name = std::string((char*)&dyn_str[name_pos]); mSymbolList.addElement(symbol); } - //printf("ElfSymbolParser::parseData() end\n"); } const fnd::List& ElfSymbolParser::getSymbolList() const diff --git a/programs/nstool/source/ElfSymbolParser.h b/programs/nstool/source/ElfSymbolParser.h index a4e4b5c..e06bdf3 100644 --- a/programs/nstool/source/ElfSymbolParser.h +++ b/programs/nstool/source/ElfSymbolParser.h @@ -1,16 +1,16 @@ #pragma once #include #include -#include +#include class ElfSymbolParser { public: struct sElfSymbol { - nn::hac::elf::SpecialSectionIndex shn_index; - nn::hac::elf::SymbolType symbol_type; - nn::hac::elf::SymbolBinding symbol_binding; + uint16_t shn_index; + byte_t symbol_type; + byte_t symbol_binding; std::string name; void operator=(const sElfSymbol& other) @@ -42,6 +42,7 @@ public: const fnd::List& getSymbolList() const; private: + const std::string kModuleName = "ElfSymbolParser"; // data fnd::List mSymbolList; diff --git a/programs/nstool/source/RoMetadataProcess.cpp b/programs/nstool/source/RoMetadataProcess.cpp index afbb982..6d0f4ba 100644 --- a/programs/nstool/source/RoMetadataProcess.cpp +++ b/programs/nstool/source/RoMetadataProcess.cpp @@ -177,30 +177,30 @@ void RoMetadataProcess::displayRoMetaData() } } -const char* RoMetadataProcess::getSectionIndexStr(nn::hac::elf::SpecialSectionIndex shn_index) const +const char* RoMetadataProcess::getSectionIndexStr(uint16_t shn_index) const { const char* str; switch (shn_index) { - case (nn::hac::elf::SHN_UNDEF): + case (fnd::elf::SHN_UNDEF): str = "UNDEF"; break; - case (nn::hac::elf::SHN_LOPROC): + case (fnd::elf::SHN_LOPROC): str = "LOPROC"; break; - case (nn::hac::elf::SHN_HIPROC): + case (fnd::elf::SHN_HIPROC): str = "HIPROC"; break; - case (nn::hac::elf::SHN_LOOS): + case (fnd::elf::SHN_LOOS): str = "LOOS"; break; - case (nn::hac::elf::SHN_HIOS): + case (fnd::elf::SHN_HIOS): str = "HIOS"; break; - case (nn::hac::elf::SHN_ABS): + case (fnd::elf::SHN_ABS): str = "ABS"; break; - case (nn::hac::elf::SHN_COMMON): + case (fnd::elf::SHN_COMMON): str = "COMMON"; break; default: @@ -210,36 +210,36 @@ const char* RoMetadataProcess::getSectionIndexStr(nn::hac::elf::SpecialSectionIn return str; } -const char* RoMetadataProcess::getSymbolTypeStr(nn::hac::elf::SymbolType symbol_type) const +const char* RoMetadataProcess::getSymbolTypeStr(byte_t symbol_type) const { const char* str; switch (symbol_type) { - case (nn::hac::elf::STT_NOTYPE): + case (fnd::elf::STT_NOTYPE): str = "NOTYPE"; break; - case (nn::hac::elf::STT_OBJECT): + case (fnd::elf::STT_OBJECT): str = "OBJECT"; break; - case (nn::hac::elf::STT_FUNC): + case (fnd::elf::STT_FUNC): str = "FUNC"; break; - case (nn::hac::elf::STT_SECTION): + case (fnd::elf::STT_SECTION): str = "SECTION"; break; - case (nn::hac::elf::STT_FILE): + case (fnd::elf::STT_FILE): str = "FILE"; break; - case (nn::hac::elf::STT_LOOS): + case (fnd::elf::STT_LOOS): str = "LOOS"; break; - case (nn::hac::elf::STT_HIOS): + case (fnd::elf::STT_HIOS): str = "HIOS"; break; - case (nn::hac::elf::STT_LOPROC): + case (fnd::elf::STT_LOPROC): str = "LOPROC"; break; - case (nn::hac::elf::STT_HIPROC): + case (fnd::elf::STT_HIPROC): str = "HIPROC"; break; default: @@ -249,30 +249,30 @@ const char* RoMetadataProcess::getSymbolTypeStr(nn::hac::elf::SymbolType symbol_ return str; } -const char* RoMetadataProcess::getSymbolBindingStr(nn::hac::elf::SymbolBinding symbol_binding) const +const char* RoMetadataProcess::getSymbolBindingStr(byte_t symbol_binding) const { const char* str; switch (symbol_binding) { - case (nn::hac::elf::STB_LOCAL): + case (fnd::elf::STB_LOCAL): str = "LOCAL"; break; - case (nn::hac::elf::STB_GLOBAL): + case (fnd::elf::STB_GLOBAL): str = "GLOBAL"; break; - case (nn::hac::elf::STB_WEAK): + case (fnd::elf::STB_WEAK): str = "WEAK"; break; - case (nn::hac::elf::STB_LOOS): + case (fnd::elf::STB_LOOS): str = "LOOS"; break; - case (nn::hac::elf::STB_HIOS): + case (fnd::elf::STB_HIOS): str = "HIOS"; break; - case (nn::hac::elf::STB_LOPROC): + case (fnd::elf::STB_LOPROC): str = "LOPROC"; break; - case (nn::hac::elf::STB_HIPROC): + case (fnd::elf::STB_HIPROC): str = "HIPROC"; break; default: diff --git a/programs/nstool/source/RoMetadataProcess.h b/programs/nstool/source/RoMetadataProcess.h index 84ff4af..e1dbff2 100644 --- a/programs/nstool/source/RoMetadataProcess.h +++ b/programs/nstool/source/RoMetadataProcess.h @@ -62,7 +62,7 @@ private: void importApiList(); void displayRoMetaData(); - const char* getSectionIndexStr(nn::hac::elf::SpecialSectionIndex shn_index) const; - const char* getSymbolTypeStr(nn::hac::elf::SymbolType symbol_type) const; - const char* getSymbolBindingStr(nn::hac::elf::SymbolBinding symbol_binding) const; + const char* getSectionIndexStr(uint16_t shn_index) const; + const char* getSymbolTypeStr(byte_t symbol_type) const; + const char* getSymbolBindingStr(byte_t symbol_binding) const; }; \ No newline at end of file diff --git a/programs/nstool/source/version.h b/programs/nstool/source/version.h index 90f7950..88311a6 100644 --- a/programs/nstool/source/version.h +++ b/programs/nstool/source/version.h @@ -1,5 +1,5 @@ #pragma once #define VER_MAJOR 1 #define VER_MINOR 0 -#define VER_PATCH 2 +#define VER_PATCH 3 #define AUTHORS "jakcron" \ No newline at end of file