OpenCores
URL https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [libdbg64g/] [services/] [elfloader/] [elf_types.h] - Rev 4

Compare with Previous | Blame | View Log

/**
 * @file
 * @copyright  Copyright 2016 GNSS Sensor Ltd. All right reserved.
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
 * @brief      elf-file loader class declaration.
 */
 
#ifndef __DEBUGGER_ELF_TYPES_H__
#define __DEBUGGER_ELF_TYPES_H__
 
#include <inttypes.h>
 
namespace debugger {
 
//#define EI_NIDENT 16
#define ARCH_64BITS
 
#ifdef ARCH_64BITS
typedef uint64_t   ElfAddr64;
typedef uint64_t   ElfOff64;
#else
typedef unsigned int   Elf32_Addr;
typedef unsigned int   Elf32_Off;
#endif
typedef unsigned short ElfHalf;
typedef signed   int   ElfSword;
typedef unsigned int   ElfWord;
typedef uint64_t       ElfDWord;
 
typedef unsigned int   ElfAddr32;
typedef unsigned int   ElfOff32;
 
static const char MAGIC_BYTES[]  = {0x7f,'E','L','F',0};
 
enum E_EI {
    EI_MAG0,
    EI_MAG1,
    EI_MAG2,
    EI_MAG3,
    EI_CLASS,
    EI_DATA,
    EI_VERSION,
    EI_PAD,
    EI_NIDENT=16
};
static const uint8_t ELFCLASSNONE = 0;
static const uint8_t ELFCLASS32   = 1;
static const uint8_t ELFCLASS64   = 2;
 
static const uint8_t ELFDATANONE  = 0;
static const uint8_t ELFDATA2LSB  = 1;
static const uint8_t ELFDATA2MSB  = 2;
 
static const uint8_t EV_NONE      = 0;          // Invalid version
static const uint8_t EV_CURRENT   = 1;          // Current version
//etype values:
static const ElfHalf ET_NONE      = 0;       // no file type
static const ElfHalf ET_REL       = 1;       // rellocatable file
static const ElfHalf ET_EXEC      = 2;       // executable file
static const ElfHalf ET_DYN       = 3;       // shared object file
static const ElfHalf ET_CORE      = 4;       // core file
static const ElfHalf ET_LOPROC    = 0xff00;  // Processor-specific
static const ElfHalf ET_HIPROC    = 0xffff;  // Processor-specific
//emachine values:
static const ElfHalf EM_NONE      = 0;       // No machine
static const ElfHalf EM_M32       = 1;       // AT&T WE 32100
static const ElfHalf EM_SPARC     = 2;       // SPARC
static const ElfHalf EM_386       = 3;       // Intel 386
static const ElfHalf EM_68K       = 4;       // Motorola 68000
static const ElfHalf EM_88K       = 5;       // Motorola 88000
static const ElfHalf EM_860       = 7;       // Intel 80860
static const ElfHalf EM_MIPS      = 8;       // MIPS RS3000
 
struct Elf32_Ehdr {
    unsigned char e_ident[EI_NIDENT];
    ElfHalf e_type;      // Shared/Executable/Rellocalable etc
    ElfHalf e_machine;   // SPARC, X86 etc
    ElfWord e_version;   //
    ElfAddr32 e_entry;     // entry point
    ElfOff32  e_phoff;     // Program header offset
    ElfOff32  e_shoff;     // Section Header offset
    ElfWord e_flags;
    ElfHalf e_ehsize;
    ElfHalf e_phentsize; // size of one entry in the Program header. All entries are the same size
    ElfHalf e_phnum;     // number of entries in a Program header
    ElfHalf e_shentsize; // entry size in the section header table. all entries are the same size
    ElfHalf e_shnum;     // number of section header entries
    ElfHalf e_shstrndx;
};
 
struct Elf64_Ehdr {
    unsigned char e_ident[EI_NIDENT];
    ElfHalf e_type;      // Shared/Executable/Rellocalable etc
    ElfHalf e_machine;   // SPARC, X86 etc
    ElfWord e_version;   //
    ElfAddr64 e_entry;     // entry point
    ElfOff64  e_phoff;     // Program header offset
    ElfOff64  e_shoff;     // Section Header offset
    ElfWord e_flags;
    ElfHalf e_ehsize;
    ElfHalf e_phentsize; // size of one entry in the Program header. All entries are the same size
    ElfHalf e_phnum;     // number of entries in a Program header
    ElfHalf e_shentsize; // entry size in the section header table. all entries are the same size
    ElfHalf e_shnum;     // number of section header entries
    ElfHalf e_shstrndx;
};
 
 
static ElfHalf SwapBytes(ElfHalf v) {
     v = ((v>>8)&0xff) | ((v&0xFF)<<8);
     return v;
}
 
static ElfWord SwapBytes(ElfWord v) {
    v = ((v >> 24) & 0xff) | ((v >> 8) & 0xff00) 
      | ((v << 8) & 0xff0000) | ((v & 0xFF) << 24);
    return v;
}
 
static ElfDWord SwapBytes(ElfDWord v) {
    v = ((v >> 56) & 0xffull) | ((v >> 48) & 0xff00ull) 
      | ((v >> 40) & 0xff0000ull) | ((v >> 32) & 0xff000000ull)
      | ((v << 8) & 0xff000000ull) | ((v << 16) & 0xff0000000000ull)
      | ((v << 24) & 0xff0000000000ull) | ((v << 32) & 0xff00000000000000ull);
    return v;
}
 
class ElfHeaderType {
 public:
    ElfHeaderType(uint8_t *img) {
        pimg_ = img;
        isElf_ = true;
        for (int i = 0; i < 4; i++) {
            if (pimg_[i] != MAGIC_BYTES[i]) {
                isElf_ = false;
            }
        }
        is32b_ = pimg_[EI_CLASS] == ELFCLASS32;
        isMsb_ = pimg_[EI_DATA] == ELFDATA2MSB;
        if (is32b_) {
            Elf32_Ehdr *h = reinterpret_cast<Elf32_Ehdr *>(pimg_);
            if (isMsb_) {
                e_shoff_ = SwapBytes(h->e_shoff);
                e_shnum_ = SwapBytes(h->e_shnum);
                e_phoff_ = SwapBytes(h->e_phoff);
            } else {
                e_shoff_ = h->e_shoff;
                e_shnum_ = h->e_shnum;
                e_phoff_ = h->e_phoff;
            }
        } else {
            Elf64_Ehdr *h = reinterpret_cast<Elf64_Ehdr *>(pimg_);
            if (isMsb_) {
                e_shoff_ = SwapBytes(h->e_shoff);
                e_shnum_ = SwapBytes(h->e_shnum);
                e_phoff_ = SwapBytes(h->e_phoff);
            } else {
                e_shoff_ = h->e_shoff;
                e_shnum_ = h->e_shnum;
                e_phoff_ = h->e_phoff;
            }
        }
    }
 
    virtual bool isElf() { return isElf_; }
    virtual bool isElf32() { return is32b_; }
    virtual bool isElfMsb() { return isMsb_; }
    virtual uint64_t get_shoff() { return e_shoff_; }
    virtual ElfHalf get_shnum() { return e_shnum_; }
    virtual uint64_t get_phoff() { return e_phoff_; }
 protected:
    uint8_t *pimg_;
    bool isElf_;
    bool is32b_;
    bool isMsb_;
    uint64_t e_shoff_;
    ElfHalf e_shnum_;
    uint64_t e_phoff_;
};
 
 
//sh_type:
static const ElfWord SHT_NULL      = 0;          // section header is inactive
static const ElfWord SHT_PROGBITS  = 1;          // section with CPU instructions
static const ElfWord SHT_SYMTAB    = 2;          // section contains symbols table (also as SHT_DYNSIM)
static const ElfWord SHT_STRTAB    = 3;          // section holds string table
static const ElfWord SHT_RELA      = 4;          // section with relocation data
static const ElfWord SHT_HASH      = 5;          // section with hash table. Must be for the dynamic lib
static const ElfWord SHT_DYNAMIC   = 6;          // section holds information for dynamic linking.
static const ElfWord SHT_NOTE      = 7;
static const ElfWord SHT_NOBITS    = 8;          // section with not initialized data
static const ElfWord SHT_REL       = 9;
static const ElfWord SHT_SHLIB     = 10;
static const ElfWord SHT_DYNSYM    = 11;         // section contains debug symbol table
static const ElfWord SHT_LOPROC    = 0x70000000;
static const ElfWord SHT_HIPROC    = 0x7fffffff;
static const ElfWord SHT_HIUSER    = 0xffffffff;
//sh_flags:
static const ElfWord SHF_WRITE     = 0x1;        // section contains data that should be writable during process execution.
static const ElfWord SHF_ALLOC     = 0x2;        // section occupies memory during process execution. 
static const ElfWord SHF_EXECINSTR = 0x4;        // section contains executable machine instructions.
static const ElfWord SHF_MASKPROC  = 0xf0000000; // processor-specific sematic
 
struct Elf32_Shdr {
    ElfWord    sh_name;//Index in a header section table (gives name of section)
    ElfWord    sh_type;
 	ElfWord	sh_flags;	/* SHF_... */
 	ElfAddr32	sh_addr;
 	ElfOff32	sh_offset;
 	ElfWord	sh_size;
    ElfWord    sh_link;
    ElfWord    sh_info;
    ElfWord   sh_addralign;
    ElfWord   sh_entsize;
};
 
struct Elf64_Shdr {
    ElfWord    sh_name;//Index in a header section table (gives name of section)
    ElfWord    sh_type;
    ElfDWord   sh_flags;
    ElfAddr64  sh_addr;
    ElfOff64   sh_offset;
    ElfDWord   sh_size;
    ElfWord    sh_link;
    ElfWord    sh_info;
    ElfDWord   sh_addralign;
    ElfDWord   sh_entsize;
};
 
class SectionHeaderType {
 public:
    SectionHeaderType(uint8_t *img, ElfHeaderType *h) {
        if (h->isElf32()) {
            Elf32_Shdr *sh = reinterpret_cast<Elf32_Shdr *>(img);
            if (h->isElfMsb()) {
                sh_name_ = SwapBytes(sh->sh_name);
                sh_type_ = SwapBytes(sh->sh_type);
                sh_flags_ = SwapBytes(sh->sh_flags);
                sh_addr_ = SwapBytes(sh->sh_addr);
                sh_offset_ = SwapBytes(sh->sh_offset);
                sh_size_ = SwapBytes(sh->sh_size);
                sh_entsize_ = SwapBytes(sh->sh_entsize);
            } else {
                sh_name_ = sh->sh_name;
                sh_type_ = sh->sh_type;
                sh_flags_ = sh->sh_flags;
                sh_addr_ = sh->sh_addr;
                sh_offset_ = sh->sh_offset;
                sh_size_ = sh->sh_size;
                sh_entsize_ = sh->sh_entsize;
            }
        } else {
            Elf64_Shdr *sh = reinterpret_cast<Elf64_Shdr *>(img);
            if (h->isElfMsb()) {
                sh_name_ = SwapBytes(sh->sh_name);
                sh_type_ = SwapBytes(sh->sh_type);
                sh_flags_ = SwapBytes(sh->sh_flags);
                sh_addr_ = SwapBytes(sh->sh_addr);
                sh_offset_ = SwapBytes(sh->sh_offset);
                sh_size_ = SwapBytes(sh->sh_size);
                sh_entsize_ = SwapBytes(sh->sh_entsize);
            } else {
                sh_name_ = sh->sh_name;
                sh_type_ = sh->sh_type;
                sh_flags_ = sh->sh_flags;
                sh_addr_ = sh->sh_addr;
                sh_offset_ = sh->sh_offset;
                sh_size_ = sh->sh_size;
                sh_entsize_ = sh->sh_entsize;
            }
        }
    }
    virtual ElfWord get_name() { return sh_name_; }
    virtual ElfWord get_type() { return sh_type_; }
    virtual uint64_t get_offset() { return sh_offset_; }
    virtual uint64_t get_size() { return sh_size_; }
    virtual uint64_t get_addr() { return sh_addr_; }
    virtual uint64_t get_flags() { return sh_flags_; }
    virtual uint64_t get_entsize() { return sh_entsize_; }
 protected:
    ElfWord sh_name_;
    ElfWord sh_type_;
    uint64_t sh_offset_;
    uint64_t sh_size_;
    uint64_t sh_addr_;
    uint64_t sh_flags_;
    uint64_t sh_entsize_;
};
 
 
#define ELF32_ST_BIND(i) ((i)>>4)
#define ELF32_ST_TYPE(i) ((i)&0xf)
#define ELF32_ST_INFO(b,t) (((b)<<4) + ((t)&0xf))
 
static const unsigned char STB_LOCAL   = 0;
static const unsigned char STB_GLOBAL  = 1;
static const unsigned char STB_WEAK    = 2;
static const unsigned char STB_LOPROC  = 13;
static const unsigned char STB_HIPROC  = 15;
 
static const unsigned char STT_NOTYPE  = 0;
static const unsigned char STT_OBJECT  = 1;
static const unsigned char STT_FUNC    = 2;
static const unsigned char STT_SECTION = 3;
static const unsigned char STT_FILE    = 4;
static const unsigned char STT_LOPROC  = 13;
static const unsigned char STT_HIPROC  = 15;
 
struct Elf32_Sym {
    ElfWord    st_name;
 	ElfAddr32	st_value;
 	ElfWord	st_size;
 	unsigned char	st_info;
 	unsigned char	st_other;
 	ElfHalf	st_shndx;
};
 
struct Elf64_Sym {
    ElfWord    st_name;
	unsigned char	st_info;
	unsigned char	st_other;
	ElfHalf	st_shndx;
	ElfAddr64	st_value;
	ElfDWord	st_size;
};
 
class SymbolTableType {
 public:
    SymbolTableType(uint8_t *img, ElfHeaderType *h) {
        if (h->isElf32()) {
            Elf32_Sym *st = reinterpret_cast<Elf32_Sym *>(img);
            if (h->isElfMsb()) {
                st_name_ = SwapBytes(st->st_name);
                st_value_ = SwapBytes(st->st_value);
                st_size_ = SwapBytes(st->st_size);
            } else {
                st_name_ = st->st_name;
                st_value_ = st->st_value;
                st_size_ = st->st_size;
            }
            st_info_ = st->st_info;
        } else {
            Elf64_Sym *st = reinterpret_cast<Elf64_Sym *>(img);
            if (h->isElfMsb()) {
                st_name_ = SwapBytes(st->st_name);
                st_value_ = SwapBytes(st->st_value);
                st_size_ = SwapBytes(st->st_size);
            } else {
                st_name_ = st->st_name;
                st_value_ = st->st_value;
                st_size_ = st->st_size;
            }
            st_info_ = st->st_info;
        }
    }
    virtual ElfWord get_name() { return st_name_; }
    virtual uint64_t get_value() { return st_value_; }
    virtual uint64_t get_size() { return st_size_; }
    virtual unsigned char get_info() { return st_info_; }
 protected:
    ElfWord    st_name_;
    unsigned char st_info_;
    uint64_t st_value_;
    uint64_t st_size_;
};
 
 
//p_type:
static const ElfWord PT_NULL     = 0;
static const ElfWord PT_LOAD     = 1;
static const ElfWord PT_DYNAMIC  = 2;
static const ElfWord PT_INTERP   = 3;
static const ElfWord PT_NOTE     = 4;
static const ElfWord PT_SHLIB    = 5;
static const ElfWord PT_PHDR     = 6;
static const ElfWord PT_LOPROC   = 0x70000000;
static const ElfWord PT_HIPROC   = 0x7fffffff;
 
typedef struct ProgramHeaderType64
{
  uint32_t    p_type;
  uint32_t    p_offset;
  uint64_t    p_vaddr;
  uint64_t    p_paddr;
#ifdef ARCH_64BITS
    ElfDWord	p_filesz;
    ElfDWord	p_memsz;
    ElfDWord	p_flags;
    ElfDWord	p_align;
#else
 	Elf32_Word	p_filesz;
 	Elf32_Word	p_memsz;
 	Elf32_Word	p_flags;
 	Elf32_Word	p_align;
#endif
} ProgramHeaderType64;
 
typedef struct ProgramHeaderType32
{
  uint32_t    p_type;
  uint32_t    p_offset;
  ElfAddr32    p_vaddr;
  ElfAddr32    p_paddr;
  ElfWord	p_filesz;
  ElfWord	p_memsz;
  ElfWord	p_flags;
  ElfWord	p_align;
} ProgramHeaderType32;
 
}  // namespace debugger
 
#endif  // __DEBUGGER_ELF_TYPES_H__
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.