Preparing updateable programs requires no source code modifications in existing programs and minimal modifications to a programs build process (e.g. Makefile). Two types of modifications are necessary:
Calls to an existing compiler, like gcc, must be changed to calls to the UpStare compiler, hcucc.pl.
The flags supplied to a linker, like ld, must be modified to allow dynamically loaded shared objects (dynamic software update patches) to use the symbols of the built binary.
Figure 4-1 shows the original Makefile used for the PostgreSQL 7.4.16 database server and Figure 4-2 shows the modifications needed to this Makefile to prepare the PostgreSQL source code to become updateable. Section 4.1 and Section 4.2 explain the modifications applied to this Makefile.
Figure 4-1. Original Makefile for PostgreSQL 7.4.16.
... CC = gcc LD = ld AR = ar RANLIB = ranlib LORDER = lorder ... LDFLAGS =
Figure 4-2. Makefile modifications for an updateable PostgreSQL 7.4.16.
... CC = hcucc.pl --merge --keepmerged --update-version=7416 --base-version LD = hcucc.pl --merge --keepmerged --update-version=7416 AR = hcucil.pl --merge --mode=AR RANLIB = echo LORDER = echo ... LDFLAGS = -Wl,--export-dynamic
The build process is modified to invoke wrapper programs, such as a wrapper compiler, a wrapper linker, etc. These wrapper programs prepare updateable source code, but with a twist: the .o object files produced do not contain binary code, but text source code. During the linking process, a wrapper linker performs whole-program merging and prepares a _comb.c file containing the source code of all object files. This final source code is then prepared to be updateable. The implication of this whole-program merging indirection is that some utilities used during the build process, besides the compiler and linker, may also need to also be wrapped.
In Figure 4-2, the "CC" variable, indicating the compiler used, needs to invoke the UpStare hcucc.pl compiler. The arguments "--merge --keepmerged" are necessary to perform whole-program merging. The "--update-version=7416" argument is supplied to indicate the initial version(7.4.16) of the updateable program. The "--base-version" argument indicates that this is the original program that will be started for the first time; future versions will be dynamically applied. The "LD" variable, indicating the linker used, is redefined similar to "CC", but does not need the "--base-version" argument. The "AR" variable, indicating the library archiving utility used, is redefined in a similar way to function in a wrapper mode. Finally, other variables, such as "RANLIB" indicating the tool used to generate an archive index, and "LORDER" indicating the tool used to list dependencies of object files, are also modified. These variables are defining tools that are taking as input binary .o object files, and are redifined to not attempt to process binary input.
In this example, whole-program merging produces the file postgresql-7.4.16/src/backend/postgres_comb.c which contains the source code of all linked objects and the final object file is called postgresql-7.4.16/src/backend/postgres_comb.o. The final binary file retains its original name postgresql-7.4.16/src/backend/postgres.