wiki:GCI/Coding/AddPerSectionSupportToBSPs

Version 4 (modified by Gedare Bloom, on Jan 6, 2016 at 4:40:03 PM) (diff)

Add info about KEEP directives in linkcmds.

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

KEEP

macro to such sections. See for example c/src/lib/libbsp/sparc/shared/startup/linkcmds.base which has already been tailored.

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.

Build each BSP in the BSP family with the configure option "--enable-tests=samples"

Record the size of the sample executables as reported by the size command for this architecture. The build output has this information but it can be obtained by running a command similar to the following from the top of the build directory:

find . -name "*.exe"  | while read f; do (cd `dirname $f `; mips-rtems4.12-size `basename $f`); done | grep "\.exe"

Note that CPU will have to be replaced with the appropriate CPU architecture.

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.

Rebuild the BSP variants in the BSP Family and again note the size. If there is no reduction, something is not right. If the reduction is near 100%, then something is not right.

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.

Attachments (1)

Download all attachments as: .zip