simulavr  1.1.0
avrreadelf.cpp
Go to the documentation of this file.
1 /*
2  ****************************************************************************
3  *
4  * simulavr - A simulator for the Atmel AVR family of microcontrollers.
5  * Copyright (C) 2001, 2002 - 2012 Klaus Rudolph & other
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  ****************************************************************************
22  *
23  * $Id$
24  */
25 
26 #include <string>
27 #include <map>
28 #include <limits>
29 
30 #include "elfio/elfio.hpp"
31 
32 #include "config.h"
33 #include "flash.h"
34 #include "hweeprom.h"
35 
36 #include "avrreadelf.h"
37 
38 void ELFLoad(const AvrDevice * core) {
39  ELFIO::elfio reader;
40 
41  if(!reader.load(core->actualFilename))
42  avr_error("File '%s' not found or isn't a elf object",
43  core->actualFilename.c_str());
44 
45  if(reader.get_machine() != EM_AVR)
46  avr_error("ELF file '%s' is not for Atmel AVR architecture (%d)",
47  core->actualFilename.c_str(),
48  reader.get_machine());
49 
50  // over all symbols ...
51  ELFIO::Elf_Half sec_num = reader.sections.size();
52 
53  for(ELFIO::Elf_Half i = 0; i < sec_num; i++) {
54  ELFIO::section* psec = reader.sections[i];
55 
56  if(psec->get_type() == SHT_SYMTAB) {
57  const ELFIO::symbol_section_accessor symbols(reader, psec);
58 
59  for(ELFIO::Elf_Xword j = 0; j < symbols.get_symbols_num(); j++) {
60  std::string name;
61  ELFIO::Elf64_Addr value = 0;
62  ELFIO::Elf_Xword size = 0;
63  unsigned char bind = 0;
64  unsigned char type = 0;
65  ELFIO::Elf_Half section_index = 0;
66  unsigned char other = 0;
67 
68  // read symbol properties
69  symbols.get_symbol(j, name, value, size, bind,
70  type, section_index, other);
71 
72  // check zero length names
73  if(name.length() == 0)
74  continue;
75 
76  // don't list section absolute symbols
77  if(section_index == SHN_ABS)
78  continue;
79 
80  // don't list local symbols
81  if((bind == STB_LOCAL) && (type != STT_NOTYPE))
82  continue;
83 
84  if(value < 0x800000) {
85  // range of flash space (.text)
86  std::pair<unsigned int, std::string> p(value >> 1, name);
87 
88  core->Flash->AddSymbol(p);
89  } else if(value < 0x810000) {
90  // range of ram (.data)
91  ELFIO::Elf64_Addr offset = value - 0x800000;
92  std::pair<unsigned int, std::string> p(offset, name);
93 
94  core->data->AddSymbol(p);
95  } else if(value < 0x820000) {
96  // range of eeprom (.eeprom)
97  ELFIO::Elf64_Addr offset = value - 0x810000;
98  std::pair<unsigned int, std::string> p(offset, name);
99 
100  core->eeprom->AddSymbol(p);
101  } else if(value < 0x820400) {
102  /* fuses space starting from 0x820000, do nothing */;
103  } else if(value >= 0x830000 && value < 0x830400) {
104  /* lock bits starting from 0x830000, do nothing */;
105  } else if(value >= 0x840000 && value < 0x840400) {
106  /* signature space starting from 0x840000, do nothing */;
107  } else
108  avr_warning("Unknown symbol address range found! (symbol='%s', address=0x%lx)",
109  name.c_str(),
110  value);
111 
112  }
113  }
114  }
115 
116  // load program, data and - if available - eeprom, fuses and signature
117  ELFIO::Elf_Half seg_num = reader.segments.size();
118 
119  for(ELFIO::Elf_Half i = 0; i < seg_num; i++) {
120  ELFIO::segment* pseg = reader.segments[i];
121 
122  if(pseg->get_type() == PT_LOAD) {
123  ELFIO::Elf_Xword filesize = pseg->get_file_size();
124  ELFIO::Elf64_Addr vma = pseg->get_virtual_address();
125  ELFIO::Elf64_Addr pma = pseg->get_physical_address();
126 
127  if(filesize == 0)
128  continue;
129 
130  const unsigned char* data = (const unsigned char*)pseg->get_data();
131 
132  if(vma < 0x810000) {
133  // read program, space below 0x810000 (.text)
134  core->Flash->WriteMem(data, pma, filesize);
135  } else if(vma >= 0x810000 && vma < 0x820000) {
136  // read eeprom content, if available, space from 0x810000 to 0x820000 (.eeprom)
137  unsigned int offset = vma - 0x810000;
138 
139  core->eeprom->WriteMem(data, offset, filesize);
140  } else if(vma >= 0x820000 && vma < 0x820400) {
141  // read fuses, if available, space from 0x820000 to 0x820400
142  if(!core->fuses->LoadFuses(data, filesize))
143  avr_error("wrong byte size of fuses");
144  } else if(vma >= 0x830000 && vma < 0x830400) {
145  // read lock bits, if available, space from 0x830000 to 0x830400
146  if(!core->lockbits->LoadLockBits(data, filesize))
147  avr_error("wrong byte size of lock bits");
148  } else if(vma >= 0x840000 && vma < 0x840400) {
149  // read and check signature, if available, space from 0x840000 to 0x840400
150  if(filesize != 3)
151  avr_error("wrong device signature size in elf file, expected=3, given=%lu",
152  filesize);
153  else {
154  unsigned int sig = (((data[2] << 8) + data[1]) << 8) + data[0];
155 
156  if(core->devSignature != std::numeric_limits<unsigned int>::max() && sig != core->devSignature)
157  avr_error("wrong device signature, expected=0x%x, given=0x%x",
158  core->devSignature,
159  sig);
160  }
161  }
162  }
163  }
164 }
165 
166 unsigned int ELFGetSignature(const char *filename) {
167  unsigned int signature = std::numeric_limits<unsigned int>::max();
168  ELFIO::elfio reader;
169 
170  if(!reader.load(filename))
171  avr_error("File '%s' not found or isn't a elf object", filename);
172 
173  if(reader.get_machine() != EM_AVR)
174  avr_error("ELF file '%s' is not for Atmel AVR architecture (%d)",
175  filename,
176  reader.get_machine());
177 
178  ELFIO::Elf_Half seg_num = reader.segments.size();
179 
180  for(ELFIO::Elf_Half i = 0; i < seg_num; i++) {
181  ELFIO::segment* pseg = reader.segments[i];
182 
183  if(pseg->get_type() == PT_LOAD) {
184  ELFIO::Elf_Xword filesize = pseg->get_file_size();
185  ELFIO::Elf64_Addr vma = pseg->get_virtual_address();
186 
187  if(filesize == 0)
188  continue;
189 
190  if(vma >= 0x840000 && vma < 0x840400) {
191  // read and check signature, if available, space from 0x840000 to 0x840400
192  if(filesize != 3)
193  avr_error("wrong device signature size in elf file, expected=3, given=%lu",
194  filesize);
195  else {
196  const unsigned char* data = (const unsigned char*)pseg->get_data();
197 
198  signature = (((data[2] << 8) + data[1]) << 8) + data[0];
199  break;
200  }
201  }
202  }
203  }
204 
205  return signature;
206 }
207 
208 // EOF
AvrFlash * Flash
Definition: avrdevice.h:98
Basic AVR device, contains the core functionality.
Definition: avrdevice.h:66
void ELFLoad(const AvrDevice *core)
Definition: avrreadelf.cpp:38
AvrFuses * fuses
Definition: avrdevice.h:100
void WriteMem(const unsigned char *src, unsigned int addr, unsigned int secSize)
Definition: flash.cpp:62
std::string actualFilename
Definition: avrdevice.h:84
void AddSymbol(std::pair< unsigned int, std::string > p)
Definition: memory.h:82
#define avr_error(...)
Definition: avrerror.h:135
bool LoadLockBits(const unsigned char *buffer, int size)
Initialize lock bits from elf, checks proper size.
Definition: flashprog.cpp:321
void WriteMem(const unsigned char *, unsigned int offset, unsigned int size)
Definition: hweeprom.cpp:288
Data * data
a hack for symbol look-up
Definition: avrdevice.h:103
HWEeprom * eeprom
Definition: avrdevice.h:102
#define avr_warning(...)
Definition: avrerror.h:133
unsigned int ELFGetSignature(const char *filename)
Definition: avrreadelf.cpp:166
unsigned int devSignature
hold the device signature for this core
Definition: avrdevice.h:75
bool LoadFuses(const unsigned char *buffer, int size)
Initialize fuses from elf, checks proper size.
Definition: flashprog.cpp:251
AvrLockBits * lockbits
Definition: avrdevice.h:101