Search code examples
debuggingbuildlinkermemory-mappingarmcc

API names missing from '*.map' files and '*.asm' files


I am compiling a project with armcc :

It has following flags:

ASFLAGS := -g --cpu Cortex-R5 --fpu None $(addprefix -i,$(INCL)) --apcs /interwork
ASFLAGS += --diag_error=warning,193
CFLAGS := -g --cpu Cortex-R5 --split_sections --c99 --gnu --depend_dir=$(OBJ_PATH) --no_depend_system_headers --md
CFLAGS += --enum_is_int
CFLAGS += --diag_error=warning,193,1301,2530 --remarks
CFLAGS += --diag_suppress=2815
CFLAGS += --diag_remark=1215
#CFLAGS += -O0
CFLAGS += -O3
CFLAGS += -DROM
CFLAGS += -Otime
CFLGAS += -O3
$(TARTGET):="Mytarget"  
LDFLAGS := $(INSTRUCTION) --info=totals --info=unused --info=sizes  --callgraph --map --symbols --scatter=$(SCAT_FILE) --list $(TARGET).map
LDFLAGS += --datacompressor=off --library_type=microlib --entry=0xFFFF0000

this generates a map file and also i have fromelf binary to generate the asm.

fromelf $(TARGET).axf -c > $(TARGET).asm

However in the output *.map(memory) file

i am unable to see API names I added to the build under the main function if the Optimization3 (-O3 ) flags is set, removing it brings back the api names

e.g source: main.c

main()
{
    test_func()
}

*.map (with O3)

main                                     0xffff2218   ARM Code     152 main.o(i.main)
util_print                               0xffff22c0   ARM Code      40  util_print.o(i.util_print)
harm_reset_handler                       0xffff22ec   ARM Code       0  host_reset.o(reset)

source: *.map (with -O0)

main                                     0xffff2218   ARM Code     152  
main.o(i.main)
test_func                                0xffff22c0   ARM Code      40  test_func.o(i.test_func)
util_print                               0xffff22ec   ARM Code      40  util_print.o(i.util_print)
harm_reset_handler                       0xffff24f4   ARM Code       0  host_reset.o(reset)

My Question is is there a way to generate the map file with the -O3 turned ON but still not have the function symbol missing from *.map and *.asm files?


Solution

  • I asked about on arm forums and got a partial answer and was able to fill in the blanks with reading more arm documentation.

    Some more background info about the problem:

    1. Codebase was sprinkled with usage of API's with attributes __inline and __forceinline with no real control/intent of usage from devlopers.
    2. -O3 optimization was identified as the cause of the above defined problem as -O3 is supper aggressive. (see snippet below)

    ARM documentation Reference: (ARM Compiler toolchain Compiler Reference Version 5.03 Home > Compiler Command-line Options > -Onum)

    link:http://infocenter.arm.com/help/topic/com.arm.doc.dui0491i/CIHGFGFB.html

    Maximum optimization. -O3 performs the same optimizations as -O2 however the balance between space and time optimizations in the generated code is more heavily weighted towards space or time compared with -O2. That is:

    -O3 -Otime aims to produce faster code than -O2 -Otime, at the risk of increasing your image size

    -O3 -Ospace aims to produce smaller code than -O2 -Ospace, but performance might be degraded.

    In addition, -O3 performs extra optimizations that are more aggressive, such as:

    High-level scalar optimizations, including loop unrolling, for -O3 -Otime. This can give significant performance benefits at a small code size cost, but at the risk of a longer build time.

    More aggressive inlining and automatic inlining for -O3 -Otime.

    Solution:

    1. The compiler flag --no_inline was added to default/force no all API's to be inline
    2. All API's with __inline attributes were converted to __forceiinline reason for this was as below:

    RealView Compiler User Guide Home > Coding Practices > Function inlining > Managing inlining

    link:http://infocenter.arm.com/help/topic/com.arm.doc.kui0097a/armcc_cihjigba.htm

    You can control whether inlining is performed at all using the --no_inline and --inline keywords. By default, inlining of functions is enabled. If you disable inlining of functions using the --no_inline command-line option, then the compiler attempts to inline only those functions that are explicitly qualified with __forceinline.

    After making the above changes i was able to see the symbols and map file entries as expected.