1 // Copyright (c) 2012- PPSSPP Project. 2 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU General Public License as published by 5 // the Free Software Foundation, version 2.0 or later versions. 6 7 // This program is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 // GNU General Public License 2.0 for more details. 11 12 // A copy of the GPL 2.0 should have been included with the program. 13 // If not, see http://www.gnu.org/licenses/ 14 15 // Official git repository and contact information can be found at 16 // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. 17 18 #pragma once 19 20 #include <vector> 21 #include "Common/CommonTypes.h" 22 #include "Core/ELF/ElfTypes.h" 23 24 enum { 25 R_MIPS_NONE, 26 R_MIPS_16, 27 R_MIPS_32, 28 R_MIPS_REL32, 29 R_MIPS_26, 30 R_MIPS_HI16, 31 R_MIPS_LO16, 32 R_MIPS_GPREL16, 33 R_MIPS_LITERAL, 34 R_MIPS_GOT16, 35 R_MIPS_PC16, 36 R_MIPS_CALL16, 37 R_MIPS_GPREL32 38 }; 39 40 enum KnownElfTypes { 41 KNOWNELF_PSP = 0, 42 KNOWNELF_DS = 1, 43 KNOWNELF_GBA = 2, 44 }; 45 46 typedef int SectionID; 47 48 class ElfReader { 49 public: ElfReader(const void * ptr,size_t size)50 ElfReader(const void *ptr, size_t size) { 51 base = (const char*)ptr; 52 base32 = (const u32 *)ptr; 53 header = (const Elf32_Ehdr*)ptr; 54 segments = (const Elf32_Phdr *)(base + header->e_phoff); 55 sections = (const Elf32_Shdr *)(base + header->e_shoff); 56 size_ = size; 57 } 58 ~ElfReader()59 ~ElfReader() { 60 delete[] sectionOffsets; 61 delete[] sectionAddrs; 62 } 63 Read32(int off)64 u32 Read32(int off) const { 65 return base32[off >> 2]; 66 } 67 68 // Quick accessors GetType()69 ElfType GetType() const { return (ElfType)(u16)(header->e_type); } GetMachine()70 ElfMachine GetMachine() const { return (ElfMachine)(u16)(header->e_machine); } GetEntryPoint()71 u32 GetEntryPoint() const { return entryPoint; } GetFlags()72 u32 GetFlags() const { return (u32)(header->e_flags); } 73 GetNumSegments()74 int GetNumSegments() const { return (int)(header->e_phnum); } GetNumSections()75 int GetNumSections() const { return (int)(header->e_shnum); } 76 const char *GetSectionName(int section) const; GetPtr(u32 offset)77 const u8 *GetPtr(u32 offset) const { 78 return (const u8*)base + offset; 79 } GetSectionDataPtr(int section)80 const u8 *GetSectionDataPtr(int section) const { 81 if (section < 0 || section >= header->e_shnum) 82 return nullptr; 83 if (sections[section].sh_type != SHT_NOBITS) 84 return GetPtr(sections[section].sh_offset); 85 else 86 return nullptr; 87 } GetSegmentPtr(int segment)88 const u8 *GetSegmentPtr(int segment) const { 89 return GetPtr(segments[segment].p_offset); 90 } GetSectionAddr(SectionID section)91 u32 GetSectionAddr(SectionID section) const { 92 return sectionAddrs[section]; 93 } GetSectionSize(SectionID section)94 int GetSectionSize(SectionID section) const { 95 return sections[section].sh_size; 96 } 97 98 //-1 for not found 99 SectionID GetSectionByName(const char *name, int firstSection = 0) const; 100 GetSegmentPaddr(int segment)101 u32 GetSegmentPaddr(int segment) const { 102 return segments[segment].p_paddr; 103 } GetSegmentOffset(int segment)104 u32 GetSegmentOffset(int segment) const { 105 return segments[segment].p_offset; 106 } GetSegmentVaddr(int segment)107 u32 GetSegmentVaddr(int segment) const { 108 return segmentVAddr[segment]; 109 } GetSegmentDataSize(int segment)110 u32 GetSegmentDataSize(int segment) const { 111 return segments[segment].p_filesz; 112 } GetSegmentMemSize(int segment)113 u32 GetSegmentMemSize(int segment) const { 114 return segments[segment].p_memsz; 115 } 116 GetFirstSegmentAlign()117 u32 GetFirstSegmentAlign() const { 118 return firstSegAlign; 119 } 120 DidRelocate()121 bool DidRelocate() const { 122 return bRelocate; 123 } 124 GetVaddr()125 u32 GetVaddr() const { 126 return vaddr; 127 } 128 GetTotalSize()129 u32 GetTotalSize() const { 130 return totalSize; 131 } 132 133 u32 GetTotalTextSize() const; 134 u32 GetTotalTextSizeFromSeg() const; 135 u32 GetTotalDataSize() const; 136 u32 GetTotalSectionSizeByPrefix(const std::string &prefix) const; 137 138 std::vector<SectionID> GetCodeSections() const; 139 140 int LoadInto(u32 vaddr, bool fromTop); 141 bool LoadSymbols(); 142 bool LoadRelocations(const Elf32_Rel *rels, int numRelocs); 143 void LoadRelocations2(int rel_seg); 144 145 private: 146 const char *base = nullptr; 147 const u32 *base32 = nullptr; 148 const Elf32_Ehdr *header = nullptr; 149 const Elf32_Phdr *segments = nullptr; 150 const Elf32_Shdr *sections = nullptr; 151 u32 *sectionOffsets = nullptr; 152 u32 *sectionAddrs = nullptr; 153 bool bRelocate = false; 154 u32 entryPoint = 0; 155 u32 totalSize = 0; 156 u32 vaddr = 0; 157 u32 segmentVAddr[32]; 158 size_t size_ = 0; 159 u32 firstSegAlign = 0; 160 }; 161