/* * Copyright 2009-2010, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ #ifndef ELF_FILE_H #define ELF_FILE_H #include #include #include #include #include #include #include "Types.h" class ElfSymbolLookup; class ElfSymbolLookupSource; class ElfSection { public: ElfSection(const char* name, uint32 type, int fd, uint64 offset, uint64 size, target_addr_t loadAddress, uint32 flags, uint32 linkIndex); ~ElfSection(); const char* Name() const { return fName; } uint32 Type() const { return fType; } uint64 Offset() const { return fOffset; } uint64 Size() const { return fSize; } const void* Data() const { return fData; } target_addr_t LoadAddress() const { return fLoadAddress; } bool IsWritable() const { return (fFlags & SHF_WRITE) != 0; } status_t Load(); void Unload(); bool IsLoaded() const { return fLoadCount > 0; } uint32 LinkIndex() const { return fLinkIndex; } private: const char* fName; uint32 fType; int fFD; uint64 fOffset; uint64 fSize; void* fData; target_addr_t fLoadAddress; uint32 fFlags; int32 fLoadCount; uint32 fLinkIndex; }; class ElfSegment { public: ElfSegment(uint32 type, uint64 fileOffset, uint64 fileSize, target_addr_t loadAddress, target_size_t loadSize, uint32 flags); ~ElfSegment(); uint32 Type() { return fType; } uint64 FileOffset() const { return fFileOffset; } uint64 FileSize() const { return fFileSize; } target_addr_t LoadAddress() const { return fLoadAddress; } target_size_t LoadSize() const { return fLoadSize; } uint32 Flags() const { return fFlags; } bool IsWritable() const { return (fFlags & PF_WRITE) != 0; } private: uint64 fFileOffset; uint64 fFileSize; target_addr_t fLoadAddress; target_size_t fLoadSize; uint32 fType; uint32 fFlags; }; struct ElfClass32 { typedef uint32 Address; typedef uint32 Size; typedef Elf32_Ehdr Ehdr; typedef Elf32_Phdr Phdr; typedef Elf32_Shdr Shdr; typedef Elf32_Sym Sym; typedef Elf32_Nhdr Nhdr; typedef Elf32_Note_Team NoteTeam; typedef Elf32_Note_Area_Entry NoteAreaEntry; typedef Elf32_Note_Image_Entry NoteImageEntry; typedef Elf32_Note_Thread_Entry NoteThreadEntry; }; struct ElfClass64 { typedef uint64 Address; typedef uint64 Size; typedef Elf64_Ehdr Ehdr; typedef Elf64_Phdr Phdr; typedef Elf64_Shdr Shdr; typedef Elf64_Sym Sym; typedef Elf64_Nhdr Nhdr; typedef Elf64_Note_Team NoteTeam; typedef Elf64_Note_Area_Entry NoteAreaEntry; typedef Elf64_Note_Image_Entry NoteImageEntry; typedef Elf64_Note_Thread_Entry NoteThreadEntry; }; class ElfFile { public: ElfFile(); ~ElfFile(); status_t Init(const char* fileName); int FD() const { return fFD; } bool Is64Bit() const { return f64Bit; } bool IsByteOrderSwapped() const { return fSwappedByteOrder; } uint16 Type() const { return fType; } uint16 Machine() const { return fMachine; } int32 CountSection() const { return fSections.CountItems(); } ElfSection* SectionAt(int32 index) const { return fSections.ItemAt(index); } ElfSection* GetSection(const char* name); void PutSection(ElfSection* section); ElfSection* FindSection(const char* name) const; ElfSection* FindSection(uint32 type) const; int32 CountSegments() const { return fSegments.CountItems(); } ElfSegment* SegmentAt(int32 index) const { return fSegments.ItemAt(index); } ElfSegment* TextSegment() const; ElfSegment* DataSegment() const; ElfSymbolLookupSource* CreateSymbolLookupSource(uint64 fileOffset, uint64 fileLength, uint64 memoryAddress) const; status_t CreateSymbolLookup(uint64 textDelta, ElfSymbolLookup*& _lookup) const; template Value Get(const Value& value) const { return StaticGet(value, fSwappedByteOrder); } template static Value StaticGet(const Value& value, bool swappedByteOrder); private: struct SymbolLookupSource; typedef BObjectList SectionList; typedef BObjectList SegmentList; private: template status_t _LoadFile(const char* fileName); bool _FindSymbolSections(ElfSection*& _symbolSection, ElfSection*& _stringSection, uint32 type) const; bool _CheckRange(uint64 offset, uint64 size) const; template bool _CheckElfHeader( typename ElfClass::Ehdr& elfHeader); static uint8 _Swap(const uint8& value) { return value; } static uint16 _Swap(const uint16& value) { return (uint16)B_SWAP_INT16(value); } static int32 _Swap(const int32& value) { return B_SWAP_INT32(value); } static uint32 _Swap(const uint32& value) { return (uint32)B_SWAP_INT32(value); } static int64 _Swap(const int64& value) { return B_SWAP_INT64(value); } static uint64 _Swap(const uint64& value) { return (uint64)B_SWAP_INT64(value); } private: uint64 fFileSize; int fFD; uint16 fType; uint16 fMachine; bool f64Bit; bool fSwappedByteOrder; SectionList fSections; SegmentList fSegments; }; template /*static*/ inline Value ElfFile::StaticGet(const Value& value, bool swappedByteOrder) { if (!swappedByteOrder) return value; return _Swap(value); } #endif // ELF_FILE_H