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

Subversion Repositories fwrisc

[/] [fwrisc/] [trunk/] [ve/] [fwrisc/] [tests/] [ElfSymtabReader.cpp] - Rev 2

Compare with Previous | Blame | View Log

/*
 * ElfSymtabReader.cpp
 *
 * Copyright 2018 Matthew Ballance
 *
 * Licensed under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in
 * compliance with the License.  You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in
 * writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 * CONDITIONS OF ANY KIND, either express or implied.  See
 * the License for the specific language governing
 * permissions and limitations under the License.
 *
 *  Created on: Nov 17, 2018
 *      Author: ballance
 */
 
#include "ElfSymtabReader.h"
#include <stdio.h>
#include <string.h>
#include <algorithm>
 
ElfSymtabReader::ElfSymtabReader() {
	// TODO Auto-generated constructor stub
 
}
 
ElfSymtabReader::~ElfSymtabReader() {
	// TODO Auto-generated destructor stub
}
 
Elf32_Sym ElfSymtabReader::find_sym(const std::string &name) {
	Elf32_Sym ret;
	std::map<std::string, Elf32_Sym>::iterator it;
 
	memset(&ret, 0, sizeof(Elf32_Sym));
 
	if ((it=m_symtab.find(name)) != m_symtab.end()) {
		ret = it->second;
	}
 
	return ret;
}
 
bool ElfSymtabReader::find_sym(Elf32_Addr addr, std::string &name) {
	std::map<Elf32_Addr,uint32_t>::iterator it;
 
	if ((it=m_addrtab.find(addr)) != m_addrtab.end()) {
		name = m_symlist.at(it->second).second;
		return true;
	} else {
		return false;
	}
}
 
int32_t ElfSymtabReader::find_sym(Elf32_Addr addr) {
	std::map<Elf32_Addr,uint32_t>::iterator it;
 
	if ((it=m_addrtab.find(addr)) != m_addrtab.end()) {
		return it->second;
	} else {
		return -1;
	}
}
 
const Elf32_Sym &ElfSymtabReader::get_sym(int32_t idx) {
	return m_symlist.at(idx).first;
}
 
const std::string &ElfSymtabReader::get_sym_name(int32_t idx) {
	return m_symlist.at(idx).second;
}
 
 
struct comp_syms {
	inline bool operator () (
			const std::pair<Elf32_Sym, std::string> &v1,
			const std::pair<Elf32_Sym, std::string> &v2) {
		return (v1.first.st_value < v2.first.st_value);
	}
};
 
 
void ElfSymtabReader::visit_shdr(const Elf32_Shdr &shdr) {
	if (shdr.sh_type == SHT_SYMTAB) {
		Elf32_Shdr str_shdr;
		std::vector<std::pair<Elf32_Sym, std::string>> syms;
 
		read(hdr().e_shoff+hdr().e_shentsize*shdr.sh_link,
				&str_shdr, sizeof(Elf32_Shdr));
 
		fprintf(stdout, "String table: %d\n", str_shdr.sh_size);
		char *str_tmp = new char[str_shdr.sh_size];
		read(str_shdr.sh_offset, str_tmp, str_shdr.sh_size);
 
		for (uint32_t i=0; i<shdr.sh_size; i+=sizeof(Elf32_Sym)) {
			Elf32_Sym sym;
 
			read(shdr.sh_offset+i, &sym, sizeof(Elf32_Sym));
 
			syms.push_back(std::pair<Elf32_Sym,std::string>(
					sym, &str_tmp[sym.st_name]));
		}
		delete [] str_tmp;
 
		// Now, sort the symbols list
		std::sort(syms.begin(), syms.end(), comp_syms());
 
		for (std::vector<std::pair<Elf32_Sym,std::string>>::const_iterator it=syms.begin();
				it!=syms.end(); it++) {
			m_symlist.push_back(*it);
			m_symtab[it->second] = it->first;
			m_addrtab[it->first.st_value] = m_symlist.size()-1; // index of the symbol
		}
	}
}
 
 
 

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.