1 #include <assert.h> 2 #include <string.h> 3 #include <stdexcept> 4 #include "ELF.h" 5 #include "PtrStream.h" 6 CELF(uint8 * content)7CELF::CELF(uint8* content) 8 : m_content(content) 9 { 10 Framework::CPtrStream stream(m_content, -1); 11 12 stream.Read(&m_Header, sizeof(ELFHEADER)); 13 14 if(m_Header.nId[0] != 0x7F || m_Header.nId[1] != 'E' || m_Header.nId[2] != 'L' || m_Header.nId[3] != 'F') 15 { 16 throw std::runtime_error("This file isn't a valid ELF file."); 17 } 18 19 if(m_Header.nId[4] != 1 || m_Header.nId[5] != 1) 20 { 21 throw std::runtime_error("This ELF file format is not supported. Only 32-bits LSB ordered ELFs are supported."); 22 } 23 24 { 25 unsigned int nCount = m_Header.nProgHeaderCount; 26 m_pProgram = new ELFPROGRAMHEADER[nCount]; 27 28 stream.Seek(m_Header.nProgHeaderStart, Framework::STREAM_SEEK_SET); 29 for(unsigned int i = 0; i < nCount; i++) 30 { 31 stream.Read(&m_pProgram[i], sizeof(ELFPROGRAMHEADER)); 32 } 33 } 34 35 { 36 unsigned int nCount = m_Header.nSectHeaderCount; 37 m_pSection = new ELFSECTIONHEADER[nCount]; 38 39 stream.Seek(m_Header.nSectHeaderStart, Framework::STREAM_SEEK_SET); 40 for(unsigned int i = 0; i < nCount; i++) 41 { 42 stream.Read(&m_pSection[i], sizeof(ELFSECTIONHEADER)); 43 } 44 } 45 } 46 ~CELF()47CELF::~CELF() 48 { 49 delete[] m_pProgram; 50 delete[] m_pSection; 51 } 52 GetContent() const53uint8* CELF::GetContent() const 54 { 55 return m_content; 56 } 57 GetHeader() const58const ELFHEADER& CELF::GetHeader() const 59 { 60 return m_Header; 61 } 62 GetSection(unsigned int nIndex)63ELFSECTIONHEADER* CELF::GetSection(unsigned int nIndex) 64 { 65 if(nIndex >= m_Header.nSectHeaderCount) 66 { 67 return nullptr; 68 } 69 return &m_pSection[nIndex]; 70 } 71 GetSectionData(unsigned int nIndex)72const void* CELF::GetSectionData(unsigned int nIndex) 73 { 74 auto section = GetSection(nIndex); 75 if(section == nullptr) return nullptr; 76 return m_content + section->nOffset; 77 } 78 GetSectionName(unsigned int sectionIndex)79const char* CELF::GetSectionName(unsigned int sectionIndex) 80 { 81 auto stringTableData = reinterpret_cast<const char*>(GetSectionData(m_Header.nSectHeaderStringTableIndex)); 82 if(stringTableData == nullptr) return nullptr; 83 auto sectionHeader = GetSection(sectionIndex); 84 if(sectionHeader == nullptr) return nullptr; 85 return stringTableData + sectionHeader->nStringTableIndex; 86 } 87 FindSection(const char * requestedSectionName)88ELFSECTIONHEADER* CELF::FindSection(const char* requestedSectionName) 89 { 90 auto sectionIndex = FindSectionIndex(requestedSectionName); 91 if(sectionIndex == 0) return nullptr; 92 return GetSection(sectionIndex); 93 } 94 FindSectionIndex(const char * requestedSectionName)95unsigned int CELF::FindSectionIndex(const char* requestedSectionName) 96 { 97 auto stringTableData = reinterpret_cast<const char*>(GetSectionData(m_Header.nSectHeaderStringTableIndex)); 98 if(stringTableData == nullptr) return 0; 99 for(unsigned int i = 0; i < m_Header.nSectHeaderCount; i++) 100 { 101 auto sectionHeader = GetSection(i); 102 auto sectionName = stringTableData + sectionHeader->nStringTableIndex; 103 if(!strcmp(sectionName, requestedSectionName)) 104 { 105 return i; 106 } 107 } 108 return 0; 109 } 110 FindSectionData(const char * requestedSectionName)111const void* CELF::FindSectionData(const char* requestedSectionName) 112 { 113 auto section = FindSection(requestedSectionName); 114 if(section == nullptr) return nullptr; 115 return m_content + section->nOffset; 116 } 117 GetProgram(unsigned int nIndex)118ELFPROGRAMHEADER* CELF::GetProgram(unsigned int nIndex) 119 { 120 if(nIndex >= m_Header.nProgHeaderCount) 121 { 122 return nullptr; 123 } 124 return &m_pProgram[nIndex]; 125 } 126