Gcc - How to Create a Mapfile of the Object File

What are gcc linker map files used for?

I recommend generating a map file and keeping a copy for any software you put into production.

It can be useful for deciphering crash reports. Depending on the system, you likely can get a stack dump from the crash. The stack dump will include memory addresses and one of the registers will include the Instruction Pointer. That tells you the memory address code was executing at. On some systems, code addresses can be moved around (when loading dynamic libraries, hence, dynamic), but the lower order bytes should remain the same.

The map file is a MAP from memory location -> code location. It gives you the name of the function at a given memory address. Due to optimizations, it may not be extremely accurate, but it gives you a place to start in terms of looking for bugs that cause the crash.

Now, in 30 years of writing commercial software, this is the only thing I've used the map files for. Twice successfully.

How do I get a map file within arm-none-eabi-gcc

I found my fault from http://thehackerworkshop.com/?p=443 ,

arm-none-eabi-gcc -g hello.c -o hello -Wl,-Map=hello.map

   $(USER_DEFINE) -T $(LINKER_SCRIPT) -o $(BOOTLOADER).o -Wl,-Map=$(BOOTLOADER).map

it's work

Linking using map file without having object files

This is by no means a complete solution to the problem of running ELFs on a embedded target but for the specific problem of providing known addresses during the linking process, GNU LD allows you to provide addresses for symbols in code defined as extern by adding a PROVIDE statement or a simple assignment to the linker script. LD won't directly read a map file, but you could parse the map file, find the relevant addresses, generate a linker script that has the appropriate symbols provided, and use that linker script in the compilation of the ELF. The documentation for the provide and assignment features can be found at https://sourceware.org/binutils/docs/ld/Assignments.html

Generating map file which shows memory range of individual components in an executable

Is it possible to generate map files for .so files like this?

It is possible to generate a map like this at runtime from within the process, e.g. by examining /proc/self/maps, or following the runtime loader _r_debug->r_map link list.

As tofro's answer correctly states, it is not possible to generate such a map at static link time, because the load address of shared libraries is not known until the binary starts running.

When do we need to use gcc/g++ to generate Map files? -g is enough for debug?

But when/why do we also need to generate Map files, any requirement or ability of gdb relies on Map files?

Assuming you are talking about the linker -M (synonym to --print-map) and -Map options, these are purely debugging aids intended to tell you what code/data is being pulled into your binary (and why).

GDB does not need or use this output (and the output is not easily parseable, i.e. intended for human consumption only).

Update:

when and how do we use this map file?

As I said before, the file answers questions like:

  • which object or library did the given function come from?
  • how much space did it consume in .text or .data section?
  • why did this particular object file get selected into the link from an archive library (i.e. which unresolved symbol caused this object file to be linked in)?

You use the map file when you have one of the above questions. If you don't have such questions, then you don't have any need for the map file.

As for "how" -- just read it with your favorite editor or pager. If you have a specific question on how to interpret particular lines there, do ask a separate specific question.

Understanding the map file, optimizing for size

You are misreading the map file. None of the occurrences of .text.port_lock,
for example, represents a definition of the ChibiOS function void port_lock(void).

All the occurrences of .text.port_lock refer to input linker sections.

The first 4 occurrences, lying within the section of the map file titled
Discarded input sections, refer to input linker sections that the linker
discarded. For example:

.text.port_lock
0x00000000 0x1c /home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chmempools.o)

means that the linker found a section .text.port_lock of size 28 bytes
in input file /home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chmempools.o)
and threw it away.

The next 6 occurrences, lying within the the section of the map file titled
Linker script and memory map all refer to input linker sections that were
mapped into the output .text section. For example the first one:

.text.port_lock
0x000012a8 0x1c /tmp/ccaossic.ltrans0.ltrans.o

means that the linker found a section .text.port_lock of size 28 bytes
in input file /tmp/ccaossic.ltrans0.ltrans.o
and mapped it at address 0x000012a8 in the output .text section. Likewise the
second occurrence:

.text.port_lock
0x00001f70 0x1c /home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chsys.o)

means that an input section of the same name and size also was found in input
file /home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chsys.o)
and was mapped at address 0x00001f70 in the output .text section.

Altogether there are .text.port_lock input sections, all of them 28 bytes,
mapped in your output .text section from these input files:

/tmp/ccaossic.ltrans0.ltrans.o
/home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chsys.o)
/home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chthreads.o)
/home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chcore_v7m.o)
/home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chmemcore.o)
/home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chschd.o)

In all 6 of these cases, the input section contains no symbols, and in particular
no functions. For contrast, here is an example of an input section that does contain symbols:

 .text          0x000002f0       0x28 /home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chcoreasm_v7m.o)
0x000002f0 _port_switch
0x00000300 _port_thread_start
0x00000310 _port_switch_from_isr
0x00000314 _port_exit_from_isr

This is the input .text section from /home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chcoreasm_v7m.o).

The map file contains no indication that the port_lock function is linked multiple times. It contains no
indication that this function is linked at all. If it were linked multiple times then there
would have been a multiple-definition linkage error (except in the event that it had
been annotated as a weak symbol).

Why these six 28-byte input sections containing no symbols are all linked, or if they
need to be, is a matter about which I have no adequate evidence or ChibiOS expertise. I notice
that all but one of the object files from which these input sections come are
archive members of libChibios. In that light, it is worth remembering that if your linkage
requires an archive member for any reason then by default you will link the whole
archive member, even it contains more stuff than you need. On the other hand, the fact
that some port_lock input sections are discarded and some are kept suggests that there
is a need to keep the ones that are kept. If for my own cunning reasons I write a source file
essentially like:

static int __attribute__((section(".text.foo"))) __attribute__((used)) 
boo(int i)
{
return i * 2;
}

int bar(int i)
{
return boo(i);
}

then in my map file you will see an empty input section called .text.foo. This
doesn't tell you anything about the symbols I'm linking.

How can I tell the toolchain to only link once each function?

The linker will not link any symbol definition more than once, except in the special
case of weak symbols. Your map file contains no evidence of any function being linked more than once.

How can I reduce the final file size?

Compile with -Os for your release, of course. And to minimize linkage redundancy,
see this question.

Reading a linker map file is usually a clunky way of investigating the symbols and sections
in your binaries. Prefer objdump, readelf
and nm

How to generate dependency files when generating object files of c sources with make

There are two small mistakes which took me quite a while to see:

  • DEPFILES := $(SRCS:%.c=$(DEPDIR)/%.d) has to be DEPFILES := $(SOURCES:%.c=$(DEPDIR)/%.d) - otherwise DEPFILES is empty since SRCS is undefined.
  • In $(CC) $(DEPFLAGS) -c $(CFLAGS) $(INCLUDES) -o $@ $^ the $^ (all the prerequisites) expands to e. g. main.c .deps/main.d, so a not yet existing .deps/main.d is passed as an input file; we want $*.c instead of $^.

Another minor error is:

  • rm -r .dep should be rm -r .deps or rm -r $(DEPDIR).


Related Topics



Leave a reply



Submit