ElfReader now supports section information.

ElfReader can now get Section start address,
end address and size by its name.
Or the according section name to any address within
a section

See ElfReader.hpp for API.

git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@2070 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
hoffmann
2013-02-07 00:51:25 +00:00
parent 7b7ae8e825
commit 609ac58c8f
4 changed files with 190 additions and 47 deletions

View File

@ -1,5 +1,4 @@
#include "ElfReader.hpp"
#include "elfinfo/elfinfo.h"
#include "sal/SALConfig.hpp"
#include <stdio.h>
#include <cstdlib>
@ -11,6 +10,20 @@ namespace fail {
const std::string ElfReader::NOTFOUND = "[ELFReader] Function not found.";
ElfReader::ElfReader() : m_log("Fail*Elfinfo", false){
// try to open elf file from environment variable
char * elfpath = getenv("FAIL_ELF_PATH");
if(elfpath == NULL){
m_log << "FAIL_ELF_PATH not set :(" << std::endl;
}else{
setup(elfpath);
}
}
ElfReader::ElfReader(const char* path) : m_log("Fail*Elfinfo", false){
setup(path);
}
void ElfReader::setup(const char* path) {
// Try to open the ELF file
FILE * fp = fopen(path, "r");
@ -46,22 +59,47 @@ void ElfReader::setup(const char* path) {
}
}
}
// Parse section information
if(read_ELF_section_header(ehdr.e_shstrndx,&sec_hdr,fp)==-1)
{
m_log << "Error: reading section string table sect_num = " << ehdr.e_shstrndx << std::endl;
}
char* buff=(char*)malloc(sec_hdr.sh_size);
if (!buff)
{
m_log << "Malloc failed to allocate buffer for shstrtab" << std::endl;
exit(0);
}
//seek to the offset in the file,
fseek(fp,(off_t)sec_hdr.sh_offset,SEEK_SET);
fread(buff,sec_hdr.sh_size,1,fp);
m_log << "Total number of sections: " << num_hdrs << std::endl;
for(i=0;i<num_hdrs;i++)
{
if(read_ELF_section_header(i,&sec_hdr,fp)==-1)
{
m_log << "Wrong Section to read\n" << std::endl;
}
else
{
process_section(&sec_hdr, buff);
}
}
if(buff)
free(buff);
fclose(fp);
}
ElfReader::ElfReader() : m_log("Fail*Elfinfo", false){
// try to open elf file from environment variable
char * elfpath = getenv("FAIL_ELF_PATH");
if(elfpath == NULL){
m_log << "FAIL_ELF_PATH not set :(" << std::endl;
}else{
setup(elfpath);
}
}
ElfReader::ElfReader(const char* path) : m_log("Fail*Elfinfo", false){
setup(path);
int ElfReader::process_section(Elf32_Shdr *sect_hdr, char* sect_name_buff){
// Add section name, start address and size to list
int idx=sect_hdr->sh_name;
m_sections_map.push_back( sect_hdr->sh_addr, sect_hdr->sh_size, sect_name_buff+idx );
return 0;
}
int ElfReader::process_symboltable(int sect_num, FILE* fp){
@ -177,6 +215,32 @@ void ElfReader::printMangled(){
}
#endif
#ifndef __puma
std::string ElfReader::getSection(guest_address_t address) {
return m_sections_map.find_name_by(address);
}
guest_address_t ElfReader::getSectionStart(const std::string& sectionname) {
SectionsMap::address_pair_t pair;
pair = m_sections_map.find_range_by(sectionname);
return pair.first;
}
guest_address_t ElfReader::getSectionEnd(const std::string& sectionname) {
SectionsMap::address_pair_t pair = m_sections_map.find_range_by(sectionname);
if ( pair.first == ADDR_INV ) {
return ADDR_INV;
}
return pair.first + pair.second;
}
size_t ElfReader::getSectionSize(const std::string& sectionname) {
SectionsMap::address_pair_t pair = m_sections_map.find_range_by(sectionname);
return pair.second;
}
#endif
} // end-of-namespace fail

View File

@ -7,11 +7,56 @@
#include <boost/bimap.hpp>
#endif
#include <ostream>
#include "sal/SALConfig.hpp" // for ADDR_INV
#include "Logger.hpp"
#include "elfinfo/elfinfo.h"
#include <vector>
#include <map>
namespace fail {
/*
* Helper struct for section information
*/
struct SectionsMap {
typedef std::pair<guest_address_t, size_t> address_pair_t;
typedef std::vector< std::pair< address_pair_t, std::string> > container ;
container section_to_name;
void push_back(guest_address_t start, size_t size, std::string name)
{
section_to_name.push_back(std::make_pair(std::make_pair(start, size), name));
}
address_pair_t find_range_by(std::string name){
for(container::iterator it = section_to_name.begin(), end = section_to_name.end(); it != end; ++it){
container::value_type pair_pair_string = *it;
typedef container::value_type::first_type section_type;
if(pair_pair_string.second == name){
return pair_pair_string.first;
}
}
return std::make_pair(ADDR_INV, 0);
}
std::string find_name_by(guest_address_t address){
for(container::iterator it = section_to_name.begin(), end = section_to_name.end(); it != end; ++it){
container::value_type pair_pair_string = *it;
typedef container::value_type::first_type section_type;
section_type section = pair_pair_string.first;
if(address >= section.first && address < section.first + section.second){
return pair_pair_string.second;
}
}
return std::string("SECTION_NOT_FOUND");
}
};
/**
* \class ElfReader
* Parses an ELF file and provides a list of symbol names
@ -48,7 +93,7 @@ namespace fail {
* @param name The address of a symbol (or around a symbol -> instruction pointer)
* @return The according address if found, else ElfReader::NOTFOUND
*/
std::string getNameByAddress(guest_address_t address) ;
std::string getNameByAddress(guest_address_t address) ;
/**
* Get the mangled symbol name associated to an address
@ -56,15 +101,15 @@ namespace fail {
* @param name The address of a symbol (or around a symbol -> instruction pointer)
* @return The according address if found, else ElfReader::NOTFOUND
*/
std::string getMangledNameByAddress(guest_address_t address) ;
std::string getMangledNameByAddress(guest_address_t address) ;
/**
* Get the demangled symbol name associated to an address
* Note the the demangled name is simplified, not showing any types!
* Note the the demangled name is simplified, not showing any types!
* @param name The address of a symbol (or around a symbol -> instruction pointer)
* @return The according address if found, else ElfReader::NOTFOUND
*/
std::string getDemangledNameByAddress(guest_address_t address) ;
std::string getDemangledNameByAddress(guest_address_t address) ;
/**
* Print the list of available mangled symbols
@ -81,12 +126,43 @@ namespace fail {
//! Default string, if symbol is not found
static const std::string NOTFOUND;
/**
* Get the name of a section
* @param address The address of the section
* @return The according section name if section was found, else SECTION_NOT_FOUND
*/
std::string getSection(guest_address_t address);
/**
* Get the start address of a section
* @param name The name of the section
* @return The according section start if section was found, else ADDR_INV
*/
guest_address_t getSectionStart(const std::string& name);
/**
* Get the end address of a section
* @param name The name of the section
* @return The according section end if section was found, else ADDR_INV
*/
guest_address_t getSectionEnd(const std::string& name);
/**
* Get the size of a section
* @param name The name of the section
* @return The according section sizh if section was found, else ADDR_INV
*/
guest_address_t getSectionSize(const std::string& name);
private:
Logger m_log;
void setup(const char*);
int process_symboltable(int sect_num, FILE* fp);
int process_section(Elf32_Shdr *sect_hdr, char* sect_name_buff);
fail::SectionsMap m_sections_map;
#ifndef __puma
typedef boost::bimap< std::string, guest_address_t > bimap_t;
typedef bimap_t::value_type entry;
@ -99,7 +175,7 @@ namespace fail {
typedef typename MapType::const_iterator const_iterator;
for( const_iterator iter = m.begin(), iend = m.end(); iter != iend; ++iter )
{
m_log << std::hex << iter->first << " - "<< std::hex << iter->second << std::endl;
m_log << std::hex << iter->first << " \t "<< std::hex << iter->second << std::endl;
}
}

View File

@ -1,8 +1,8 @@
/* DISCLAIMER :This is a FREE SOFTWARE You can Use it at your own RISK
that is if you are screwed by using this software, then
that is if you are screwed by using this software, then
accept the fact that you screwed yourself.
## THIS HAS BEEN DEVELOPED AND TESTED UNDER FEDORA-9 HOPEFULLY IT WILL
## WORK ON OTHER SYSTEMS
## THIS HAS BEEN DEVELOPED AND TESTED UNDER FEDORA-9 HOPEFULLY IT WILL
## WORK ON OTHER SYSTEMS
======================================================================
elfinfo.c - Copyright (C)2008 Ashok Shankar Das ashok.s.das@gmail.com
@ -28,10 +28,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include <string.h>
#include <elf.h>
void read_ELF_file_header(FILE* fp,Elf32_Ehdr *filehdr)
{
//rewind(fp);
//rewind(fp);
fread(filehdr,sizeof(Elf32_Ehdr),1,fp);
}
@ -50,7 +50,7 @@ int read_ELF_section_header(int sect_num,Elf32_Shdr *sect_hdr,FILE *fp)
Elf32_Ehdr elfhdr;
off_t sect_hdr_off;
fseek(fp,(off_t)0,SEEK_SET);
read_ELF_file_header(fp,&elfhdr);
read_ELF_file_header(fp,&elfhdr);
numsect=elfhdr.e_shnum;
if ((numsect<sect_num)||(sect_num<0))
return -1;
@ -59,20 +59,21 @@ int read_ELF_section_header(int sect_num,Elf32_Shdr *sect_hdr,FILE *fp)
sect_hdr_off+=elfhdr.e_shentsize*sect_num;
fseek(fp,(off_t)sect_hdr_off,SEEK_SET);
fread(sect_hdr,sizeof(Elf32_Shdr),1,fp);
return 1;
return 1;
}
void process_sect_hdr(Elf32_Shdr *sect_hdr,char *sect_name_buff)
{
int idx;
idx=sect_hdr->sh_name;
printf(" %-20s ",sect_name_buff+idx);
printf(" %-20s (0x%x++0x%x) ",sect_name_buff+idx, sect_hdr->sh_addr, sect_hdr->sh_size);
if(sect_hdr->sh_entsize)
printf(" %c ",'*');
else
printf(" %c ",' ');
switch(sect_hdr->sh_type)
{
{
case 0: printf("NULL \t");
break;
case 1: printf("PROGBITS \t");
@ -120,7 +121,7 @@ void process_sect_hdr(Elf32_Shdr *sect_hdr,char *sect_name_buff)
case 0x6ffffff8: printf("CKSUM \t");
break;
case 0x6ffffffa: printf("SUN SPECIFIC \t");
break;
break;
case 0x6ffffffb: printf("SUNCOMDAT \t");
break;
case 0x6ffffffc: printf("SUNSYMINFO \t");
@ -148,7 +149,7 @@ void display_sections(FILE *fp)
Elf32_Ehdr ehdr;
Elf32_Shdr sec_hdr;
int num_hdrs,i;
char *buff=NULL;
char *buff=NULL;
fseek(fp,(off_t)0,SEEK_SET);
read_ELF_file_header(fp, &ehdr);
if(is_ELF(&ehdr)==-1)
@ -173,7 +174,7 @@ void display_sections(FILE *fp)
//seek to the offset in the file,
fseek(fp,(off_t)sec_hdr.sh_offset,SEEK_SET);
fread(buff,sec_hdr.sh_size,1,fp);
printf("There are [%d] sections\n",num_hdrs);
printf("There are [%d] sections\n",num_hdrs);
for(i=0;i<num_hdrs;i++)
{
if(read_ELF_section_header(i,&sec_hdr,fp)==-1)
@ -184,7 +185,7 @@ void display_sections(FILE *fp)
{
printf("[section %3d] ",i);
process_sect_hdr(&sec_hdr,buff);
}
}
if(buff)
@ -193,7 +194,7 @@ void display_sections(FILE *fp)
int process_symtab(int sect_num,FILE *fp)
{
Elf32_Shdr sect_hdr;
Elf32_Shdr sect_hdr;
Elf32_Sym mysym;
char *name_buf=NULL;
int num_sym,link,i,idx;
@ -207,32 +208,32 @@ int process_symtab(int sect_num,FILE *fp)
link=sect_hdr.sh_link;
sym_data_offset=sect_hdr.sh_offset;
sym_data_size=sect_hdr.sh_size;
num_sym=sym_data_size/sizeof(Elf32_Sym);
num_sym=sym_data_size/sizeof(Elf32_Sym);
//read the coresponding strtab
if(read_ELF_section_header(link,&sect_hdr,fp)==-1)
{
return -1;
}
//get the size of strtab in file and allocate a buffer
//get the size of strtab in file and allocate a buffer
name_buf=(char*)malloc(sect_hdr.sh_size);
if(!name_buf)
return -1;
//get the offset of strtab in file and seek to it
fseek(fp,sect_hdr.sh_offset,SEEK_SET);
//read all data from the section to the buffer.
fread(name_buf,sect_hdr.sh_size,1,fp);
fread(name_buf,sect_hdr.sh_size,1,fp);
//so we have the namebuf now seek to symtab data
fseek(fp,sym_data_offset,SEEK_SET);
printf("[%d] symbols\n",num_sym);
for(i=0;i<num_sym;i++)
{
//memcpy((char *)&mysym,(char *)sym_buf,sizeof(Elf32_Sym));
fread(&mysym,sizeof(Elf32_Sym),1,fp);
//dump_sym(&mysym);
idx=mysym.st_name;
//printf("symbol %d index in strtab %d\n",i,idx);
//printf("symbol %d index in strtab %d\n",i,idx);
printf("[%3d] %s ",i,name_buf+idx);
switch(ELF32_ST_BIND(mysym.st_info))
{
@ -253,8 +254,8 @@ int process_symtab(int sect_num,FILE *fp)
case 15: printf("CPU-specific-end ");
break;
}
switch(ELF32_ST_TYPE(mysym.st_info))
{
case 0: printf(" NOTYPE ");
@ -302,14 +303,14 @@ int process_symtab(int sect_num,FILE *fp)
break;
case SHN_XINDEX: printf(" XINDEX ");
break;
}
}
printf("\n");
}
if(name_buf)
free(name_buf);
return 0;
}
@ -329,15 +330,16 @@ void dump_symbols(FILE *fp)
}
else
{
if((sec_hdr.sh_type==SHT_SYMTAB)||(sec_hdr.sh_type==SHT_DYNSYM))
if((sec_hdr.sh_type==SHT_SYMTAB)||(sec_hdr.sh_type==SHT_DYNSYM))
{
printf("\n[section %3d] contains ",i);
process_symtab(i,fp);
}
else
continue;
continue;
}
}
}

View File

@ -17,5 +17,6 @@
void read_ELF_file_header(FILE* fp,Elf32_Ehdr *filehdr);
int read_ELF_section_header(int sect_num,Elf32_Shdr *sect_hdr,FILE *fp);
void display_sections(FILE *fp);
#endif // ELFINFO_H