Fixed problem in DeviceSettings::strParam, returned wrong string
[avr-sim.git] / src / BfdProgram.cpp
blob340fe083f259b8667b5f093cf242d2e12a26da8c
1 /*
2 * avr-sim: An atmel AVR simulator
3 * Copyright (C) 2008 Tom Haber
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "config.h"
21 #ifdef HAVE_LIBBFD
22 #include "BfdProgram.h"
23 #include <bfd.h>
24 #include <iostream>
25 #include <cstdlib>
26 #include "Format.h"
27 #include "RuntimeException.h"
29 namespace avr {
31 void BfdProgram::load(const char *filename) {
32 if( abfd != 0 )
33 bfd_close(abfd);
35 bfd_init();
36 abfd = bfd_openr(filename, NULL);
38 if (abfd==0)
39 throw util::RuntimeException( util::format("Could not open file: %s") % filename );
41 bfd_check_format(abfd, bfd_object);
42 sec = abfd->sections;
44 loadSymbols();
47 BfdProgram::~BfdProgram() {
48 if( abfd != 0 )
49 bfd_close(abfd);
52 void BfdProgram::loadSymbols() {
53 //reading out the symbols
54 int storage_needed = bfd_get_symtab_upper_bound(abfd);
55 if( storage_needed < 0 )
56 throw util::RuntimeException( "Failed to read symbols from bfd" );
58 if( storage_needed == 0 )
59 return;
61 asymbol **symTable = (asymbol **)malloc(storage_needed);
63 int numSymbols = bfd_canonicalize_symtab(abfd, symTable);
64 if( numSymbols < 0)
65 throw util::RuntimeException( "Failed to read symbols from bfd" );
67 for(int i = 0; i < numSymbols; ++i) {
68 // if no section data, skip
69 if( symTable[i]->section == 0 )
70 continue;
72 // Skip local symbols
73 if( (symTable[i]->flags & BSF_LOCAL) != 0 )
74 continue;
76 unsigned int lma = symTable[i]->section->lma;
77 unsigned int vma = symTable[i]->section->vma;
79 if( vma < 0x7fffff ) { //range of flash space
80 addSymbolFlash( symTable[i]->value + lma, symTable[i]->name );
81 } else if( vma < 0x80ffff ) { //range of ram
82 unsigned int offset = vma - 0x800000;
83 addSymbolRam( symTable[i]->value + offset, symTable[i]->name );
84 addSymbolFlash( symTable[i]->value + lma, symTable[i]->name );
85 } else if (vma<0x81ffff) { //range of eeprom
86 unsigned int offset = vma - 0x810000;
87 addSymbolEeprom( symTable[i]->value + offset, symTable[i]->name );
88 } else {
89 //throw util::RuntimeException(
90 // util::format( "Unknown symbol address range found!: %s (%lu)")
91 // % symTable[i]->name % vma );
92 std::cerr << "Unknown symbol address range found!:"
93 << symTable[i]->name << " (" << vma << ")"
94 << std::endl;
98 free(symTable);
101 bool BfdProgram::readNextSection(Section & s) {
102 if( sec == 0 )
103 return false;
105 bool found = false;
106 do {
107 //only read flash bytes and data
108 if( ((sec->flags&SEC_LOAD) != 0) && (sec->vma < 0x80ffff) ) {
109 int size = sec->size;
110 s.init( Section::FLASH, sec->lma, size );
111 bfd_get_section_contents(abfd, sec, s.data(), 0, size);
112 found = true;
113 } else if( ((sec->flags&SEC_LOAD) != 0) && (sec->vma >= 0x810000) ) {
114 int size = sec->size;
115 s.init( Section::EEPROM, sec->vma - 0x810000, size );
116 bfd_get_section_contents(abfd, sec, s.data(), 0, size);
117 found = true;
120 sec = sec->next;
121 } while( ! found && (sec != 0) );
123 return found;
127 #endif