📄 fc_binutils.cpp
字号:
/*
* TOPPERS/JSP Kernel
* Toyohashi Open Platform for Embedded Real-Time Systems/
* Just Standard Profile Kernel
*
* Copyright (C) 2003 by Embedded and Real-Time Systems Laboratory
* Toyohashi Univ. of Technology, JAPAN
*
* 忋婰挊嶌尃幰偼丆埲壓偺 (1)乣(4) 偺忦審偐丆Free Software Foundation
* 偵傛偭偰岞昞偝傟偰偄傞 GNU General Public License 偺 Version 2 偵婰
* 弎偝傟偰偄傞忦審傪枮偨偡応崌偵尷傝丆杮僜僼僩僂僃傾乮杮僜僼僩僂僃傾
* 傪夵曄偟偨傕偺傪娷傓丏埲壓摨偠乯傪巊梡丒暋惢丒夵曄丒嵞攝晍乮埲壓丆
* 棙梡偲屇傇乯偡傞偙偲傪柍彏偱嫋戻偡傞丏
* (1) 杮僜僼僩僂僃傾傪僜乕僗僐乕僪偺宍偱棙梡偡傞応崌偵偼丆忋婰偺挊嶌
* 尃昞帵丆偙偺棙梡忦審偍傛傃壓婰偺柍曐徹婯掕偑丆偦偺傑傑偺宍偱僜乕
* 僗僐乕僪拞偵娷傑傟偰偄傞偙偲丏
* (2) 杮僜僼僩僂僃傾傪丆儔僀僽儔儕宍幃側偳丆懠偺僜僼僩僂僃傾奐敪偵巊
* 梡偱偒傞宍偱嵞攝晍偡傞応崌偵偼丆嵞攝晍偵敽偆僪僉儏儊儞僩乮棙梡
* 幰儅僯儏傾儖側偳乯偵丆忋婰偺挊嶌尃昞帵丆偙偺棙梡忦審偍傛傃壓婰
* 偺柍曐徹婯掕傪宖嵹偡傞偙偲丏
* (3) 杮僜僼僩僂僃傾傪丆婡婍偵慻傒崬傓側偳丆懠偺僜僼僩僂僃傾奐敪偵巊
* 梡偱偒側偄宍偱嵞攝晍偡傞応崌偵偼丆師偺偄偢傟偐偺忦審傪枮偨偡偙
* 偲丏
* (a) 嵞攝晍偵敽偆僪僉儏儊儞僩乮棙梡幰儅僯儏傾儖側偳乯偵丆忋婰偺挊
* 嶌尃昞帵丆偙偺棙梡忦審偍傛傃壓婰偺柍曐徹婯掕傪宖嵹偡傞偙偲丏
* (b) 嵞攝晍偺宍懺傪丆暿偵掕傔傞曽朄偵傛偭偰丆TOPPERS僾儘僕僃僋僩偵
* 曬崘偡傞偙偲丏
* (4) 杮僜僼僩僂僃傾偺棙梡偵傛傝捈愙揑傑偨偼娫愙揑偵惗偠傞偄偐側傞懝
* 奞偐傜傕丆忋婰挊嶌尃幰偍傛傃TOPPERS僾儘僕僃僋僩傪柶愑偡傞偙偲丏
*
* 杮僜僼僩僂僃傾偼丆柍曐徹偱採嫙偝傟偰偄傞傕偺偱偁傞丏忋婰挊嶌尃幰偍
* 傛傃TOPPERS僾儘僕僃僋僩偼丆杮僜僼僩僂僃傾偵娭偟偰丆偦偺揔梡壜擻惈傕
* 娷傔偰丆偄偐側傞曐徹傕峴傢側偄丏傑偨丆杮僜僼僩僂僃傾偺棙梡偵傛傝捈
* 愙揑傑偨偼娫愙揑偵惗偠偨偄偐側傞懝奞偵娭偟偰傕丆偦偺愑擟傪晧傢側偄丏
*
* @(#) $Id: fc_binutils.cpp,v 1.1 2006/04/14 02:46:04 9564907 Exp $
*/
#if defined(FILECONTAINER_BINUTILS) || defined(TESTSUITE)
#ifdef _MSC_VER
#pragma warning(disable:4786) //僨僶僢僌暥帤楍傪255暥帤偵愗傝媗傔偨
#endif
#include "base/filecontainer.h"
#include <string>
#include <map>
#include <fstream>
#include <cassert>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#define _isspace(x) isspace(x)
#define _isprint(x) isprint(x)
#define SIZE_LOADPAGE 65536 //僶僀僫儕僨乕僞傪奿擺偡傞儁乕僕扨埵
#define SIZE_TO_CONFIRM_BINARYFILE 128 //僼傽僀儖偑僶僀僫儕傪娷傓偐偳偆偐傪妋擣偡傞偺偵撉傒弌偡僨乕僞偺挿偝 (僶僢僼傽傪庢傞偺偱偁傑傝戝偒偔偟側偄偙偲)
#define MAGIC_SYMBOL "_checker_magic_number"
#define MAGIC_NUMBER 0x01234567 //4僶僀僩偺惍悢
#define CMD_GNUNM "nm"
#define CMD_GNUOBJCOPY "objcopy"
#define MAKE_BASEADDRESS(x) ((x) & ~(SIZE_LOADPAGE-1))
#define MAKE_OFFSETADDRESS(x) ((x) & (SIZE_LOADPAGE-1))
using namespace std;
namespace {
class FileContainerBinutilsImpl : public FileContainer
{
public:
typedef void (interceptor_func_t)(fstream &, const string &); //晄堄偵朘傟偨僶僀僫儕僼傽僀儖偺廝寕偵懳墳偡傞娭悢偺宆
protected:
string symbol_prefix;
map<string, address_t> symbol_table;
map<address_t, char *> contents;
address_t last_address; //僉儍僢僔儏傕偳偒
char * last_page;
//僨乕僞庢傝崬傒
void loadSymbols(fstream & file) throw(Exception);
void loadDataContents(fstream & file) throw(Exception);
//contents傊1僶僀僩彂偒崬傒
void writeByte(address_t address, unsigned int) throw(Exception);
//帺摦張棟
void searchSymbolPrefix(void) throw();
void searchByteOrder(void) throw();
public:
FileContainerBinutilsImpl(void) throw();
virtual ~FileContainerBinutilsImpl(void) throw();
/* 僀儞僞僼僃乕僗晹 */
virtual void attachModule(const string & filename) throw(Exception);
virtual void loadContents(void * dest, address_t address, size_t size) throw(Exception);
virtual address_t getSymbolAddress(const string & symbol) throw(Exception);
virtual std::string getArchitecture(void) throw();
TESTSUITE_PROTOTYPE(main)
};
namespace {
FileContainerBinutilsImpl instance_of_FileContainerBinutilsImpl;
}
/* 僐儞僗僩儔僋僞 */
FileContainerBinutilsImpl::FileContainerBinutilsImpl(void) throw()
: symbol_prefix(""), symbol_table(), contents(), last_address(0), last_page(0)
{}
/* 僨僗僩儔僋僞 : 僨乕僞僶僢僼傽偺夝曻 */
FileContainerBinutilsImpl::~FileContainerBinutilsImpl(void) throw()
{
map<address_t, char *>::iterator scope;
scope = contents.begin();
while(scope != contents.end()) {
delete [] scope->second;
++ scope;
}
symbol_table.clear();
contents.clear();
}
/* 僼傽僀儖柤傪僇儞儅偱擇偮偵暘偗傞 */
void splitFilename(const string & src, string & first, string & second) throw(Exception)
{
if(!src.empty()) {
string::size_type pos;
pos = src.find_first_of(',');
if(pos != string::npos) {
first = src.substr(0, pos);
second = src.substr(pos + 1);
}
else {
//僼傽僀儖柤偑堦偮偟偐巜掕偝傟偰偄側偄
first = src;
second = src;
}
}
else
ExceptionMessage("[FCBI] Empty filename could not be accepted.","[FCBI] 僼傽僀儖柤偑偁傝傑偣傫").throwException();
}
/* 僼傽僀儖偑僶僀僫儕僨乕僞傪帩偭偰偄傞偐偳偆偐傪敾掕 */
bool hasBinaryContents(fstream & file) throw()
{
assert(file.is_open());
bool result = false;
char buffer[SIZE_TO_CONFIRM_BINARYFILE];
streamsize length;
file.read(buffer, SIZE_TO_CONFIRM_BINARYFILE);
length = file.gcount();
for(streamsize i = 0; i < length; ++ i) {
if(buffer[i] < 0 || !(_isprint(buffer[i]) || _isspace(buffer[i]))){
result = true;
break;
}
}
if(!result) {
file.clear();
file.seekg(0, ios::beg); //愭摢偵栠偟偰偍偔
}
return result;
}
/* 僥僉僗僩僼傽僀儖傪奐偔 (僶僀僫儕偩偭偨応崌偵偼懳張) */
void openTextFile(fstream & file, const string & filename, FileContainerBinutilsImpl::interceptor_func_t * interceptor) throw(Exception)
{
assert(!filename.empty());
assert(!file.is_open());
file.open(filename.c_str(), ios::in|ios::binary);
if(!file.is_open()) {
ExceptionMessage("File '%' could not be opened.","僼傽僀儖 '%' 偼奐偗傑偣傫") << filename << throwException;
return;
}
/* 僶僀僫儕僼傽僀儖偩偭偨傜... */
while(hasBinaryContents(file)) {
file.close();
if(interceptor != 0) {
(*interceptor)(file, filename);
interceptor = 0; //懳張偼堦夞偺傒
}
if(!file.is_open()) {
break;
}
}
/* 僼傽僀儖偑奐偗側偐偭偨傜椺奜 */
if(!file.is_open())
ExceptionMessage("Program failed to convert the binary '%' into suitable style. Please specify a suitable TEXT file.",
"僾儘僌儔儉偼僶僀僫儕僼傽僀儖'%'偺曄姺偵幐攕偟傑偟偨丅惓偟偄僥僉僗僩僼傽僀儖傪巜掕偟捈偟偰偔偩偝偄丅")
<< filename << throwException;
}
/* 堦帪揑側僼傽僀儖柤偺惗惉 */
const char * makeTemporaryFilename(void) throw()
{
static char filename[10];
sprintf(filename, "cfg%06x", (int)(rand() & 0xffffffl));
return filename;
}
/* 僶僀僫儕傪GNU-NM傪巊偭偰曄姺偡傞 */
void interceptWithGnuNM(fstream & file, const string & filename) throw(Exception)
{
assert(!file.is_open());
string cmdline;
string symfile;
symfile.assign(makeTemporaryFilename());
cmdline = string(CMD_GNUNM) + " " + filename + " > " + symfile;
VerboseMessage("[EXEC] %\n") << cmdline;
system(cmdline.c_str());
/* 惓偟偔奐偗偨傜僼傽僀儖傪嶍彍 */
file.open(symfile.c_str(), ios::in);
if(file.is_open()) {
remove(symfile.c_str());
}
}
/* 僶僀僫儕傪GNU-OBJCOPY傪巊偭偰曄姺偡傞 */
void interceptWithGnuObjcopy(fstream & file, const string & filename) throw(Exception)
{
assert(!file.is_open());
string cmdline;
string srecfile;
srecfile.assign(makeTemporaryFilename());
cmdline = string(CMD_GNUOBJCOPY) + " -F srec " + filename + " " + srecfile;
VerboseMessage("[EXEC] %\n") << cmdline;
system(cmdline.c_str());
/* 惓偟偔奐偗偨傜僼傽僀儖傪嶍彍 */
file.open(srecfile.c_str(), ios::in);
if(file.is_open()) {
remove(srecfile.c_str());
}
}
/* 16恑偐傜10恑傊偺曄姺 (億僀儞僞堏摦, 挿偝巜掕晅偒) */
unsigned int hextodec(const char * & src, size_t length) throw()
{
assert(length <= sizeof(unsigned int) * 2);
unsigned int result = 0;
unsigned int digit;
while(length-- > 0) {
if(*src >= '0' && *src <= '9')
digit = *src - '0';
else if(*src >= 'A' && *src <='F')
digit = *src - 'A' + 10;
else if(*src >= 'a' && *src <='f')
digit = *src - 'a' + 10;
else
break;
++ src;
result = (result << 4) | (digit & 0xf);
}
return result;
}
/* NM偑弌椡偟偨峴傪僷乕僗 */
bool readGnuNmLine(fstream & file, FileContainer::address_t & address, string & attribute, string & symbolname) throw()
{
assert(file.is_open());
string src;
string addr;
string::size_type pos1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -