= Add Per Function and Data Element Section Support to a BSP = [[TOC(GCI/Coding/AddPerSectionSupportToBSPs, depth=2)]] 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. == Directions for Students == **Pre-Requisite**: You '''must''' have completed "Getting Started: Hello World" or the equivalent of [wiki:GSoC/GettingStarted Getting Started for GSoC Students] before attempting this task. 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. 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 RTEMS_TESTER_DIR=${HOME}/rtems-4.11-work/rtems-tools/ RTEMS_TOOLS_DIR=${HOME}/rtems-4.11-work/tools/ }}} 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 0 }}} 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 https://git.rtems.org/rtems/commit/c/src?id=bd655345c1a5f7dba42ddf6cd56f6259c62eb267. 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. == Directions for Mentors == Check the commit, if it looks good and you have rights, push it. If not, ask on devel for a maintainer to push it.