1 /* od-avrelf.c -- dump information about an AVR elf object file.
2 Copyright (C) 2011-2014 Free Software Foundation, Inc.
3 Written by Senthil Kumar Selvaraj, Atmel.
5 This file is part of GNU Binutils.
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 3, or (at your option)
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.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
26 #include "safe-ctype.h"
32 #include "elf/external.h"
33 #include "elf/internal.h"
35 /* Index of the options in the options[] array. */
36 #define OPT_MEMUSAGE 0
38 /* List of actions. */
39 static struct objdump_private_option options
[] =
48 elf32_avr_help (FILE *stream
)
52 mem-usage Display memory usage\n\
56 typedef struct tagDeviceInfo
62 uint32_t eeprom_start
;
68 /* Return TRUE if ABFD is handled. */
71 elf32_avr_filter (bfd
*abfd
)
73 return bfd_get_flavour (abfd
) == bfd_target_elf_flavour
;
77 elf32_avr_get_note_section_contents (bfd
*abfd
, bfd_size_type
*size
)
81 if ((section
= bfd_get_section_by_name (abfd
, ".note.gnu.avr.deviceinfo")) == NULL
)
84 *size
= bfd_get_section_size (section
);
85 char *contents
= (char *) xmalloc (*size
);
86 bfd_get_section_contents (abfd
, section
, contents
, 0, *size
);
91 static char* elf32_avr_get_note_desc (bfd
*abfd
, char *contents
,
94 Elf_External_Note
*xnp
= (Elf_External_Note
*) contents
;
97 if (offsetof (Elf_External_Note
, name
) > size
)
100 in
.type
= bfd_get_32 (abfd
, xnp
->type
);
101 in
.namesz
= bfd_get_32 (abfd
, xnp
->namesz
);
102 in
.namedata
= xnp
->name
;
103 if (in
.namesz
> contents
- in
.namedata
+ size
)
106 in
.descsz
= bfd_get_32 (abfd
, xnp
->descsz
);
107 in
.descdata
= in
.namedata
+ align_power (in
.namesz
, 2);
109 && (in
.descdata
>= contents
+ size
110 || in
.descsz
> contents
- in
.descdata
+ size
))
113 if (strcmp (in
.namedata
, "AVR") != 0)
120 elf32_avr_get_device_info (bfd
*abfd
, char *description
,
123 if (description
== NULL
)
126 const bfd_size_type memory_sizes
= 6;
128 memcpy (device
, description
, memory_sizes
* sizeof(uint32_t));
131 uint32_t *stroffset_table
= ((uint32_t *) description
) + memory_sizes
;
132 bfd_size_type stroffset_table_size
= bfd_get_32 (abfd
, stroffset_table
);
133 char *str_table
= ((char *) stroffset_table
) + stroffset_table_size
;
135 /* If the only content is the size itself, there's nothing in the table */
136 if (stroffset_table_size
== 4)
139 /* First entry is the device name index. */
140 uint32_t device_name_index
= bfd_get_32 (abfd
, stroffset_table
+ 1);
142 device
->name
= str_table
+ device_name_index
;
146 elf32_avr_get_memory_usage (bfd
*abfd
,
147 bfd_size_type
*text_usage
,
148 bfd_size_type
*data_usage
,
149 bfd_size_type
*eeprom_usage
)
152 bfd_size_type avr_datasize
= 0;
153 bfd_size_type avr_textsize
= 0;
154 bfd_size_type avr_bsssize
= 0;
155 bfd_size_type bootloadersize
= 0;
156 bfd_size_type noinitsize
= 0;
157 bfd_size_type eepromsize
= 0;
160 if ((section
= bfd_get_section_by_name (abfd
, ".data")) != NULL
)
161 avr_datasize
= bfd_section_size (abfd
, section
);
162 if ((section
= bfd_get_section_by_name (abfd
, ".text")) != NULL
)
163 avr_textsize
= bfd_section_size (abfd
, section
);
164 if ((section
= bfd_get_section_by_name (abfd
, ".bss")) != NULL
)
165 avr_bsssize
= bfd_section_size (abfd
, section
);
166 if ((section
= bfd_get_section_by_name (abfd
, ".bootloader")) != NULL
)
167 bootloadersize
= bfd_section_size (abfd
, section
);
168 if ((section
= bfd_get_section_by_name (abfd
, ".noinit")) != NULL
)
169 noinitsize
= bfd_section_size (abfd
, section
);
170 if ((section
= bfd_get_section_by_name (abfd
, ".eeprom")) != NULL
)
171 eepromsize
= bfd_section_size (abfd
, section
);
173 *text_usage
= avr_textsize
+ avr_datasize
+ bootloadersize
;
174 *data_usage
= avr_datasize
+ avr_bsssize
+ noinitsize
;
175 *eeprom_usage
= eepromsize
;
179 elf32_avr_dump_mem_usage (bfd
*abfd
)
181 char *description
= NULL
;
182 bfd_size_type note_section_size
= 0;
184 deviceinfo device
= {0};
185 device
.name
= "Unknown";
187 bfd_size_type data_usage
= 0;
188 bfd_size_type text_usage
= 0;
189 bfd_size_type eeprom_usage
= 0;
191 char *contents
= elf32_avr_get_note_section_contents (abfd
,
194 if (contents
!= NULL
)
196 description
= elf32_avr_get_note_desc (abfd
, contents
, note_section_size
);
197 elf32_avr_get_device_info (abfd
, description
, &device
);
200 elf32_avr_get_memory_usage (abfd
, &text_usage
, &data_usage
,
203 printf ("AVR Memory Usage\n"
205 "Device: %s\n\n", device
.name
);
208 printf ("Program:%8ld bytes", text_usage
);
209 if (device
.flash_size
> 0)
210 printf (" (%2.1f%% Full)", ((float) text_usage
/ device
.flash_size
) * 100);
212 printf ("\n(.text + .data + .bootloader)\n\n");
215 printf ("Data: %8ld bytes", data_usage
);
216 if (device
.ram_size
> 0)
217 printf (" (%2.1f%% Full)", ((float) data_usage
/ device
.ram_size
) * 100);
219 printf ("\n(.data + .bss + .noinit)\n\n");
222 if (eeprom_usage
> 0)
224 printf ("EEPROM: %8ld bytes", eeprom_usage
);
225 if (device
.eeprom_size
> 0)
226 printf (" (%2.1f%% Full)", ((float) eeprom_usage
/ device
.eeprom_size
) * 100);
228 printf ("\n(.eeprom)\n\n");
231 if (contents
!= NULL
)
237 elf32_avr_dump (bfd
*abfd
)
239 if (options
[OPT_MEMUSAGE
].selected
)
240 elf32_avr_dump_mem_usage (abfd
);
243 const struct objdump_private_desc objdump_private_desc_elf32_avr
=