2009-06-14 16:53:29 +04:00
|
|
|
/*
|
2010-11-02 23:03:11 +03:00
|
|
|
* Copyright 2009-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
|
2009-06-14 16:53:29 +04:00
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*/
|
|
|
|
#ifndef ELF_FILE_H
|
|
|
|
#define ELF_FILE_H
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
|
|
#include <SupportDefs.h>
|
|
|
|
|
2015-10-26 20:43:44 +03:00
|
|
|
#include <elf_private.h>
|
2009-06-14 16:53:29 +04:00
|
|
|
#include <util/DoublyLinkedList.h>
|
|
|
|
|
2009-06-30 02:38:15 +04:00
|
|
|
#include "Types.h"
|
|
|
|
|
2009-06-14 16:53:29 +04:00
|
|
|
|
|
|
|
class ElfSection : public DoublyLinkedListLinkImpl<ElfSection> {
|
|
|
|
public:
|
|
|
|
ElfSection(const char* name, int fd,
|
2010-11-02 23:03:11 +03:00
|
|
|
off_t offset, off_t size,
|
|
|
|
target_addr_t loadAddress, uint32 flags);
|
2009-06-14 16:53:29 +04:00
|
|
|
~ElfSection();
|
|
|
|
|
|
|
|
const char* Name() const { return fName; }
|
|
|
|
off_t Offset() const { return fOffset; }
|
|
|
|
off_t Size() const { return fSize; }
|
|
|
|
const void* Data() const { return fData; }
|
2010-11-02 23:03:11 +03:00
|
|
|
target_addr_t LoadAddress() const
|
|
|
|
{ return fLoadAddress; }
|
|
|
|
bool IsWritable() const
|
|
|
|
{ return (fFlags & SHF_WRITE) != 0; }
|
2009-06-14 16:53:29 +04:00
|
|
|
|
|
|
|
status_t Load();
|
|
|
|
void Unload();
|
2010-12-13 17:05:44 +03:00
|
|
|
bool IsLoaded() const { return fLoadCount > 0; }
|
2009-06-14 16:53:29 +04:00
|
|
|
|
|
|
|
private:
|
|
|
|
const char* fName;
|
|
|
|
int fFD;
|
|
|
|
off_t fOffset;
|
|
|
|
off_t fSize;
|
|
|
|
void* fData;
|
2010-11-02 23:03:11 +03:00
|
|
|
target_addr_t fLoadAddress;
|
|
|
|
uint32 fFlags;
|
2009-06-14 16:53:29 +04:00
|
|
|
int32 fLoadCount;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2009-06-30 02:38:15 +04:00
|
|
|
class ElfSegment : public DoublyLinkedListLinkImpl<ElfSegment> {
|
|
|
|
public:
|
|
|
|
ElfSegment(off_t fileOffset, off_t fileSize,
|
|
|
|
target_addr_t loadAddress,
|
|
|
|
target_size_t loadSize, bool writable);
|
|
|
|
~ElfSegment();
|
|
|
|
|
|
|
|
off_t FileOffset() const { return fFileOffset; }
|
|
|
|
off_t FileSize() const { return fFileSize; }
|
|
|
|
target_addr_t LoadAddress() const { return fLoadAddress; }
|
|
|
|
target_size_t LoadSize() const { return fLoadSize; }
|
|
|
|
bool IsWritable() const { return fWritable; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
off_t fFileOffset;
|
|
|
|
off_t fFileSize;
|
|
|
|
target_addr_t fLoadAddress;
|
|
|
|
target_size_t fLoadSize;
|
|
|
|
bool fWritable;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2009-06-14 16:53:29 +04:00
|
|
|
class ElfFile {
|
|
|
|
public:
|
|
|
|
ElfFile();
|
|
|
|
~ElfFile();
|
|
|
|
|
|
|
|
status_t Init(const char* fileName);
|
|
|
|
|
2009-06-30 02:38:15 +04:00
|
|
|
int FD() const { return fFD; }
|
|
|
|
|
2009-06-14 16:53:29 +04:00
|
|
|
ElfSection* GetSection(const char* name);
|
|
|
|
void PutSection(ElfSection* section);
|
2010-12-13 17:05:44 +03:00
|
|
|
ElfSection* FindSection(const char* name) const;
|
2009-06-14 16:53:29 +04:00
|
|
|
|
2009-06-30 02:38:15 +04:00
|
|
|
ElfSegment* TextSegment() const;
|
|
|
|
ElfSegment* DataSegment() const;
|
|
|
|
|
2009-06-14 16:53:29 +04:00
|
|
|
private:
|
|
|
|
typedef DoublyLinkedList<ElfSection> SectionList;
|
2009-06-30 02:38:15 +04:00
|
|
|
typedef DoublyLinkedList<ElfSegment> SegmentList;
|
2009-06-14 16:53:29 +04:00
|
|
|
|
|
|
|
private:
|
2012-12-19 23:54:20 +04:00
|
|
|
template<typename Ehdr, typename Phdr, typename Shdr>
|
|
|
|
status_t _LoadFile(const char* fileName);
|
|
|
|
|
2009-06-14 16:53:29 +04:00
|
|
|
bool _CheckRange(off_t offset, off_t size) const;
|
2012-12-19 23:54:20 +04:00
|
|
|
static bool _CheckElfHeader(Elf32_Ehdr& elfHeader);
|
|
|
|
static bool _CheckElfHeader(Elf64_Ehdr& elfHeader);
|
2009-06-14 16:53:29 +04:00
|
|
|
|
|
|
|
private:
|
|
|
|
off_t fFileSize;
|
|
|
|
int fFD;
|
|
|
|
SectionList fSections;
|
2009-06-30 02:38:15 +04:00
|
|
|
SegmentList fSegments;
|
2009-06-14 16:53:29 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#endif // ELF_FILE_H
|