Using -save-temps it is often very useful to study the .s (asm source) files generated by the C compiler for each source file that is input. However the files are pure Asm with no obvious links to the source that generated them. When built with later versions of the compiler and -g the files do, however, contain .file statements to identify the source files involved and also .loc statements to identify specific lines in those source. These are used in the creation of the Dwarf2 information in the .elf file and are what allows objdump -S to produce a source annotated disassembly in the .lss file.
The utility presented here can be run as a post-build step on each .s file that is created by -g -save-temps and it then embeds the C source lines referred to by .loc's into a new file it generated (for file.s it produces file.source.s). It also strips out a lot of internal labels and other "housekeeping" to make the .source.s file much easier to read than the plain .s file.
To invoke just use:
avr-source file.s
This will create file.source.s in the same directory. A typical example is this C source:
int main(void) {
DDRB= 0xFF;
while(1) {
PORTB ^= 0xFF;
_delay_ms(100);
}
}
which produces this in the .s file:
.global main
.type main, @function
main:
.LFB6:
.file 1 ".././ledblink.c"
.loc 1 4 0
.cfi_startproc
/* prologue: function */
/* frame size = 0 */
/* stack size = 0 */
.L__stack_usage = 0
.loc 1 5 0
ldi r24,lo8(-1) ; tmp46,
out 0x17,r24 ; MEM(volatile uint8_t *)55B?, tmp46
.L2:
.loc 1 7 0 discriminator 1
in r24,0x18 ; D.1487, MEM(volatile uint8_t *)56B?
com r24 ; D.1487
out 0x18,r24 ; MEM(volatile uint8_t *)56B?, D.1487
.LVL0:
.LBB4:
.LBB5:
.file 2 "c:\\program files\\atmel\\atmel toolchain\\avr8 gcc\\native\\3.4.2.876\\avr8-gnu-toolchain\\bin\\../lib/gcc/avr/4.7.2/../../../../avr/include/util/delay.h"
.loc 2 164 0 discriminator 1
ldi r24,lo8(24999) ; ,
ldi r25,hi8(24999) ; ,
1: sbiw r24,1 ;
brne 1b
rjmp .
nop
rjmp .L2 ;
.LBE5:
.LBE4:
.cfi_endproc
.LFE6:
.size main, .-main
and after processing with avr-source this becomes (the hopefully more readable!):
.global main
.type main, @function
main:
//==> int main(void) {
/* prologue: function */
/* frame size = 0 */
/* stack size = 0 */
.L__stack_usage = 0
//==> DDRB= 0xFF;
ldi r24,lo8(-1) ; tmp46,
out 0x17,r24 ; MEM(volatile uint8_t *)55B?, tmp46
.L2:
//==> PORTB ^= 0xFF;
in r24,0x18 ; D.1487, MEM(volatile uint8_t *)56B?
com r24 ; D.1487
out 0x18,r24 ; MEM(volatile uint8_t *)56B?, D.1487
//==> __builtin_avr_delay_cycles(__ticks_dc);
ldi r24,lo8(24999) ; ,
ldi r25,hi8(24999) ; ,
1: sbiw r24,1 ;
brne 1b
rjmp .
nop
rjmp .L2 ;
.size main, .-main
.text
Each line of source annotation beginning //==>