On Tue, Oct 14, 2014 at 04:29:19PM +0530, Senthil Kumar Selvaraj wrote: > On Sat, Oct 11, 2014 at 10:35:22AM +0200, Joerg Wunsch wrote: > > I finally had a chance to test all this. > > > > For reference, here's the result for an ATmega1281: > > > > % avr-objdump -h -j .note.gnu.avr.deviceinfo -s > > avr/lib/avr5/atmega1281/crtm1281.o > > > > avr/lib/avr5/atmega1281/crtm1281.o: file format elf32-avr > > > > Sections: > > Idx Name Size VMA LMA File off Algn > > 11 .note.gnu.avr.deviceinfo 00000034 00000000 00000000 0000181c 2**2 > > CONTENTS, READONLY > > Contents of section .note.gnu.avr.deviceinfo: > > 0000 04000000 23000000 01000000 41565200 ....#.......AVR. > > 0010 00000000 00000200 00020000 00200000 ............. .. > > 0020 00000000 00100000 08000000 01000000 ................ > > 0030 00000000 .... > > > > > > As Senthil Kumar Selvaraj wrote: > > > > > How does the below patch look? Once you guys find it ok, I'll follow it > > > up with a documentation patch. Note that the part above the > > > L__desc_start label (and the .balign directive at the end) are there as > > > per the ELF spec for a note section. > > > > OK, if that's required, we have to stick with that. > > > > Wouldn't the note name string also possibly need padding > > for alignment behind it? (In the case of the "AVR\0", > > it only incidentally aligns the following .long values > > to a long boundary.) > > Yes, I figured it's only going to be "AVR\0", so I skipped the align > directive. I'll add it. > > > > For the documentation, please include a C struct definition > > as explanation: > > > > #define __NOTE_NAME_LEN 4 > > struct __note_gnu_avr_deviceinfo > > { > > struct > > { > > uint32_t note_name_len; /* = __NOTE_NAME_LEN */ > > uint32_t desc_len; > > char note_name[__NOTE_NAME_LEN]; /* = "AVR\0" */ > > } > > elfinfo_hdr; > > struct > > { > > uint32_t flash_start; > > uint32_t flash_size; > > uint32_t sram_start; > > uint32_t sram_size; > > uint32_t eeprom_start; > > uint32_t eeprom_size; > > uint32_t offset_table[2]; /* index 0: ... */ > > // ??? > > } > > avr_desc; > > }; > > Ok, will do. > > > > > +.L__stroffsettab_end: > > > + /* String table for storing arbitrary strings. > > > + Offsets are stored in the string offset table above */ > > > +.L__strtab_start: > > > + .byte 0 > > > +.L__device_name_start: > > > + .asciz DEVICE_NAME > > > +.L__device_name_end: > > > + .byte 0 > > > +.L__strtab_end: > > > > I don't quite understand the purpose of the two ".byte 0" definitions. > > I used the standard ELF string table convention - the first and last > bytes are null. From http://man7.org/linux/man-pages/man5/elf.5.html, > > "String table sections hold null-terminated character sequences, > commonly called strings. The object file uses these strings to > represent symbol and section names. One references a string as an > index into the string table section. The first byte, which is index > zero, is defined to hold a null byte ('\0'). Similarly, a string > table's last byte is defined to hold a null byte, ensuring null > termination for all strings." > > There's no need to follow that convention though - the descriptor's > layout/interpretation can be arbitrary. If you think it is redundant, > I'll drop it. > > I'll send a new patch with all the changes. >
Does the below patch look good? I've added documentation about the section's layout to doc/api/sections.dox. Regards Senthil ChangeLog 2014-11-03 Senthil Kumar Selvaraj <senthil_kumar.selva...@atmel.com> * crt1/gcrt1.S: Add a note section embedding device info. * doc/api/sections.dox: Document it. diff --git avr-libc/crt1/gcrt1.S avr-libc/crt1/gcrt1.S index 2d341a4..777bedb 100644 --- avr-libc/crt1/gcrt1.S +++ avr-libc/crt1/gcrt1.S @@ -304,3 +304,71 @@ __do_copy_data: #endif /* __AVR_ASM_ONLY__ */ ; .endfunc + .section .note.gnu.avr.deviceinfo, "", @note +#define NOTE_NAME "AVR" +#ifdef __AVR_DEVICE_NAME__ + #define DEVICE_NAME STR(__AVR_DEVICE_NAME__) +#else + #define DEVICE_NAME "" +#endif + + .long .L__note_name_end - .L__note_name_start + .long .L__desc_end - .L__desc_start + .long 1 ; Type 1 - this is the only known note type for AVR. +.L__note_name_start: + .asciz NOTE_NAME + .balign 4 +.L__note_name_end: +.L__desc_start: +#ifdef FLASHSTART + .long FLASHSTART +#else + .long 0 +#endif +#ifdef PROGMEM_SIZE + .long PROGMEM_SIZE +#elif FLASHEND > 0 + .long FLASHEND + 1 +#else + .long FLASHEND +#endif + .long RAMSTART +#ifdef RAMSIZE + .long RAMSIZE +#elif RAMEND > 0 + .long RAMEND - RAMSTART + 1 +#else + .long RAMEND +#endif +#ifdef E2START + .long E2START +#else + .long 0 +#endif +#ifdef EEPROM_SIZE + .long EEPROM_SIZE +#elif E2END > 0 + .long E2END + 1 +#else + .long E2END +#endif + /* String offsets table. + Index 0 - Size of offset table in bytes + Index 1 - Device name byte offset + */ +.L__stroffsettab_start: +.long .L__stroffsettab_end - .L__stroffsettab_start /* Size of index table in bytes */ +.long .L__device_name_start - .L__strtab_start /* Byte offset of device name */ +.L__stroffsettab_end: + /* String table for storing arbitrary strings. + Offsets are stored in the string offset table above */ +.L__strtab_start: + .byte 0 +.L__device_name_start: + .asciz DEVICE_NAME +.L__device_name_end: + .byte 0 +.L__strtab_end: +.L__desc_end: + .balign 4 + diff --git avr-libc/doc/api/sections.dox avr-libc/doc/api/sections.dox index a93dec4..a71f13b 100644 --- avr-libc/doc/api/sections.dox +++ avr-libc/doc/api/sections.dox @@ -207,6 +207,51 @@ Unused. User definable. Goes into an infinite loop after program termination and completion of any _exit() code (execution of code in the .fini9 -> .fini1 sections). +\section sec_dot_note The .note.gnu.avr.deviceinfo Section + +This section contains device specific information picked up from the device +header file and compiler builtin macros. The layout conforms to the standard ELF +note section layout (http://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-18048.html). + +The section contents are laid out as below. + +\code +#define __NOTE_NAME_LEN 4 +struct __note_gnu_avr_deviceinfo +{ + struct + { + uint32_t namesz; /* = __NOTE_NAME_LEN */ + uint32_t descsz; /* = size of avr_desc */ + uint32_t type; /* = 1 - no other AVR note types exist */ + char note_name[__NOTE_NAME_LEN]; /* = "AVR\0" */ + } + note_header; + struct + { + uint32_t flash_start; + uint32_t flash_size; + uint32_t sram_start; + uint32_t sram_size; + uint32_t eeprom_start; + uint32_t eeprom_size; + uint32_t offset_table_size; + uint32_t offset_table[1]; /* Offset table containing byte offsets into + string table that immediately follows it. + index 0: Device name byte offset + */ + char str_table [2 + + strlen(__AVR_DEVICE_NAME__)]; /* Standard ELF string table. + index 0 : NULL + index 1 : Device name + index 2 : NULL + */ + } + avr_desc; +}; +\endcode + + \section asm_sections Using Sections in Assembler Code Example: _______________________________________________ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-libc-dev