Bug fix: check if vm exists
[avr-sim.git] / BfdProgram.cpp
blob8c8bbf1f4e61626ff65e05b3883d779bb7cd24cb
1 #ifdef HAVE_BFD
2 #include "BfdProgram.h"
3 #include <bfd.h>
4 #include <iostream>
5 #include "Format.h"
6 #include "RuntimeException.h"
8 namespace avr {
10 void BfdProgram::load(const char *filename) {
11 if( abfd != 0 )
12 bfd_close(abfd);
14 bfd_init();
15 abfd = bfd_openr(filename, NULL);
17 if (abfd==0)
18 throw util::RuntimeException( util::format("Could not open file: %s") % filename );
20 bfd_check_format(abfd, bfd_object);
21 sec = abfd->sections;
23 loadSymbols();
26 BfdProgram::~BfdProgram() {
27 if( abfd != 0 )
28 bfd_close(abfd);
31 void BfdProgram::loadSymbols() {
32 //reading out the symbols
33 int storage_needed = bfd_get_symtab_upper_bound(abfd);
34 if( storage_needed < 0 )
35 throw util::RuntimeException( "Failed to read symbols from bfd" );
37 if( storage_needed == 0 )
38 return;
40 asymbol **symTable = (asymbol **)malloc(storage_needed);
42 int numSymbols = bfd_canonicalize_symtab(abfd, symTable);
43 if( numSymbols < 0)
44 throw util::RuntimeException( "Failed to read symbols from bfd" );
46 for(int i = 0; i < numSymbols; ++i) {
47 // if no section data, skip
48 if( symTable[i]->section == 0 )
49 continue;
51 unsigned int lma = symTable[i]->section->lma;
52 unsigned int vma = symTable[i]->section->vma;
54 if( vma < 0x7fffff ) { //range of flash space
55 addSymbolFlash( symTable[i]->value + lma, symTable[i]->name );
56 } else if( vma < 0x80ffff ) { //range of ram
57 unsigned int offset = vma - 0x800000;
58 addSymbolRam( symTable[i]->value + offset, symTable[i]->name );
59 addSymbolFlash( symTable[i]->value + lma, symTable[i]->name );
60 } else if (vma<0x81ffff) { //range of eeprom
61 unsigned int offset = vma - 0x810000;
62 addSymbolEeprom( symTable[i]->value + offset, symTable[i]->name );
63 } else {
64 //throw util::RuntimeException(
65 // util::format( "Unknown symbol address range found!: %s (%lu)")
66 // % symTable[i]->name % vma );
67 std::cerr << "Unknown symbol address range found!:"
68 << symTable[i]->name << " (" << vma << ")"
69 << std::endl;
74 bool BfdProgram::readNextSection(Section & s) const {
75 if( sec == 0 )
76 return false;
78 bool found = false;
79 do {
80 //only read flash bytes and data
81 if( ((sec->flags&SEC_LOAD) != 0) && (sec->vma < 0x80ffff) ) {
82 int size = sec->size;
83 s.init( Section::FLASH, sec->lma, size );
84 bfd_get_section_contents(abfd, sec, s.data(), 0, size);
85 found = true;
86 } else if( ((sec->flags&SEC_LOAD) != 0) && (sec->vma >= 0x810000) ) {
87 int size = sec->size;
88 s.init( Section::EEPROM, sec->vma - 0x810000, size );
89 bfd_get_section_contents(abfd, sec, s.data(), 0, size);
90 found = true;
93 sec = sec->next;
94 } while( ! found && (sec != 0) );
96 return found;
100 #endif