60 if (buf[0]==0x00 && buf[1]==0x8b && buf[2]==0x01 && buf[3]==0x07) {
64 if (buf[0]==0x00 && buf[1]==0x87 && buf[2]==0x01 && buf[3]==0x08) {
67 return "a.out_M68K_vaddr0";
75 if (buf[0]==0x00 && buf[1]==0x99 && buf[2]==0x01 && buf[3]==0x0b) {
77 return "a.out_M88K_fromBeginning";
79 if (buf[0]==0x00 && buf[1]==0x8f && buf[2]==0x01 && buf[3]==0x0b) {
81 return "a.out_ARM_fromBeginning";
83 if (buf[0]==0x00 && buf[1]==0x86 && buf[2]==0x01 && buf[3]==0x0b) {
85 return "a.out_i386_fromBeginning";
87 if (buf[0]==0x01 && buf[1]==0x03 && buf[2]==0x01 && buf[3]==0x07) {
89 return "a.out_SPARC_noSizes";
91 if (buf[0]==0x00 && buf[2]==0x00 && buf[8]==0x7a && buf[9]==0x75) {
93 return "a.out_MIPS_osf1";
101 static uint32_t unencode32(uint8_t *p,
Endianness endianness)
106 res = p[3] + (p[2] << 8) + (p[1] << 16) + (p[0] << 24);
108 res = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24);
118 messages <<
"Target is not an AddressDataBus.\n";
123 if (!file.is_open()) {
124 messages <<
"Unable to read file.\n";
128 unsigned char buf[65536];
130 memset(buf, 0,
sizeof(buf));
131 file.seekg(0, std::ios_base::end);
132 uint64_t totalSize = file.tellg();
133 file.seekg(0, std::ios_base::beg);
134 file.read((
char *)buf, totalSize <
sizeof(buf)? totalSize :
sizeof(buf));
135 size_t amountRead = file.gcount();
141 messages <<
"Unknown a.out format.\n";
145 file.seekg(0, std::ios_base::beg);
150 messages <<
"Target does not have the 'bigendian' variable,"
151 " which is needed to\n"
152 "load a.out files.\n";
158 struct exec aout_header;
159 uint32_t entry, datasize, textsize;
160 int32_t symbsize = 0;
161 uint32_t vaddr, total_len;
163 if (format.substr(format.length()-5, 5) ==
"_osf1") {
164 file.read((
char *)buf, 32);
165 if (file.gcount() != 32) {
166 messages <<
"The file is too small to be an OSF1 a.out.\n";
170 vaddr = unencode32(buf + 16, endianness);
171 entry = unencode32(buf + 20, endianness);
174 file.seekg(0, std::ios_base::end);
176 textsize = (uint32_t) file.tellg() - 512;
178 file.seekg(512, std::ios_base::beg);
179 }
else if (format.substr(format.length()-8, 8) ==
"_noSizes") {
180 file.seekg(0, std::ios_base::end);
181 textsize = (uint32_t) file.tellg() - 32;
184 file.seekg(32, std::ios_base::beg);
186 file.read((
char *)&aout_header,
sizeof(aout_header));
187 if (file.gcount() !=
sizeof(aout_header)) {
188 messages <<
"The file is too small to be an a.out.\n";
192 entry = unencode32((
unsigned char*)&aout_header.
a_entry, endianness);
196 if (format.substr(format.length()-7, 7) ==
"_vaddr0")
199 textsize = unencode32((
unsigned char*)&aout_header.
a_text, endianness);
200 datasize = unencode32((
unsigned char*)&aout_header.
a_data, endianness);
201 symbsize = unencode32((
unsigned char*)&aout_header.
a_syms, endianness);
204 if (format.substr(format.length()-14, 14) ==
"_fromBeginning") {
205 file.seekg(0, std::ios_base::beg);
209 messages.flags(std::ios::hex);
210 messages <<
"a.out: entry point 0x";
211 messages << setw(8) << setfill(
'0') << (uint32_t) entry <<
"\n";
213 messages.flags(std::ios::dec);
214 messages <<
"text + data = " << textsize <<
" + " << datasize <<
" bytes\n";
217 total_len = textsize + datasize;
218 while (total_len != 0) {
219 int len = total_len >
sizeof(buf) ?
sizeof(buf) : total_len;
220 file.read((
char *)buf, len);
226 for (
int k=0; k<len; ++k) {
229 messages.flags(std::ios::hex);
230 messages <<
"Failed to write data to virtual "
231 "address 0x" << vaddr <<
"\n";
241 if (total_len != 0) {
242 messages <<
"Failed to read the entire file.\n";
249 symbolRegistry = &
cpu->GetSymbolRegistry();
252 if (symbolRegistry != NULL && symbsize > 0) {
253 messages.flags(std::ios::dec);
254 messages <<
"symbols: " << symbsize <<
" bytes at 0x";
255 messages.flags(std::ios::hex);
256 messages << file.tellg() <<
"\n";
258 vector<char> symbolData;
259 symbolData.resize(symbsize);
260 file.read(&symbolData[0], symbsize);
261 if (file.gcount() != symbsize) {
262 messages <<
"Failed to read all symbols.\n";
266 off_t oldpos = file.tellg();
267 file.seekg(0, std::ios_base::end);
268 size_t strings_len = (off_t)file.tellg() - oldpos;
269 file.seekg(oldpos, std::ios_base::beg);
271 messages.flags(std::ios::dec);
272 messages <<
"strings: " << strings_len <<
" bytes at 0x";
273 messages.flags(std::ios::hex);
274 messages << file.tellg() <<
"\n";
276 vector<char> symbolStrings;
278 symbolStrings.resize(strings_len + 1);
279 file.read(&symbolStrings[0], strings_len);
280 if ((
size_t)file.gcount() != strings_len) {
281 messages <<
"Failed to read all strings.\n";
290 int n_symbols = symbsize /
sizeof(
struct aout_symbol);
291 for (
int i = 0; i < n_symbols; i++) {
292 uint32_t index = unencode32((
unsigned char*)&aout_symbol_ptr[i].
strindex, endianness);
293 uint32_t
type = unencode32((
unsigned char*)&aout_symbol_ptr[i].
type, endianness);
294 uint32_t
addr = unencode32((
unsigned char*)&aout_symbol_ptr[i].
addr, endianness);
299 if (!(
type & 0x01000000))
305 if ((
type & 0x1f000000) == 0x1f000000)
308 if (index >= (uint32_t)strings_len) {
309 messages <<
"symbol " << i <<
" has invalid string index\n";
313 string symbol = ((
char*) &symbolStrings[0]) + index;
325 messages.flags(std::ios::dec);
326 messages << nsymbols <<
" symbols read\n";
331 ss << (int64_t)(int32_t)entry;
345 static void Test_FileLoader_aout_Constructor()
352 UNITTEST(Test_FileLoader_aout_Constructor);