Notice: We have migrated to GitLab launching 2024-05-01 see here:

Version 7 (modified by Joel Sherrill, on 01/07/16 at 01:29:24) (diff)

Add more on repeat on variants

Add Per Function and Data Element Section Support to a BSP

When a program is compiled and linked, the linker attempts to resolve all references to functions and data elements required by the program. By default, the GNU linker will place an entire object file into an application executable even if only one symbol is required by the application. This can lead to unused code in an executable. This is undesirable from both an application image size and code review perspective.

The GNU tools, specifically GCC and GNU ld, have support for a special compilation and linking mode which results in only the referenced symbols being placed into an application executable. However, there are known cases where the application and supporting software are not 100% correct and all needed functions and data are not referenced in a way that results in GNU ld pulling in all needed methods and data.

Although large parts of RTEMS are carefully implemented to have only one method per file, experiments with turning on this capability have shown reductions in RTEMS test programs and user applications of up to 50% in overall size.

This task consists of turning on this capability for a specific BSP family. A BSP family is the collection of BSPs under a single directory such as c/src/lib/libbsp/CPU/BSP_FAMILY. The make/custom directory has a BSP.cfg file for each BSP which may be built. If the BSP Family supports multiple BSP variants, the BSP.cfg files may include either a shared ".inc" file or a base ".cfg" file with common settings.

All BSPS for the SPARC architecture support this advanced capability. For an example, see the file c/src/lib/libbsp/sparc/erc32/make/custom/erc32.cfg. Note the following lines at the bottom of the file which turn on the advanced capabilities.

# Add CFLAGS and LDFLAGS for compiling and linking with per item sections
CFLAGS_OPTIMIZE_V += -ffunction-sections -fdata-sections
LDFLAGS            = -Wl,--gc-sections

This is also a BSP Family with multiple BSP variants. The sis.cfg file includes erc32.cfg so editing one file impacts both BSPs.

With these options turned on, the linker script needs to be tailored to avoid removing any sections that are not referenced directly but need to be kept in the linked executable by adding the


macro to such sections. See for example c/src/lib/libbsp/sparc/shared/startup/linkcmds.base which has already been tailored. Each BSP will have a linkcmds file which may or may not include a shared base file.

Task Requirements

In the description of this task, you were given a BSP Family to enable this capability for. The BSP Family will be named CPU/BSP_FAMILY which indicates its location in the source tree and implies a set of BSP variants as described above. The task requires you to:

Build a toolset for the CPU architecture per the instruction in the Hello World task. You likely did this for sparc/sis. In that case, sparc was the CPU and sis was the BSP.

Be prepared to generate a proper patch for your changes.

A script "build_bsp" is attached which will assist in performing this task. It should be downloaded, placed in the same directory as the rtems/ source directory, and made executable (e.g. chmod +x build_bsp). The following lines near the top of the "build_bsp" script should be edited to localize the following directory paths:

# Tailor these for your local installation

The script is invoked as:

./build_bsp CPU BSP

It will build the specified CPU/BSP in the appropriate configuration for evaluating the reduction in application executable size. When executed, the script will create a build directory (b-BSP), configure in that directory (output in b-BSP/c.log), and then build RTEMS (output in b-BSP/b.log). If the build completes successfully, a "0" will be printed. Otherwise an error has occurred.

Record the size of the sample executables as reported by the "build_bsp" script and printed as part of the output on a successful build. This is an example invocation of "build_bsp" for the sh/gensh1 BSP:

$ time ./build_bsp sh gensh1

real	0m46.623s
user	1m48.800s
sys	0m32.261s
   text	   data	    bss	    dec	    hex	filename
  67826	   8090	   8760	  84676	  14ac4	ticker.exe
  29762	   3770	   5064	  38596	   96c4	minimum.exe
 144274	  20038	  10564	 174876	  2ab1c	capture.exe
  84242	   8502	   8836	 101580	  18ccc	nsecs.exe
 134978	  18986	   9328	 163292	  27ddc	paranoia.exe
 150194	  22910	   9036	 182140	  2c77c	cdtest.exe
  64850	   7274	   8728	  80852	  13bd4	base_sp.exe
  66946	   7510	  12168	  86624	  15260	unlimited.exe
  80770	   5866	   8316	  94952	  172e8	hello.exe

Note that the "time" command was used to measure how long this took to execute. The next lines show the size of the sample executables. The final line is "0" indicating the invocation was successful.

Repeat this for every BSP variant in the BSP family.

Now make the modifications needed to turn on the per element section capability:

  • Edit one or more .cfg and .inc files to add the appropriate options to CFLAGS_OPTIMIZE_V and LDFLAGS as shown in the previous section.
  • Edit one or more linkcmds files located within either c/src/lib/libbsp/CPU/BSP/startup/ or c/src/lib/libbsp/CPU/shared/startup to add the KEEP directives.

Using the "build_bsp" script, rebuild each the BSP variants in the BSP Family and again keep a running record of the sizes. The before and after size information is a critical part of the commit information.

There are a few quick indicators if something is not right.

  • If the reduction is near 100%, then something is not right. You will likely need mentor help to resolve this.
  • If the BSP did not reduce in size at all, then something is not right.

The expected drop is 10-50% for the tests with cdtest.exe and cxx_iostream.exe often showing the greatest reductions.

If the BSP variant is one which can be tested on a simulator, then you need to test it.

The commit message for your patch should be similar to the following one which was used for the mips/jmr3904 BSP.

mips/jmr3904: Add per-section compilation and linking support

The size of the sample executables without this option were:

 128028	   1812	  12224	 142064	  22af0	ticker.exe
  52600	   1324	   8192	  62116	   f2a4	minimum.exe
1156240	   2168	  19696	1178104	 11f9f8	cxx_iostream.exe
 706952	   5908	  24600	 737460	  b40b4	fileio.exe
 243232	   2372	  14084	 259688	  3f668	capture.exe
 155660	   1940	  12376	 169976	  297f8	nsecs.exe
 201256	   2212	  12896	 216364	  34d2c	paranoia.exe
 253696	   1872	  12576	 268144	  41770	cdtest.exe
 124452	   1812	  12208	 138472	  21ce8	base_sp.exe
 127640	   1844	  15648	 145132	  236ec	unlimited.exe
 133452	   1780	  11760	 146992	  23e30	hello.exe

The size of the sample executables with this option enabled were:

 115052	   1712	  12096	 128860	  1f75c	ticker.exe
  40760	   1256	   8144	  50160	   c3f0	minimum.exe
 671768	   2076	  18688	 692532	  a9134	cxx_iostream.exe
 679672	   5696	  23992	 709360	  ad2f0	fileio.exe
 227384	   2196	  13924	 243504	  3b730	capture.exe
 143132	   1832	  12248	 157212	  2661c	nsecs.exe
 187736	   2104	  12768	 202608	  31770	paranoia.exe
 234324	   1788	  12448	 248560	  3caf0	cdtest.exe
 111556	   1712	  12080	 125348	  1e9a4	base_sp.exe
 112876	   1744	  15520	 130140	  1fc5c	unlimited.exe
 118120	   1688	  11696	 131504	  201b0	hello.exe

If you noticed that cxx_iostream.exe dropped in size the most, this is because it is a C++ application while the others were C applications. Actual savings will vary by BSP.

The complete patch and commit message for the mips/jmr3904 can be viewed at

If the BSP Family has multiple variants, the commit message will need to include the before and after information for each BSP variant in the family.

Attachments (1)

Download all attachments as: .zip