1 /* 2 * Copyright 2009-2010, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef ELF_FILE_H 6 #define ELF_FILE_H 7 8 #include <sys/types.h> 9 10 #include <ByteOrder.h> 11 #include <SupportDefs.h> 12 #include <ObjectList.h> 13 14 #include <elf_private.h> 15 #include <util/DoublyLinkedList.h> 16 17 #include "Types.h" 18 19 20 class ElfSymbolLookup; 21 class ElfSymbolLookupSource; 22 23 24 class ElfSection { 25 public: 26 ElfSection(const char* name, uint32 type, 27 int fd, uint64 offset, uint64 size, 28 target_addr_t loadAddress, uint32 flags, 29 uint32 linkIndex); 30 ~ElfSection(); 31 32 const char* Name() const { return fName; } 33 uint32 Type() const { return fType; } 34 uint64 Offset() const { return fOffset; } 35 uint64 Size() const { return fSize; } 36 const void* Data() const { return fData; } 37 target_addr_t LoadAddress() const 38 { return fLoadAddress; } 39 bool IsWritable() const 40 { return (fFlags & SHF_WRITE) != 0; } 41 42 status_t Load(); 43 void Unload(); 44 bool IsLoaded() const { return fLoadCount > 0; } 45 uint32 LinkIndex() const { return fLinkIndex; } 46 47 private: 48 const char* fName; 49 uint32 fType; 50 int fFD; 51 uint64 fOffset; 52 uint64 fSize; 53 void* fData; 54 target_addr_t fLoadAddress; 55 uint32 fFlags; 56 int32 fLoadCount; 57 uint32 fLinkIndex; 58 }; 59 60 61 class ElfSegment { 62 public: 63 ElfSegment(uint32 type, uint64 fileOffset, 64 uint64 fileSize, target_addr_t loadAddress, 65 target_size_t loadSize, uint32 flags); 66 ~ElfSegment(); 67 68 uint32 Type() { return fType; } 69 uint64 FileOffset() const { return fFileOffset; } 70 uint64 FileSize() const { return fFileSize; } 71 target_addr_t LoadAddress() const { return fLoadAddress; } 72 target_size_t LoadSize() const { return fLoadSize; } 73 uint32 Flags() const { return fFlags; } 74 bool IsWritable() const 75 { return (fFlags & PF_WRITE) != 0; } 76 77 private: 78 uint64 fFileOffset; 79 uint64 fFileSize; 80 target_addr_t fLoadAddress; 81 target_size_t fLoadSize; 82 uint32 fType; 83 uint32 fFlags; 84 }; 85 86 87 struct ElfClass32 { 88 typedef uint32 Address; 89 typedef uint32 Size; 90 typedef Elf32_Ehdr Ehdr; 91 typedef Elf32_Phdr Phdr; 92 typedef Elf32_Shdr Shdr; 93 typedef Elf32_Sym Sym; 94 typedef Elf32_Nhdr Nhdr; 95 typedef Elf32_Note_Team NoteTeam; 96 typedef Elf32_Note_Area_Entry NoteAreaEntry; 97 typedef Elf32_Note_Image_Entry NoteImageEntry; 98 typedef Elf32_Note_Thread_Entry NoteThreadEntry; 99 }; 100 101 102 struct ElfClass64 { 103 typedef uint64 Address; 104 typedef uint64 Size; 105 typedef Elf64_Ehdr Ehdr; 106 typedef Elf64_Phdr Phdr; 107 typedef Elf64_Shdr Shdr; 108 typedef Elf64_Sym Sym; 109 typedef Elf64_Nhdr Nhdr; 110 typedef Elf64_Note_Team NoteTeam; 111 typedef Elf64_Note_Area_Entry NoteAreaEntry; 112 typedef Elf64_Note_Image_Entry NoteImageEntry; 113 typedef Elf64_Note_Thread_Entry NoteThreadEntry; 114 }; 115 116 117 class ElfFile { 118 public: 119 ElfFile(); 120 ~ElfFile(); 121 122 status_t Init(const char* fileName); 123 124 int FD() const { return fFD; } 125 126 bool Is64Bit() const { return f64Bit; } 127 bool IsByteOrderSwapped() const 128 { return fSwappedByteOrder; } 129 uint16 Type() const { return fType; } 130 uint16 Machine() const { return fMachine; } 131 132 int32 CountSection() const 133 { return fSections.CountItems(); } 134 ElfSection* SectionAt(int32 index) const 135 { return fSections.ItemAt(index); } 136 ElfSection* GetSection(const char* name); 137 void PutSection(ElfSection* section); 138 ElfSection* FindSection(const char* name) const; 139 ElfSection* FindSection(uint32 type) const; 140 141 int32 CountSegments() const 142 { return fSegments.CountItems(); } 143 ElfSegment* SegmentAt(int32 index) const 144 { return fSegments.ItemAt(index); } 145 146 ElfSegment* TextSegment() const; 147 ElfSegment* DataSegment() const; 148 149 ElfSymbolLookupSource* CreateSymbolLookupSource(uint64 fileOffset, 150 uint64 fileLength, 151 uint64 memoryAddress) const; 152 status_t CreateSymbolLookup(uint64 textDelta, 153 ElfSymbolLookup*& _lookup) const; 154 155 template<typename Value> 156 Value Get(const Value& value) const 157 { return StaticGet(value, 158 fSwappedByteOrder); } 159 160 template<typename Value> 161 static Value StaticGet(const Value& value, 162 bool swappedByteOrder); 163 164 private: 165 struct SymbolLookupSource; 166 167 typedef BObjectList<ElfSection> SectionList; 168 typedef BObjectList<ElfSegment> SegmentList; 169 170 private: 171 template<typename ElfClass> 172 status_t _LoadFile(const char* fileName); 173 174 bool _FindSymbolSections(ElfSection*& _symbolSection, 175 ElfSection*& _stringSection, 176 uint32 type) const; 177 178 bool _CheckRange(uint64 offset, uint64 size) const; 179 180 template<typename ElfClass> 181 bool _CheckElfHeader( 182 typename ElfClass::Ehdr& elfHeader); 183 184 static uint8 _Swap(const uint8& value) 185 { return value; } 186 static uint16 _Swap(const uint16& value) 187 { return (uint16)B_SWAP_INT16(value); } 188 static int32 _Swap(const int32& value) 189 { return B_SWAP_INT32(value); } 190 static uint32 _Swap(const uint32& value) 191 { return (uint32)B_SWAP_INT32(value); } 192 static int64 _Swap(const int64& value) 193 { return B_SWAP_INT64(value); } 194 static uint64 _Swap(const uint64& value) 195 { return (uint64)B_SWAP_INT64(value); } 196 197 private: 198 uint64 fFileSize; 199 int fFD; 200 uint16 fType; 201 uint16 fMachine; 202 bool f64Bit; 203 bool fSwappedByteOrder; 204 SectionList fSections; 205 SegmentList fSegments; 206 }; 207 208 209 template<typename Value> 210 /*static*/ inline Value 211 ElfFile::StaticGet(const Value& value, bool swappedByteOrder) 212 { 213 if (!swappedByteOrder) 214 return value; 215 return _Swap(value); 216 } 217 218 219 #endif // ELF_FILE_H 220