Unused Section Elimination

Introduction

By default projects created within the LPCXpresso IDE are compiled with the options -ffunction-sections and -fdata-sections, which causes each function/data item to be placed into its own section. In addition the linker has the option --gc-sections enabled, which then allows the linker to remove any sections (ie code/data) that are not actually referenced by your code - which can have a noticeable effect on the overall size of your image.

What sections have been eliminated?

The linker option -map, allows you to analyse in more detail the contents of your application image. When you do a build, this will cause a file called <application>.map to be created in the Debug (or Release) subdirectory, which can be loaded into the editor view. This contains a large amount of information, including a list of discarded input sections (because they are unused and the linker option --gc-sections is enabled).

The -map option is enabled by default by the project wizard when a new project is created.

Do I really want to build my image with unused section elimination?

Generally building with unused section elimination enabled is the right thing to do for most users, since it will typically lead to smaller overall image sizes.

This is definitely the case where a project uses some code pulled in from libraries (either generated from other projects within your workspace, or from the C/C++ library). In such cases only some code from the library may be required, and hence you do not want extra unused code linked in.

In some cases though, particularly if the source code for a project is being tightly controlled and where all of the code being compiled ends up in the final image, then sometimes the compiler -ffunction-sectionsand -fdata-sections options will cause a slightly larger image to be generated. Thus it can sometime be worth experimenting if code size for you application is critical.

Debug problems caused by unused section elimination

Unfortunately users very occasionally encounter strange, irregular problems when debugging a specific part of an image that has been built with unused section elimination enabled. Examples of such behavior that have been seen in the past include:

Local variables not been displayed in the Variables view for a certain function in the image.

Erratic single stepping behavior when stepping through a certain function in the image.

Such behavior is typically being caused by issues in debug tables contained in the image. These debug tables are not downloaded to the target MCU, but rather provide information for the debugger such as how to match source code up to the binary instructions/data executed on the target MCU. These issues might be that certain sections of the debug tables having being erroneously removed (where the corresponding code has not been) or vice versa. This then means that for certain small sections of your application, the debugger can no longer keep the source and instruction information fully in step.

Note that such issues are definitely not common!

Typically, such issues can be solved by slight reordering of the source code where the strange behavior is being seen (for example moving a function from the end of a source file to the start, or even moving it into a different source file). Otherwise you can try turning off unused section elimination, as described below.

Turning off unused section elimination

The simplest way to turn off unused section elimination is to remove the linker option --gc-sections. But this is typically not an ideal solution, as the size of the image generated will typically increase noticeably (particularly if any library code is being pulled in).

It is possible to "control" more finely what gets removed by stopping the compiler breaking single source files into multiple sections (one for each function, and one for each data item).

To do this, remove the -ffunction-sections and -fdata-sections from the compiler settings for your project or for just a specific source file.

Even if you keep the --gc-sections option on the linker, removing these compiler options may well then, for example, prevent incorrect debug information generation for specific areas of your code. And it is probable that this may be done without bloating your code/data size to quite the same extend as just removing the --gc-sections does.