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/>.
22 #include "BfdProgram.h"
27 #include "RuntimeException.h"
31 void BfdProgram::load(const char *filename
) {
36 abfd
= bfd_openr(filename
, NULL
);
39 throw util::RuntimeException( util::format("Could not open file: %s") % filename
);
41 bfd_check_format(abfd
, bfd_object
);
47 BfdProgram::~BfdProgram() {
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 )
61 asymbol
**symTable
= (asymbol
**)malloc(storage_needed
);
63 int numSymbols
= bfd_canonicalize_symtab(abfd
, symTable
);
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 )
73 if( (symTable
[i
]->flags
& BSF_LOCAL
) != 0 )
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
);
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
<< ")"
101 bool BfdProgram::readNextSection(Section
& s
) {
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
);
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
);
121 } while( ! found
&& (sec
!= 0) );