📄 fc_binutils.cpp
字号:
/*
* TOPPERS/JSP Kernel
* Toyohashi Open Platform for Embedded Real-Time Systems/
* Just Standard Profile Kernel
*
* Copyright (C) 2000-2002 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.11 2003/07/01 10:55:30 takayuki Exp $
*/
#ifndef NO_FC_BINUTILS_CPP
#include "base/defs.h"
#include "base/filecontainer.h"
#include "base/message.h"
#include "base/component.h"
#include <stdlib.h>
#include <string.h>
#include <cassert>
#include <fstream>
#include <sstream>
#include <string>
#include <map>
#define SIZE_STRINGBUFFER 1024
#define SIZE_LOADPAGE 65536 //2傋偒悢昁恵
#define HOST_ENDIAN LITTLE //儂僗僩偑儕僩儖僄儞僨傿傾儞
//#define HOST_ENDIAN BIG //儂僗僩偑價僢僌僄儞僨傿傾儞
using namespace std;
/*
* binutils傪巊偭偨僼傽僀儖僐儞僥僫僋儔僗
*/
class filecontainer_binutils : public filecontainer, public Component
{
protected:
enum tagEndian { UNKNOWN, LITTLE, BIG } endian; //僞乕僎僢僩僄儞僨傿傾儞
map<string, unsigned long> symbol_table; //専嶕梡僴僢僔儏傕偳偒
map<unsigned long, char *> contents; //僨乕僞僐儞僥儞僣
string symbol_prefix; //僔儞儃儖僾儗僼傿僋僗
void check_defaultendian(void);
void check_defaultprefix(void);
unsigned int load_symbols_withGnuNM(const char * module);
void obtain_contents(const char * module);
virtual void parseOption(Directory &);
public:
filecontainer_binutils(void);
~filecontainer_binutils(void);
virtual bool attach_module(const char *);
virtual bool change_endian(void * target, unsigned int size);
virtual bool load_contents(void * dest, unsigned long address, unsigned int size);
virtual unsigned long get_symbol_address(const char *);
virtual const char * get_architecture(void);
} Instance_of_filecontainer_binutils;
filecontainer_binutils::filecontainer_binutils(void)
{
instance = this;
endian = HOST_ENDIAN; //儂僗僩偺僄儞僨傿傾儞偵崌傢偣傞
}
filecontainer_binutils::~filecontainer_binutils(void)
{
map<unsigned long, char *>::iterator scope;
//僨乕僞僶僢僼傽偺嶍彍
scope = contents.begin();
while(scope != contents.end())
{
delete [] scope->second;
scope->second = NULL;
++ scope;
}
contents.clear();
}
void filecontainer_binutils::parseOption(Directory & parameter)
{
string loadmodule;
string work;
/* 僿儖僾昞帵 */
if(findOption(parameter,"h","help"))
{
cout << endl << Message(
"File container (binutils) - option\n"
" -mb : Take the target byte order for big endian\n"
" -ml : Take the target byte order for little endian\n",
"僐儞僼傿僊儏儗乕僔儑儞僠僃僢僇 - 僆僾僔儑儞\n"
" -mb : 僞乕僎僢僩偼 價僢僌僄儞僨傿傾儞偱偁傞\n"
" -ml : 僞乕僎僢僩偼 儕僩儖僄儞僨傿傾儞偱偁傞\n");
return;
}
/* 僨僼僅儖僩偱價僢僌僄儞僨傿傾儞 (屻偱帺摦専弌偱忋彂偒偡傞) */
if(findOption(parameter,"mb","mb"))
{
/* 價僢僌/儕僩儖偺摨帪巜掕偼僄儔乕 */
if(findOption(parameter,"ml","ml"))
ExceptionMessage("The two conflict options appeared - \"mb\" and \"ml\"","2偮偺憡斀偡傞僆僾僔儑儞偑巜掕偝傟偰偄傑偡 - \"mb\" 偲 \"ml\"").throwException();
endian = BIG;
}
/* 僨僼僅儖僩偱儕僩儖僄儞僨傿傾儞 (屻偱帺摦専弌偱忋彂偒偡傞) */
if(findOption(parameter,"ml","ml"))
endian = LITTLE;
}
/* 僼傽僀儖傪奐偒丄僥僉僗僩僼傽僀儖偱偁傞偙偲傪妋擣偡傞 */
static bool attach_textfile(fstream & file, const char * filename)
{
streamsize i;
streamsize itemcount;
char buffer[SIZE_STRINGBUFFER];
if(file.is_open())
file.close();
//僆乕僾儞張棟
file.open(filename,ios::in);
if(!file.is_open())
ExceptionMessage("File not found \"%\"","僼傽僀儖(%)偑偁傝傑偣傫") << filename << throwException;
/* 嵟弶偺128暥帤偩偗傪庢傝弌偟偰丄僶僀僫儕偱柍偄偐偳偆偐傪妋擣偡傞 */
file.read(buffer, 128);
itemcount = file.gcount();
if(itemcount == 0)
ExceptionMessage("File \"%\" has no stream.","僼傽僀儖(%)偵偼拞恎偑偁傝傑偣傫") << filename << throwException;
for(i=0;i<itemcount;i++)
if(!isprint(buffer[i]) && !isspace(buffer[i]))
{
file.close();
return false; //僶僀僫儕偺偨傔庢傝崬傑側偐偭偨
}
file.seekg(0, ios::beg);
return true;
}
/*
* load_symbols_withGnuNM : GNU NM傪巊偭偰僔儞儃儖傪撉傒弌偡
*/
unsigned int filecontainer_binutils::load_symbols_withGnuNM(const char * filename)
{
int itemcount;
unsigned long address;
char * pos;
char * epos;
fstream content;
char buffer[SIZE_STRINGBUFFER];
if(!attach_textfile(content, filename))
{
/* 僶僀僫儕偩偭偨偲偒偵偼nm傪婲摦偡傞 */
FILE * pipe;
string cmdline;
string symfile;
/* 僾儘僌儔儉婲摦 : objcopy -F srec 僜乕僗僼傽僀儖柤 僥儞億儔儕僼傽僀儖柤 */
strcpy(buffer, "cfgXXXXXX");
mktemp(buffer);
symfile.assign(buffer);
cmdline = string(CMD_SYMBOLLISTER) + " " + filename + " > " + symfile;
pipe = popen(cmdline.c_str(), "r");
if(pipe == NULL)
ExceptionMessage("Error on External program execution \"%\"","奜晹僾儘僌儔儉婲摦偵幐攕 - \"%\"") << cmdline << throwException;
pclose(pipe);
/* 僥儞億儔儕偵揻偄偨寢壥傪僗僩儕乕儉偵庢傝崬傓 */
if(!attach_textfile(content, symfile.c_str()))
ExceptionMessage("Internal error : nm did not create the destination srec file \"%\"","撪晹僄儔乕 : nm偑僼傽僀儖\"%\"傪弌椡偟偰偄傑偣傫") << symfile << throwException;
remove(symfile.c_str()); //UNIX偱偼奐偄偨傑傑嶍彍偼傗偭偰傕偄偄 (僙僉儏儕僥傿懳嶔偲偐偱偼忢搮庤抜傜偟偄)
}
itemcount = symbol_table.size();
VerboseMessage("Symbol loading [NM] \"%\"\n","僔儞儃儖庢摼 [NM] \"%\"\n") << filename;
/* 僔儞儃儖偺庢傝崬傒 */
content.seekg(0,ios::beg);
while(!content.eof())
{
content.getline(buffer,SIZE_STRINGBUFFER);
if(buffer[0] == '\0')
break;
/* 堦暥帤栚偑僗儁乕僗 -> 枹掕媊僔儞儃儖 */
if(buffer[0] != ' ')
{
/* 傾僪儗僗偺僷乕僗 (16恑悢) */
pos = ::strtok(buffer," \n\t\r");
address = ::strtoul(pos, &epos, 16);
/* 僔儞儃儖懏惈偺僷乕僗 (晄梫) */
pos = ::strtok(NULL, " \n\t\r");
/* 僔儞儃儖柤偺僷乕僗 */
pos = ::strtok(NULL, " \n\t\r");
if(*pos != '*')
symbol_table.insert(pair<string, unsigned long>(string(pos), address));
}
}
return symbol_table.size() - itemcount;
}
/* 億僀儞僞堏摦,寘悢巜掕偮偒偺16恑暥帤->惍悢曄姺 */
static unsigned int hextodec(char * & target, unsigned int digit)
{
unsigned int result;
result = 0;
while(digit-- > 0)
{
result <<= 4;
if((*target >= '0') && (*target <= '9'))
result |= *target - '0';
else
if((*target >= 'A') && (*target <= 'F'))
result |= *target - 'A' + 10;
else
if((*target >= 'a') && (*target <= 'f'))
result |= *target - 'a' + 10;
else
break;
++ target;
}
return result;
}
/* 儌僩儘乕儔S儗僐乕僪偺夝愅 */
void filecontainer_binutils::obtain_contents(const char * filename)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -