avr-objdump is very useful, but sometimes it's necessary to see information about the link that can only be generated by the linker. A map file contains this information. A map file is useful for monitoring the sizes of your code and data. It also shows where modules are loaded and which modules were loaded from libraries. It is yet another view of your application. To get a map file, I usually add -Wl,-Map,demo.map to my link command. Relink the application using the following command to generate demo.map (a portion of which is shown below).

$ avr-gcc -g -mmcu=atmega8 -Wl,-Map,demo.map -o demo.elf demo.o

Some points of interest in the demo.map file are:

.rela.plt
 *(.rela.plt)

.text           0x0000000000000000       0xd8
 *(.vectors)
 *(.vectors)
 *(.progmem.gcc*)
                0x0000000000000000                . = ALIGN (0x2)
                0x0000000000000000                __trampolines_start = .
 *(.trampolines)
 .trampolines   0x0000000000000000        0x0 linker stubs
 *(.trampolines*)
                0x0000000000000000                __trampolines_end = .
 *(.progmem*)
                0x0000000000000000                . = ALIGN (0x2)
 *(.jumptables)
 *(.jumptables*)
 *(.lowtext)
 *(.lowtext*)
                0x0000000000000000                __ctors_start = .

The .text segment (where program instructions are stored) starts at location 0x0.

*(.fini2)
*(.fini2)
*(.fini1)
*(.fini1)
*(.fini0)
.fini0         0x00000000000000d4        0x4 /data2/home/toolsbuild/jenkins-mcu-knuth/workspace/avr8-gnu-toolchain-dev/avr8-gnu-toolchain-linux_x86_64/lib/gcc/avr/4.8.1/avr4/libgcc.a(_exit.o)
*(.fini0)
               0x00000000000000d8                _etext = .

.data           0x0000000000800060        0x0 load address 0x00000000000000d8
               0x0000000000800060                PROVIDE (__data_start, .)
*(.data)
.data          0x0000000000800060        0x0 demo.o
.data          0x0000000000800060        0x0 /data2/home/toolsbuild/jenkins-mcu-knuth/workspace/avr8-gnu-toolchain-dev/src/avr-libc/avr/lib/avr4/exit.o
.data          0x0000000000800060        0x0 /data2/home/toolsbuild/jenkins-mcu-knuth/workspace/avr8-gnu-toolchain-dev/avr8-gnu-toolchain-linux_x86_64/lib/gcc/avr/4.8.1/avr4/libgcc.a(_exit.o)
.data          0x0000000000800060        0x0 /data2/home/toolsbuild/jenkins-mcu-knuth/workspace/avr8-gnu-toolchain-dev/avr8-gnu-toolchain-linux_x86_64/lib/gcc/avr/4.8.1/avr4/libgcc.a(_clear_bss.o)
*(.data*)
*(.rodata)
*(.rodata*)
*(.gnu.linkonce.d*)
               0x0000000000800060                . = ALIGN (0x2)
               0x0000000000800060                _edata = .
               0x0000000000800060                PROVIDE (__data_end, .)

.bss            0x0000000000800060        0x3
               0x0000000000800060                PROVIDE (__bss_start, .)
*(.bss)
.bss           0x0000000000800060        0x3 demo.o
.bss           0x0000000000800063        0x0 /data2/home/toolsbuild/jenkins-mcu-knuth/workspace/avr8-gnu-toolchain-dev/src/avr-libc/avr/lib/avr4/exit.o
.bss           0x0000000000800063        0x0 /data2/home/toolsbuild/jenkins-mcu-knuth/workspace/avr8-gnu-toolchain-dev/avr8-gnu-toolchain-linux_x86_64/lib/gcc/avr/4.8.1/avr4/libgcc.a(_exit.o)
.bss           0x0000000000800063        0x0 /data2/home/toolsbuild/jenkins-mcu-knuth/workspace/avr8-gnu-toolchain-dev/avr8-gnu-toolchain-linux_x86_64/lib/gcc/avr/4.8.1/avr4/libgcc.a(_clear_bss.o)
*(.bss*)
*(COMMON)
               0x0000000000800063                PROVIDE (__bss_end, .)
               0x00000000000000d8                __data_load_start = LOADADDR (.data)
               0x00000000000000d8                __data_load_end = (__data_load_start + SIZEOF (.data))

.noinit         0x0000000000800063        0x0
               0x0000000000800063                PROVIDE (__noinit_start, .)
*(.noinit*)
               0x0000000000800063                PROVIDE (__noinit_end, .)
               0x0000000000800063                _end = .
               0x0000000000800063                PROVIDE (__heap_start, .)

.eeprom         0x0000000000810000        0x0
*(.eeprom*)
               0x0000000000810000                __eeprom_end = .

The last address in the .text segment is location 0x114 ( denoted by _etext ), so the instructions use up 276 bytes of FLASH.

The .data segment (where initialized static variables are stored) starts at location 0x60, which is the first address after the register bank on an ATmega8 processor.

The next available address in the .data segment is also location 0x60, so the application has no initialized data.

The .bss segment (where uninitialized data is stored) starts at location 0x60.

The next available address in the .bss segment is location 0x63, so the application uses 3 bytes of uninitialized data.

The .eeprom segment (where EEPROM variables are stored) starts at location 0x0.

The next available address in the .eeprom segment is also location 0x0, so there aren't any EEPROM variables.