Experimental Dynamic Linking GCC for RISC OS

This is an experimental version of GCC for RISC OS that supports the creation of shared libraries and dynamically linked binaries. It is an ELF only toolchain which consists of GCC v3.4.6 and binutils v2.16.1. All supplied tools are themselves dynamically linked binaries which can be used to produced dynamically or statically linked ELF binaries/libraries.


Code Generation

The download and installation of the tools is the same as for the offical version of GCC:

gcc.zip (2435K) 21/07/06
Contains the basic static libraries and compiler driver.

cc1.zip (1663K) 21/07/06
Contains the C compiler and C++ compiler driver.

utils.zip (2459K) 21/07/06
Contains bison, cmp, cxxfilt, diff, diff3, flex, gperf, grep, gzip, make, mkdir, objcopy, objdump, patch, readelf, sdiff, sed, size, strip, touch.

cc1plus.zip (3327K) 21/07/06
Contains the static C++ library and C++ compiler.

system.zip 21/07/06
This is V1.10 of the SharedUnixLibrary. If you already have a newer version than this installed, then you don't require this version.

It is advisable to install this experimental version of GCC in a different place to your usual installation so that you can use either one as required.


Code Execution
To be able to use these tools and any binaries they create, the ELF loaders package and shared libraries below are required:

loaders.bin.zip (v1.03) (196K) 24/08/06
Contains the static loader, dynamic loader and support module.
History:
1.03 - Bugfix: Fixed corruption of r9 by support module SWI handler.
1.02 - Document change to handling of -fPIC by GCC.
1.01 - Initial release.

libUnixLib.so.zip (543K) 21/07/06
Contains a shared version of UnixLib.

libgcc.so.zip (11K) 02/06/06
Contains a shared version of the GCC support library.

libstdc++.so.zip (185K) 02/06/06
Contains a shared version of the C++ standard library. This library is only required for C++ binaries.

Installation of the runtime system above is simply a case of extracting the !DSO-libs directory from each archive in to the same directory on your harddrive. You must ensure that !DSO-libs has been run before you build or run any ELF code.


Building the ELF toolchain
Two sets of diffs are provided that will hopefully allow anyone to build the ELF toolchain as contained in the archives above:

GCCSDK diffs (333K)
Binutils diffs (18K)

These instructions may be a bit sparse in detail as I'm not very familiar with the use of diffs and patch, however, I hope they're of use to somebody.

They assume fresh downloads of GCCSDK V3.4.6 Release 1 from the SVN repository at www.riscos.info and binutils V2.16.1 from ftp.gnu.org.
After extracting GCCSDK to the build directory, binutils-2.16.1 should be extracted to gccsdk/riscos-elf so that the directory structure looks similar to this:

gccsdk/riscos-elf/binutils-2.16.1/bfd/
gccsdk/riscos-elf/binutils-2.16.1/binutils/
gccsdk/riscos-elf/binutils-2.16.1/config/
gccsdk/riscos-elf/binutils-2.16.1/cpu/
gccsdk/riscos-elf/binutils-2.16.1/etc/
gccsdk/riscos-elf/binutils-2.16.1/gas/
...
etc

Next apply the diffs from above to binutils and gccsdk. Configure binutils using the do-configure script within the binutils-2.16.1 directory and then configure gccsdk using the do-configure script in the gccsdk base directory. You will need to alter the pathnames within this script to suit your system. The toolchain can then be built as normal by issuing the make command from within the gccsdk base directory.

Notes:


Writing code for RISC OS shared libraries
Generally when writing C source code for a shared library, there are few changes required by the programmer than when writing for a static library, as the compiler does most of the work. However, there are a few things that the programmer can do to help the compiler/linker produce a more efficient library.
One of the simplest things that can be done is to declare any variables that are known to be constant and read only as const. This has the effect of placing the corresponding data into the text area of the library rather than the data area meaning that the data exists only once for all clients rather than separately for each client. The advantages are that less memory is required at runtime and the dynamic loader does not have to do as much work during program initialisation.
When a function is accessed through the PLT, it is necessary to call two routines to find the required information to be able to call the function. Both of these routines involve a search through a linked list which may be time consuming. In order to speed up this process, each routine caches the last information it was asked to find and attempts to reuse it next time, so avoiding the search. The programmer can ensure that this is the case by grouping together calls to functions in the same library.

As of V3.4.6 of ELF GCC the command line required to build a dynamically linked executable has been simplified. It was realised that up until now it was impossible to use a simple command line such as:

gcc test.c -o test

to build a dynamically linked executable due to the -fPIC switch being required during the link stage but not the compile stage. Adding -fPIC to the above command line would have given both stages the switch causing incorrect code generation (the code would be for a shared libary rather than an executable). To rectify this, GCC's built in specs have been changed so that unless the switches -static or -fpic have been specified by the user, -fPIC is assumed at link time.


Lee Noar (leenoar at ntlworld dot com)