home *** CD-ROM | disk | FTP | other *** search
- <!-- Warning to the author: -->
- <!-- Automatically generated by ./makeindex.pl: EDIT THE SOURCE INSTEAD -->
- <!doctype linuxdoc system> <!-- Oy! -*- SGML -*- mode, for this one -->
- <!-- $Id: gcc-howto.sgmlp,v 1.17 1996/02/28 19:35:50 dan Exp dan $ -->
- <article>
-
- <title>The Linux GCC HOWTO
- <author>Daniel Barlow <tt><dan@detached.demon.co.uk></tt>
- <date>v1.17, 28 February 1996
-
- <abstract>
- This document covers how to set up the GNU C compiler and development
- libraries under Linux, and gives an overview of compiling, linking,
- running and debugging programs under it. Most of the material in it
- has been taken from Mitch D'Souza's GCC-FAQ, which it replaces, or the
- ELF-HOWTO, which it will eventually largely replace.
-
- This is the first publically released version (despite the version
- number; that's an artifact of RCS). Feedback is welcomed.
- </abstract>
-
- <!-- *********************** SECTION ************************** -->
- <!-- Preliminaries -->
-
- <sect>Preliminaries
-
- <sect1> ELF vs. a.out
- <label id="index.0"> <!-- elf -->
- <label id="index.1"> <!-- a.out -->
-
- <p> Linux development is in a state of flux right now. Briefly, there
- are two formats for the binaries that Linux knows how to execute, and
- depending on how your system is put together, you may have either.
- When reading this HOWTO, it helps to know which.
-
- <label id="index.2"> <!-- <tt/file/ -->
-
- How to tell? Use the `file' utility (eg <tt>file /bin/bash</tt>).
- For an ELF program it will say something with ELF in, for an a.out
- program it will say something involving <tt>Linux/i386</tt>.
-
- The differences between ELF and a.out are covered (extensively) later
- in this document. ELF is the newer format, and generally accepted as
- better.
-
- <sect1> Administrata
-
- <label id="index.3"> <!-- chewing gum -->
- <p>The copyright information and like legalese can be found at the
- <em/end/ of this document, together with the statutory warnings about
- asking dumb questions on Usenet, revealing your ignorance of the C
- language by reporting bugs which aren't, and picking your nose while
- chewing gum.
-
- <sect1> Typography
-
- <p> If you're reading this in Postscipt, dvi, or html format, you get
- to see a little more font variation than people with the plain text
- version. In particular, filenames, commands, command output and
- source code excerpts are set in some form of <tt/typewriter/ font,
- whereas `variables' and random things that need emphasizing are
- <em/empasized/.
-
- You also get a usable index. In dvi or postscript, the numbers in the
- index are section numbers. In HTML they're just sequentially assigned
- numbers that you can click on. In the plain text version, they really
- are just numbers. Get an upgrade!
-
- The Bourne (rather than C) shell syntax is used in examples. C shell
- users will want to use
- <tscreen><verb>
- % setenv FOO bar
- </verb></tscreen>
- where I have written
- <tscreen><verb>
- $ FOO=bar; export FOO
- </verb></tscreen>
-
- If the prompt shown is <tt/#/ rather than <tt/$/, the command shown
- will probably only work as root. Of course, I accept no
- responsibility for anything that happens to your system as a result of
- trying these examples. Have a nice day <tt/:-)/
-
- <!-- *********************** SECTION ************************** -->
- <!-- Where to get things -->
-
- <sect>Where to get things
-
- <sect1>This document
-
- <p> This document is one of the Linux HOWTO series, so is available from all
- Linux HOWTO repositories, such as <url
- url="http://sunsite.unc.edu/pub/linux/docs/HOWTO/">. The HTML version
- can also be found (possibly in a slightly newer version) from <url
- url="http://ftp.linux.org.uk/~barlow/howto/gcc-howto.html">.
-
- <sect1> Other documentation
- <label id="index.4"> <!-- documentation -->
-
- <p> The official documentation for gcc is in the source distribution
- (see below) as texinfo files, and as <tt/.info/ files. If you have a fast
- network connection, a cdrom, or a reasonable amount of patience, you
- can just untar it and copy the relevant bits into <tt>/usr/info</tt>. If not,
- you may find them at <url url=
- "ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/" name="tsx-11">, but
- not necessarily always the latest version.
-
- <label id="index.5"> <!-- manual pages -->
-
- <p> There are two source of documentation for libc. GNU libc comes
- with info files which describe Linux libc fairly accurately except for
- stdio. Also, the <url name="manpages"
- url="ftp://sunsite.unc.edu/pub/Linux/docs/"> archive are written for
- Linux and describe a lot of system calls (section 2) and libc
- functions (section 3).
-
- <sect1>GCC
- <label id="index.6"> <!-- gcc -->
-
- <p> There are two answers.
-
- (a) The official Linux GCC distribution can always be found in binary
- (ready-compiled) form at <url url=
- "ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/">. At the time of
- writing, 2.7.2 (<tt/gcc-2.7.2.bin.tar.gz/) is the latest version.
-
- (b) The latest source distribution of GCC from the Free Software
- Foundation can be had from <url name="GNU archives"
- url="ftp://prep.ai.mit.edu/pub/gnu/">. This is not necessarily always
- the same version as above, though it is just now. The Linux GCC
- maintainer(s) have made it easy for you to compile the latest version
- available yourself --- the <tt/configure/ script should set it all up
- for you. Check <url name="tsx-11" url=
- "ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/"> as well, for patches
- which you may want to apply.
-
- To compile anything non-trivial (and quite a few trivial things also)
- you will also need the
-
- <sect1> C library and header files
- <label id="index.7"> <!-- libc -->
-
- <p>What you want here depends on (i) whether your system is ELF or
- a.out, and (ii) which you want it to be. If you're upgrading from
- libc 4 to libc 5, you are recommended to look at the ELF-HOWTO from
- approximately the same place as you found this document.
-
- These are available from <url name ="tsx-11" url=
- "ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/"> as above:
-
- <descrip>
-
- <tag/<tt/libc-5.2.18.bin.tar.gz// --- ELF shared library images, static
- libraries and include files for the C and maths libraries.
-
- <tag/<tt/libc-5.2.18.tar.gz// --- Source for the above. You will also
- need the <tt>.bin.</tt> package for the header files. If you are
- deliberating whether to compile the C library yourself or use the
- binaries, the right answer in nearly all cases is to use the binaries.
- You will however need to roll your own if you want NYS or shadow
- password support.
-
- <tag/<tt/libc-4.7.5.bin.tar.gz// --- a.out shared library images and static
- libraries for version 4.7.5 of the C library and friends. This is
- designed to coexist with the libc 5 package above, but is only really
- necessary if you wish to keep using/developing a.out format programs.
- </descrip>
-
- <sect1>Associated tools (as, ld, ar, strings etc)
-
- <label id="index.8"> <!-- <tt/as/ -->
- <label id="index.9"> <!-- <tt/ld/ -->
- <label id="index.10"> <!-- <tt/ar/ -->
- <label id="index.11"> <!-- <tt/strings/ -->
-
- <p> From <url name ="tsx-11" url=
- "ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/">, just like everything
- else so far. The current version is <tt/binutils-2.6.0.2.bin.tar.gz/.
-
- <p> Note that the binutils are only available in ELF, the current libc
- version is in ELF and the a.out libc is happiest when used in
- conjunction with an ELF libc. C library development is moving
- emphatically ELFwards, and unless you have really good reasons for
- needing a.out things you're encouraged to follow suit.
-
- <!-- to insert: 29) Where can I get Objective C for Linux ?-->
-
- <!-- *********************** SECTION ************************** -->
- <!-- installation and setup -->
-
- <sect>GCC installation and setup
-
- <sect1>GCC versions
-
- <label id="index.12"> <!-- version numbers -->
- <label id="index.13"> <!-- gcc, flags -->
- <label id="index.14"> <!-- gcc -v -->
-
- <p> You can find out what GCC version you're running by typing <tt>gcc
- -v</tt> at the shell prompt. This is also a fairly reliable way to
- find out whether you are set up for ELF or a.out. On my system it does
-
- <tscreen><verb>
- $ gcc -v
- Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.7.2/specs
- gcc version 2.7.2
- </verb></tscreen>
-
- <p> The key things to note here are
- <itemize>
- <item> <tt/i486/. This indicates that the gcc you are using was built
- for a 486 processor --- you might have 386 or 586 instead. All of
- these chips can run code compiled for each of the others; the
- difference is that the 486 code has added padding in some places so
- runs faster on a 486. This has no detrimental performance effect on a
- 386, but does make the binaries slightly larger.
-
- <item> <tt/box/. This is <em/not/ at all important, and may say
- something else (such as <tt/slackware/ or <tt/debian/) or nothing at
- all (so that the complete directory name is <tt/i486-linux/). If you
- build your own gcc, you can set this at build time for cosmetic
- effect. Just like I did <tt/:-)/
-
- <item> <tt/linux/. This may instead say <tt/linuxelf/ or
- <tt/linuxaout/, and, confusingly, the meaning of each varies according
- to the version that you are using.
-
- <itemize>
- <item> <tt/linux/ means ELF if the version is 2.7.0 or newer, a.out
- otherwise.
-
- <item><tt/linuxaout/ means a.out. It was introduced as a target
- when the definition of <tt/linux/ was changed from a.out to ELF, so
- you won't see any <tt/linuxaout/ gcc older than 2.7.0.
-
- <label id="index.15"> <!-- gcc, bugs -->
- <item><tt/linuxelf/ is obsolete. It is generally a version of gcc
- 2.6.3 set to produce ELF executables. Note that gcc 2.6.3 has known
- bugs when producing code for ELF --- an upgrade is advisable.
-
- </itemize>
- <item> <tt/2.7.2/ is the version number.
- </itemize>
-
- So, in summary, I have gcc 2.7.2 producing ELF code. Quelle surprise.
-
- <sect1> Where did it go?
-
- <p>If you installed gcc without watching, or if you got it as part of
- a distribution, you may like to find out where it lives in the
- filesystem. The key bits are
-
- <itemize>
- <item> <tt>/usr/lib/gcc-lib/</tt><em>target</em><tt>/</tt><em/version/<tt>/</tt> (and
- subdirectories) is where most of the compiler lives. This includes
- the executable programs that do actual compiling, and some
- version-specific libraries and include files.
-
- <item> <tt>/usr/bin/gcc</tt> is the compiler driver --- the bit that you
- can actually run from the command line. This can be used with
- multiple versions of gcc provided that you have multiple compiler
- directories (as above) installed. To find out the default version it
- will use, type <tt/gcc -v/. To force it to another version, type
- <tt/gcc -V /<em/version/. For example
-
- <tscreen><verb>
- # gcc -v
- Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.7.2/specs
- gcc version 2.7.2
- # gcc -V 2.6.3 -v
- Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.6.3/specs
- gcc driver version 2.7.2 executing gcc version 2.6.3
- </verb></tscreen>
-
- <item> <tt>/usr/</tt><em>target</em><tt>/(bin|lib|include)/</tt>. If you have
- multiple targets installed (for example, a.out and elf, or a
- cross-compiler of some sort, the libraries, binutils (<tt/as/, <tt/ld/
- and so on) and header files for the non-native target(s) can be found
- here. Even if you only have one kind of gcc installed you might find
- anyway that various bits for it are kept here. If not, they're in
- <tt>/usr/(bin|lib|include)</tt>.
-
- <item> <tt>/lib/</tt>,<tt>/usr/lib</tt> and others are library directories for
- the native system. You will also need <tt>/lib/cpp</tt> for many
- applications (X makes quite a lot of use of it) --- either copy it
- from <tt>/usr/lib/gcc-lib/</tt><em>target</em><tt>/</tt><em/version/<tt>/</tt> or
- make a symlink pointing there.
-
- <label id="index.16"> <!-- /lib/cpp -->
- </itemize>
-
- <sect1> Where are the header files?
- <label id="index.17"> <!-- header files -->
-
- <p>Apart from whatever you install yourself under
- <tt>/usr/local/include</tt>, there are three main sources of header
- files in Linux:
-
- <itemize>
-
- <item> Most of <tt>/usr/include/</tt> and its subdirectories are
- supplied with the libc binary package from H J Lu. I say `most'
- because you may also have files from other sources (<tt/curses/ and
- <tt/dbm/ libraries, for example) in here, especially if you are using
- the newest libc distribution (which doesn't come with curses or dbm,
- unlike the older ones).
-
- <label id="index.18"> <!-- <linux/*.h> -->
- <label id="index.19"> <!-- <asm/*.h> -->
-
- <item> <tt>/usr/include/linux</tt> and <tt>/usr/include/asm</tt> (for
- the files <tt><linux/*.h></tt> and <tt><asm/*.h></tt>)
- should be symbolic links to the directories
- <tt>linux/include/linux</tt> and <tt>linux/include/asm</tt> in the
- kernel source distribution. You need to install these if you plan to
- do <em/any/ non-trivial development; they are not just there for
- compiling the kernel.
-
- You might find also that you need to do <tt>make config</tt> in the
- kernel directory after unpacking the sources. Many files depend on
- <tt><linux/autoconf.h></tt> which otherwise may not exist, and in
- some kernel versions <tt/asm/ is a symbolic link itself and only
- created at <tt/make config/ time.
-
- So, if you unpack your kernel sources under <tt>/usr/src/linux</tt>, that's
- <tscreen><verb>
- $ cd /usr/src/linux
- $ su
- # make config
- [answer the questions. Unless you're going to go on and build the kernel
- it doesn't matter _too_ much what you say]
- # cd /usr/include
- # ln -s ../src/linux/include/linux .
- # ln -s ../src/linux/include/asm .
- </verb></tscreen>
-
- <label id="index.20"> <!-- <float.h> -->
- <label id="index.21"> <!-- <limits.h> -->
- <label id="index.22"> <!-- <varargs.h> -->
- <label id="index.23"> <!-- <stdarg.h> -->
- <label id="index.24"> <!-- <stddef.h> -->
-
- <item> Files such as <tt/<float.h>/, <tt/<limits.h>/,
- <tt/<varargs.h>/, <tt/<stdarg.h>/ and
- <tt/<stddef.h>/ vary according to the compiler version, so are
- found in <tt>/usr/lib/gcc-lib/i486-box-linux/2.7.2/include/</tt> and
- places of that ilk.
-
- </itemize>
-
- <sect1> Building cross compilers
-
- <sect2> Linux as the target platform
-
- <p> Assuming you have obtained the source code to gcc, usually you can
- just follow the instructions given in the INSTALL file for GCC. A
- <tt/configure --target=i486-linux --host=XXX/ on platform <tt/XXX/
- followed by a <tt/make/ should do the trick. Note that you will need
- the Linux includes, the kernel includes, and also to build the cross
- assembler and cross linker from the sources in <url
- url="ftp://tsx-11.mit.edu/pub/linux/packages/GCC/">.
-
- <sect2> Linux as the source platform, MSDOS as the target
-
- <p> Ugh. Apparently this is somewhat possible by using the "emx"
- package or the "go" extender. Please look at <url
- url="ftp://sunsite.unc.edu/pub/Linux/devel/msdos">.
-
- I have not tested this and cannot vouch for its abilities.
-
- <!-- *********************** SECTION ************************** -->
- <!-- * Porting and Compiling -->
-
- <sect>Porting and Compiling
-
- <sect1> Automatically defined symbols
- <label id="index.25"> <!-- gcc, flags -->
-
- <p>You can find out what symbols your version of gcc defines
- automatically by running it with the <tt/-v/ switch. For example,
- mine does:
-
- <tscreen><verb>
- $ echo 'main(){printf("hello world\n");}' | gcc -E -v -
- Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.7.2/specs
- gcc version 2.7.2
- /usr/lib/gcc-lib/i486-box-linux/2.7.2/cpp -lang-c -v -undef
- -D__GNUC__=2 -D__GNUC_MINOR__=7 -D__ELF__ -Dunix -Di386 -Dlinux
- -D__ELF__ -D__unix__ -D__i386__ -D__linux__ -D__unix -D__i386
- -D__linux -Asystem(unix) -Asystem(posix) -Acpu(i386)
- -Amachine(i386) -D__i486__ -
- </verb></tscreen>
-
- If you are writing code that uses Linux-specific features, it is a
- good idea to enclose the nonportable bits in
-
- <tscreen><verb>
- #ifdef __linux__
- /* ... funky stuff ... */
- #endif /* linux */
- </verb></tscreen>
-
- Use <tt>__linux__</tt> for this purpose, <em/not/ <tt/linux/.
- Although the latter is defined, it is not POSIX compliant.
-
- <!-- what does this mean? are we talking namespace issues here? -->
-
- <sect1> Compiler invocation
-
- <p> The documentation for compiler switches is the gcc info page (in
- Emacs, use <tt>C-h i</tt> then select the `gcc' option). Your distributor
- may not have packed this with your system, or you may have an old
- version; the best thing to do in this case is to download the gcc
- source archive from <url url="ftp://prep.ai.mit.edu/pub/gnu"> or one
- of its mirrors, and copy them out of it.
-
- The gcc manual page (<tt/gcc.1/) is, generally speaking, out of date.
- It will warn you of this when you try to look at it.
-
- <sect2> Compiler flags
- <label id="index.26"> <!-- gcc, flags -->
- <label id="index.27"> <!-- optimisation -->
-
- <p> gcc can be made to optimize its output code by adding
- <tt/-O/<em/n/ to its command line, where <em/n/ is an optional small
- integer. Meaningful values of <em/n/, and their exact effect, vary
- according to the exact version, but typically it ranges from 0 (no
- optimization) to 2 (lots) or 3 (lots and lots).
-
- Internally, gcc translates these to a series of <tt/-f/ and <tt/-m/
- options. You can see exactly which <tt/-O/ levels map to which
- options by running gcc with the <tt/-v/ flag and the (undocumented)
- <tt/-Q/ flag. For example, for <tt/-O2/, mine says
-
- <tscreen><verb>
- enabled: -fdefer-pop -fcse-follow-jumps -fcse-skip-blocks
- -fexpensive-optimizations
- -fthread-jumps -fpeephole -fforce-mem -ffunction-cse -finline
- -fcaller-saves -fpcc-struct-return -frerun-cse-after-loop
- -fcommon -fgnu-linker -m80387 -mhard-float -mno-soft-float
- -mno-386 -m486 -mieee-fp -mfp-ret-in-387
- </verb></tscreen>
-
- Using an optimization level higher than your compiler supports
- (e.g. <tt/-O6/) will have exactly the same effect as using the highest
- level that it <em/does/ support. Distributing code which is set to
- compile this way is a poor idea though --- if further optimisations
- are incorporated into future versions, you (or your users) may find
- that they break your code.
-
- <label id="index.28"> <!-- gcc, bugs -->
- Users of gcc 2.7.0 thru 2.7.2 should note that there is a bug in
- <tt/-O2/ on these. Specifically, strength reduction doesn't work. A
- patch can be had to fix this if you feel like recompiling gcc,
- otherwise make sure that you always compile with <tt/-fno-strength-reduce/
-
- <!-- I need a source for this patch -->
-
- <sect3>Processor-specific
-
- <p> There are other <tt/-m/ flags which aren't turned on by any variety of
- <tt/-O/ but are nevertheless useful. Chief among these are <tt/-m386/
- and <tt/-m486/, which tell gcc to favour the 386 or 486 respectively.
- Code compiled with one of these will still work on the other; 486 code
- is bigger, but otherwise not slower on the 386.
-
- There is currently no <tt/-mpentium/ or <tt/-m586/. Linus suggests
- using <tt/-m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2/,
- to get 486 code optimisations but without the big gaps for alignment
- (which the pentium doesn't need). Michael Meissner (of Cygnus) says
-
- <quote>
- My hunch is that <tt/-mno-strength-reduce/ also results in faster code on
- the x86 (note, I'm not talking about the strength reduction bug, which
- is another issue). This is because the x86 is rather register starved
- (and GCC's method of grouping registers into spill registers vs. other
- registers doesn't help either). Strength reduction typically results
- in using additional registers to replace multiplications with
- addition. I also suspect <tt/-fcaller-saves/ may also be a loss.
- </quote>
- <quote>
- Another hunch is that <tt/-fomit-frame-pointer/ might or might not be a
- win. On the one hand, it can mean that another register is available
- for allocation. On the other hand, the way the x86 encodes its
- instruction set, means that stack relative addresses take more space
- instead of frame relative addresses, which means slightly less Icache
- availble to the program. Also, <tt/-fomit-frame-pointer/, means that the
- compiler has to constantly adjust the stack pointer after calls, while
- with a frame, it can let the stack accumulate for a few calls.
- </quote>
-
- The final word on this subject is from Linus again:
-
- <quote>
- Note that if you want to get optimal performance, don't believe me:
- test. There are lots of gcc compiler switches, and it may be that a
- particular set gives the best optimizations for you.
- </quote>
-
- <!-- TODO: url for pentium gcc-->
-
- <sect2> <tt/Internal compiler error: cc1 got fatal signal 11/
-
- <label id="index.29"> <!-- gcc, bugs -->
- <label id="index.30"> <!-- segmentation fault -->
- <label id="index.31"> <!-- SIGSEGV -->
- <label id="index.32"> <!-- SIGSEGV, in gcc -->
- <label id="index.33"> <!-- segmentation fault, in GCC -->
-
- <p> Signal 11 is SIGSEGV, or `segmentation violation'. Usually it
- means that the program got its pointers confused and tried to write to
- memory it didn't own. So, it could be a gcc bug.
-
- gcc is however, a well tested and reliable piece of software, for
- the most part. It also uses a large number of complex data
- structures, and an awful lot of pointers. In short, it's the pickiest
- RAM tester commonly available. If you <em/can't duplicate the bug/
- --- if it doesn't stop in the same place when you restart the
- compilation --- it's almost certainly a problem with your hardware
- (CPU, memory, motherboard or cache). <bf/Don't/ claim it as a bug
- because your computer passes the power-on checks or runs Windows ok or
- whatever; these `tests' are commonly and rightly held to be worthless.
- And don't claim it's a bug because a kernel compile always stops
- during `<tt/make zImage/' --- of course it will! `<tt/make zImage/'
- is probably compiling over 200 files; we're looking for a slightly
- <em/smaller/ place than that.
-
- <p> If you can duplicate the bug, and (better) can produce a short
- program that exhibits it, you can submit it as a bug report to the
- FSF, or to the linux-gcc mailing list. See the gcc documentation for
- details of exactly what information they need.
-
- <!-- pointer to the sig11 faq -->
-
- <sect1>Portability
-
- <!-- 25) How do I port program XXX to Linux ? -->
-
- <p> It has been said that, these days, if something hasn't been ported
- to Linux then it is not worth having :-)
-
- Seriously though, in general only minor changes are needed to the
- sources to get over Linux's 100% POSIX compliance. It is also
- worthwhile passing back any changes to authors of the code such that
- in the future only `make' need be called to provide a working
- executable.
-
- <sect2> BSDisms (including <tt/bsd_ioctl/, <tt/daemon/ and <tt/<sgtty.h>/)
-
- <p> You can compile your program with <tt>-I/usr/include/bsd</tt> and link
- it with <tt>-lbsd</tt> (i.e. add <tt>-I/usr/include/bsd</tt> to <tt>CFLAGS</tt>
- and <tt>-lbsd</tt> to the <tt>LDFLAGS</tt> line in your Makefile). There is
- <em/no/ need to add <tt>-D__USE_BSD_SIGNAL</tt> any more if you want BSD
- type signal behavior, as you get this automatically when you have
- <tt>-I/usr/include/bsd</tt> and include <tt/<signal.h>/.
-
- <sect2> `Missing' signals
- (<tt/SIGBUS/, <tt/SIGEMT/, <tt/SIGIOT/, <tt/SIGTRAP/, <tt/SIGSYS/ etc)
- <label id="index.34"> <!-- <tt/SIGBUS/ -->
- <label id="index.35"> <!-- <tt/SIGEMT/ -->
- <label id="index.36"> <!-- <tt/SIGIOT/ -->
- <label id="index.37"> <!-- <tt/SIGTRAP/ -->
- <label id="index.38"> <!-- <tt/SIGSYS/ -->
-
- <p> Linux is POSIX compliant. These are not POSIX-defined signals ---
- ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
-
- <quote>
- ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS were omitted
- from POSIX.1 because their behavior is implementation dependent and
- could not be adequately categorized. Conforming implementations may
- deliver these signals, but must document the circumstances under which
- they are delivered and note any restrictions concerning their
- delivery.''
- </quote>
-
- <p>The cheap and cheesy way to fix this is to redefine these signals
- to <tt/SIGUNUSED/. The <em/correct/ way is to bracket the code that
- handles them with appropriate <tt/#ifdef/s:
-
- <tscreen><verb>
- #ifdef SIGSYS
- /* ... non-posix SIGSYS code here .... */
- #endif
- </verb></tscreen>
-
- <sect2> K & R Code
- <label id="index.39"> <!-- <tt/-fwritable-strings/ -->
-
- <p> GCC is an ANSI compiler; much existing code is not ANSI. There's
- really not much that can be done about this, except to add
- <tt/-traditional/ to the compiler flags. There is a certain amount of
- finer-grained control over which varieties of brain damage to emulate;
- consult the gcc info page.
-
- Note that <tt/-traditional/ has effects beyond just changing the
- language that gcc accepts. For example, it turns on
- <tt>-fwritable-strings</tt>, which moves string constants into data space
- (from text space, where they cannot be written to). This increases
- the memory footprint of the program.
-
- <sect2> Preprocessor symbols conflict with prototypes in the code
- <label id="index.40"> <!-- <tt/atoi()/ -->
- <label id="index.41"> <!-- <tt/atol()/ -->
-
- <p> One of the most frequent problems is that some common functions
- are defined as macros in Linux's header files and the preprocessor
- will refuse to parse similar prototype definitions in the code. Common
- ones are <tt/atoi()/ and <tt/atol()/.
-
- <sect2> <tt>sprintf()</tt>
- <label id="index.42"> <!-- <tt/sprintf()/ -->
-
- <p> Something to be aware of, especially when porting from SunOS, is
- that <tt/sprintf(string, fmt, ...)/ returns a pointer to <tt/string/
- on many unices, whereas Linux (following ANSI) returns the number of
- characters which were put into the string.
-
- <sect2> <tt/fcntl/ and friends. Where are the definitions of
- <tt/FD_*/ stuff ?
- <label id="index.43"> <!-- <tt/FD_SET/ -->
- <label id="index.44"> <!-- <tt/FD_CLR/ -->
- <label id="index.45"> <!-- <tt/FD_ISSET/ -->
- <label id="index.46"> <!-- <tt/FD_ZERO/ -->
- <label id="index.47"> <!-- <tt/fcntl/ -->
- <label id="index.48"> <!-- <tt><sys/time.h></tt> -->
- <label id="index.49"> <!-- <tt><unistd.h></tt> -->
-
- <p> In <tt><sys/time.h></tt>. If you are using <tt/fcntl/ you
- probably want to include <tt/<unistd.h>/ too, for the actual
- prototype.
-
- Generally speaking, the manual page for a function lists the necessary
- <tt/#include/s in its SYNOPSIS section.
-
- <!-- These courtesy of Bruno Haible-->
-
- <sect2> The <tt>select()</tt> timeout. Programs start busy-waiting.
- <label id="index.50"> <!-- select() -->
-
- <P> Once upon a time, the timeout parameter to <tt>select()</tt> was used
- read-only. Even then, manual pages warned:
-
- <quote>
- select() should probably return the time remaining from the original
- timeout, if any, by modifying the time value in place. This may be
- implemented in future versions of the system. Thus, it is unwise to
- assume that the timeout pointer will be unmodified by the select()
- call.
- </quote>
-
- The future has arrived! At least, it has here. On return from a
- <tt/select()/, the timeout argument will be set to the remaining time
- that it would have waited had data not arrived. If no data had
- arrived, this will be zero, and future calls using the same timeout
- structure will immediately return.
-
- To fix, put the timeout value into that structure every time you call
- <tt/select()/. Change code like
- <tscreen><verb>
- struct timeval timeout;
- timeout.tv_sec = 1; timeout.tv_usec = 0;
- while (some_condition)
- select(n,readfds,writefds,exceptfds,&ero;timeout);
- </verb></tscreen>
- to, say,
- <tscreen><verb>
- struct timeval timeout;
- while (some_condition) {
- timeout.tv_sec = 1; timeout.tv_usec = 0;
- select(n,readfds,writefds,exceptfds,&ero;timeout);
- }
- </verb></tscreen>
-
- Some versions of Mosaic were at one time notable for this problem.
- The speed of the spinning globe animation was inversely related to the
- speed that the data was coming in from the network at!
-
- <sect2> Interrupted system calls.
- <label id="index.51"> <!-- interrupted system calls -->
- <label id="index.52"> <!-- EINTR -->
-
- <sect3>Symptom:
-
- <p>When a program is stopped using Ctrl-Z and then restarted - or in
- other situations that generate signals: Ctrl-C interruption,
- termination of a child process etc. - it complains about "interrupted
- system call" or "write: unknown error" or things like that.
-
- <sect3>Problem:
-
- <p>POSIX systems check for signals a bit more often than some older
- unices. Linux may execute signal handlers ---
-
- <itemize>
- <item> asynchronously (at a timer tick)
- <item> on return from any system call
- <item> during the execution of the following system calls:
- <tt>select()</tt>, <tt>pause()</tt>, <tt>connect()</tt>,
- <tt>accept()</tt>, <tt>read()</tt> on terminals, sockets, pipes or
- files in <tt>/proc</tt>, <tt>write()</tt> on terminals, sockets, pipes or
- the line printer, <tt>open()</tt> on FIFOs, PTYs or serial lines,
- <tt>ioctl()</tt> on terminals, <tt>fcntl()</tt> with command
- <tt/F_SETLKW/, <tt>wait4()</tt>, <tt>syslog()</tt>, any TCP or NFS
- operations.
- </itemize>
-
- For other operating systems you may have to include the system calls
- <tt>creat()</tt>, <tt>close()</tt>, <tt>getmsg()</tt>, <tt>putmsg()</tt>,
- <tt>msgrcv()</tt>, <tt>msgsnd()</tt>, <tt>recv()</tt>, <tt>send()</tt>,
- <tt>wait()</tt>, <tt>waitpid()</tt>, <tt>wait3()</tt>, <tt>tcdrain()</tt>,
- <tt>sigpause()</tt>, <tt>semop()</tt> to this list.
- <!-- What does this MEAN? -->
-
- <p>If a signal (that the program has installed a handler for) occurs
- during a system call, the handler is called. When the handler returns
- (to the system call) it detects that it was interrupted, and
- immediately returns with -1 and <tt/errno = EINTR/. The program is
- not expecting that to happen, so bottles out.
-
- You may choose between two fixes.
-
- (1) For every signal handler that you install, add <tt/SA_RESTART/ to the
- sigaction flags. For example, change
-
- <tscreen><verb>
- signal (sig_nr, my_signal_handler);
- </verb></tscreen>
- to
- <tscreen><verb>
- signal (sig_nr, my_signal_handler);
- { struct sigaction sa;
- sigaction (sig_nr, (struct sigaction *)0, &ero;sa);
- #ifdef SA_RESTART
- sa.sa_flags |= SA_RESTART;
- #endif
- #ifdef SA_INTERRUPT
- sa.sa_flags &ero;= ~ SA_INTERRUPT;
- #endif
- sigaction (sig_nr, &ero;sa, (struct sigaction *)0);
- }
- </verb></tscreen>
-
- Note that while this applies to most system calls, you must still
- check for <tt/EINTR/ yourself on <tt/read()/, <tt/write()/,
- <tt/ioctl()/, <tt/select()/, <tt/pause()/ and <tt/connect()/. See
- below.
-
- (2) Check for <tt/EINTR/ explicitly, yourself:
-
- Here are two examples for <tt/read()/ and <tt/ioctl()/,
-
- Original piece of code using <tt/read()/
-
- <tscreen><verb>
- int result;
- while (len > 0) {
- result = read(fd,buffer,len);
- if (result < 0) break;
- buffer += result; len -= result;
- }
- </verb></tscreen>
- becomes
-
- <tscreen><verb>
- int result;
- while (len > 0) {
- result = read(fd,buffer,len);
- if (result < 0) { if (errno != EINTR) break; }
- else { buffer += result; len -= result; }
- }
-
- </verb></tscreen>
- and a piece of code using <tt/ioctl()/
-
- <tscreen><verb>
- int result;
- result = ioctl(fd,cmd,addr);
- </verb></tscreen>
- becomes
- <tscreen><verb>
- int result;
- do { result = ioctl(fd,cmd,addr); }
- while ((result == -1) && (errno == EINTR));
- </verb></tscreen>
-
- Note that in some versions of BSD Unix the default behaviour is to
- restart system calls. To get system calls interrupted you have to use
- the <tt/SV_INTERRUPT/ or <tt/SA_INTERRUPT/ flag.
-
- <!-- according to some comments in /usr/include this may no longer be -->
- <!-- the case. Should check -->
-
- <sect2> Writable strings (program seg faults randomly)
- <label id="index.53"> <!-- SIGSEGV -->
- <label id="index.54"> <!-- segmentation fault -->
- <label id="index.55"> <!-- <tt/mktemp()/ -->
- <label id="index.56"> <!-- <tt/-fwritable-strings/ -->
-
- <p> GCC has an optimistic view of its users, believing that they
- intend string constants to be exactly that --- constant. Thus, it
- stores them in the text (code) area of the program, where they can be
- paged in and out from the program's disk image (instead of taking up
- swapspace), and any attempt to rewrite them will cause a segmentation
- fault. This is a feature!
-
- It may cause a problem for old programs that, for example, call
- <tt>mktemp()</tt> with a string constant as argument. <tt/mktemp()/
- attempts to rewrite its argument in place.
-
- To fix, either (a) compile with <tt/-fwritable-strings/, to get gcc to
- put constants in data space, or (b) rewrite the offending parts to
- allocate a non-constant string and strcpy the data into it before
- calling.
-
- <sect2> Why does the <tt>execl()</tt> call fail?
- <label id="index.57"> <!-- <tt/execl()/ -->
-
- <p> Because you're calling it wrong. The first argument to <tt/execl/
- is the program that you want to run. The second and subsequent
- arguments become the <tt/argv/ array of the program you're calling.
- Remember: <tt/argv[0]/ is traditionally set even when a program is run
- with `no' arguments. So, you should be writing
-
- <tscreen><verb>
- execl("/bin/ls","ls",NULL);
- </verb></tscreen>
- not just
- <tscreen><verb>
- execl("/bin/ls", NULL);
- </verb></tscreen>
-
- <p> Executing the program with no arguments at all is construed as an
- invitation to print out its dynamic library dependencies, at least
- using a.out. ELF does things differently.
-
- <p>(If you want this library information, there are simpler interfaces;
- see the section on dynamic loading, or the manual page for <tt/ldd/).
-
- <!-- *********************** SECTION ************************** -->
- <!-- * Debugging -->
-
- <sect> Debugging and Profiling
-
- <sect1> Preventative maintenance (lint)
- <label id="index.58"> <!-- lint -->
-
- <p> There is no widely-used lint for Linux, as most people are
- satisfied with the warnings that gcc can generate.
- Probably the most useful is the <tt/-Wall/ switch --- this stands for
- `Warnings, all' but probably has more mnemonic value if thought of as
- the thing you bang your head against.
-
- There is a public domain lint available from <url
- url="ftp://larch.lcs.mit.edu/pub/Larch/lclint">. I don't know how
- good it is.
-
- <sect1> Debugging
- <label id="index.59"> <!-- debugging -->
-
- <sect2> How do I get debugging information into a program ?
- <label id="index.60"> <!-- <tt/gcc -g/ -->
- <label id="index.61"> <!-- <tt/gcc -fomit-frame-pointer/ -->
- <label id="index.62"> <!-- <tt/libg.a/ -->
-
- <p> You need to compile and link all its bits with the <tt/-g/ switch,
- and without the <tt/-fomit-frame-pointer/ switch. Actually, you don't
- need to recompile all of it, just the bits you're interested in debugging.
-
- <p> On a.out configurations the shared libraries are compiled with
- <tt/-fomit-frame-pointer/, which gdb won't get on with. Giving the
- <tt/-g/ option when you link should imply static linking; this is why.
-
- <p> If the linker fails with a message about not finding libg.a, you
- don't have <tt>/usr/lib/libg.a</tt>, which is the special
- debugging-enabled C library. It may be supplied in the libc binary
- package, or (in newer C library versions) you may need to get the libc
- source code and build it yourself. You don't actually <em/need/ it
- though; you can get enough information for most purposes simply by
- symlinking it to <tt>/usr/lib/libc.a</tt>
-
- <sect3> How do I get it out again?
- <label id="index.63"> <!-- binaries too big -->
-
- <p> A lot of GNU software comes set up to compile and link with
- <tt/-g/, causing it to make very big (and often static) executables.
- This is not really such a hot idea.
-
- <p> If the program has an autoconf generated <tt/configure/ script,
- you can usually turn off debugging information by doing
- <tt>./configure CFLAGS=</tt> or <tt>./configure CFLAGS=-O2</tt>. Otherwise,
- check the Makefile. Of course, if you're using ELF, the program is
- dynamically linked regardless of the <tt/-g/ setting, so you can just
- <tt/strip/ it.
-
- <!--- gdb; where on sunsite? xxgdb almost certainly has wrong url-->
-
- <sect2> Available software
- <label id="index.64"> <!-- gdb -->
-
- <p> Most people use <bf/gdb/, which you can get in source form from
- <url url="ftp://prep.ai.mit.edu/pub/gnu" name="GNU archive sites">, or
- as a binary from <url
- url="ftp://tsx-11.mit.edu/pub/linux/packages/GCC" name="tsx-11"> or
- sunsite. <bf/xxgdb/ is an X debugger based on this (i.e. you need gdb
- installed first). The source may be found at <url
- url="ftp://ftp.x.org/contrib/xxgdb-1.08.tar.gz">
-
- Also, the <bf/UPS/ debugger has been ported by Rick Sladkey. It runs
- under X as well, but unlike xxgdb, it is not merely an X front end for
- a text based debugger. It has quite a number of nice features, and if
- you spend any time debugging stuff, you probably should check it
- out. The Linux precompiled version and patches for the stock UPS
- sources can be found in <url
- url="ftp://sunsite.unc.edu/pub/Linux/devel/debuggers/">, and the
- original source at <url
- url="ftp://ftp.x.org/contrib/ups-2.45.2.tar.Z">.
-
- Another tool you might find useful for debugging is `<bf/strace/', which
- displays the system calls that a process makes. It has a multiplicity
- of other uses too, including figuring out what pathnames were compiled
- into binaries that you don't have the source for, exacerbating race
- conditions in programs that you suspect contain them, and generally
- learning how things work. The latest version of strace (currently
- 3.0.8) can be found at <url url="ftp://ftp.std.com/pub/jrs/">.
-
- <sect2> Background (daemon) programs
-
- <p> Daemon programs typically execute <tt/fork()/ early, and terminate
- the parent. This makes for a short debugging session.
-
- <p> The simplest way to get around this is to set a breakpoint for
- <tt/fork/, and when the program stops, force it to return 0.
-
- <tscreen><verb>
- (gdb) list
- 1 #include <stdio.h>
- 2
- 3 main()
- 4 {
- 5 if(fork()==0) printf("child\n");
- 6 else printf("parent\n");
- 7 }
- (gdb) break fork
- Breakpoint 1 at 0x80003b8
- (gdb) run
- Starting program: /home/dan/src/hello/./fork
- Breakpoint 1 at 0x400177c4
-
- Breakpoint 1, 0x400177c4 in fork ()
- (gdb) return 0
- Make selected stack frame return now? (y or n) y
- #0 0x80004a8 in main ()
- at fork.c:5
- 5 if(fork()==0) printf("child\n");
- (gdb) next
- Single stepping until exit from function fork,
- which has no line number information.
- child
- 7 }
- </verb></tscreen>
-
- <sect2> Core files
-
- <p> When Linux boots it is usually configured not to produce core
- files. If you like them, use your shell's builtin command to re-enable them:
- for C-shell compatibles (e.g. tcsh) this is
- <tscreen><verb>
- % limit core unlimited
- </verb></tscreen>
- while Bourne-like shells (sh, bash, zsh, pdksh) use
- <tscreen><verb>
- $ ulimit -c unlimited
- </verb></tscreen>
-
- If you want a bit more versatility in your core file naming (for
- example, if you're trying to conduct a post-mortem using a debugger
- that's buggy itself) you can make a simple mod to your kernel. Look
- for the code in <tt>fs/binfmt_aout.c</tt> and <tt>fs/binfmt_elf.c</tt> (in
- newer kernels, you'll have to grep around a little in older ones) that
- says
-
- <tscreen><verb>
- memcpy(corefile,"core.",5);
- #if 0
- memcpy(corefile+5,current->comm,sizeof(current->comm));
- #else
- corefile[4] = '\0';
- #endif
- </verb></tscreen>
-
- and change the <tt/0/s to <tt/1/s.
-
- <sect1>Profiling
-
- <p>Profiling is a way to examine which bits of a program are called most
- often or run for longest. It is a good way to optimize code and look
- at where time is being wasted. You must compile all object files that
- you require timing information for with <tt/-p/, and to make sense of
- the output file you will also need <tt/gprof/ (from the binutils
- package). See the <tt/gprof/ manual page for details.
-
- <!-- **************************** SECTION ********************* -->
- <!-- * Linking -->
-
- <sect>Linking
-
- <p> Between the two incompatible binary formats, the static vs shared
- library distinction, and the overloading of the verb `link' to mean
- both `what happens after compilation' and `what happens when a
- compiled program is invoked' (and, actually, the overloading of
- the word `load' in a comparable but opposite sense), this section is
- complicated. Little of it is much more complicated than that
- sentence, though, so don't worry too much about it.
-
- <p> To alleviate the confusion somewhat, we refer to what happens at
- runtime as `dynamic loading' and cover it in the next section. You
- will also see it described as `dynamic linking', but not here. This
- section, then, is exclusively concerned with the kind of linking
- that happens at the end of a compilation.
-
- <sect1> Shared vs static libraries
-
- <p> The last stage of building a program is to `link' it; to join all
- the pieces of it together and see what is missing. Obviously there
- are some things that many programs will want to do --- open files, for
- example, and the pieces that do these things are provided for you in
- the form of libraries. On the average Linux system these can be found
- in <tt>/lib</tt> and <tt>/usr/lib/</tt>, among other places.
-
- <label id="index.65"> <!-- binaries too big -->
- <label id="index.66"> <!-- statically linked binaries, unexpected -->
-
- When using a static library, the linker finds the bits that the
- program modules need, and physically copies them into the executable
- output file that it generates. For shared libraries, it doesn't ---
- instead it leaves a note in the output saying `when this program is
- run, it will first have to load this library'. Obviously shared
- libraries tend to make for smaller executables; they also use less
- memory and mean that less disk space is used. The default behaviour
- of Linux is to link shared if it can find the shared libraries, static
- otherwise. If you're getting static binaries when you want shared,
- check that the shared library files (<tt/*.sa/ for a.out, <tt/*.so/
- for ELF) are where they should be, and are readable.
-
- On Linux, static libraries have names like <tt/libname.a/, while
- shared libraries are called <tt/libname.so.x.y.z/ where <tt/x.y.z/ is
- some form of version number. Shared libraries often also have links
- pointing to them, which are important, and (on a.out configurations)
- associated <tt/.sa/ files. The standard libraries come in both shared
- and static formats.
-
- You can find out what shared libraries a program requires by using
- <tt/ldd/ (List Dynamic Dependencies)
- <tscreen><verb>
- $ ldd /usr/bin/lynx
- libncurses.so.1 => /usr/lib/libncurses.so.1.9.6
- libc.so.5 => /lib/libc.so.5.2.18
- </verb></tscreen>
-
- This shows that on my system the WWW browser `lynx' depends on the
- presence of <tt/libc.so.5/ (the C library) and <tt/libncurses.so.1/
- (used for terminal control). If a program has no dependencies,
- <tt/ldd/ will say `<tt/statically linked/' or `<tt/statically linked (ELF)/'.
-
- <sect1>Interrogating libraries (`which library is <tt/sin()/ in?')
- <label id="index.67"> <!-- <tt/sin()/ -->
- <label id="index.68"> <!-- <tt/cos()/ -->
- <label id="index.69"> <!-- maths -->
-
- <p> <tt/nm /<em/libraryname/ should list all the symbols that
- <em/libraryname/ has references to. It works on both static and shared
- libraries. Suppose that you want to know where <tt/tcgetattr()/ is defined:
- you might do
-
- <tscreen><verb>
- $ nm libncurses.so.1 |grep tcget
- U tcgetattr
- </verb></tscreen>
-
- The <tt/U/ stands for `undefined' --- it shows that the ncurses
- library uses but does not define it. You could also do
-
- <tscreen><verb>
- $ nm libc.so.5 | grep tcget
- 00010fe8 T __tcgetattr
- 00010fe8 W tcgetattr
- 00068718 T tcgetpgrp
- </verb></tscreen>
-
- The `<tt/W/' stands for `weak', which means that the symbol is
- defined, but in such a way that it can be overridden by another
- definition in a different library. A straightforward `normal'
- definition (such as the one for <tt/tcgetpgrp/) is marked by a
- `<tt/T/'
-
- <label id="index.70"> <!-- <tt/<math.h>/ -->
-
- The short answer to the question in the title, by the way, is
- <tt/libm.(so|a)/. All the functions defined in <tt><math.h></tt> are
- kept in the maths library; thus you need to link with <tt/-lm/ when
- using any of them.
-
- <!-- 13) Why are my binaries so huge and how do I reduce them ? -->
- <!-- covered static/shared, need to look at -g, -N -->
-
- <sect1>Finding files
-
- <p><tt/ld: Output file requires shared library `libfoo.so.1`/
-
- <p> The file search strategy of ld and friends varies according to
- version, but the only default you can reasonably assume is
- <tt>/usr/lib</tt>. If you want libraries elsewhere to be searched,
- specify their directories with the <tt/-L/ option to gcc or ld.
-
- <p> If that doesn't help, check that you have the right file in that
- place. For a.out, linking with <tt/-lfoo/ makes ld look for
- <tt/libfoo.sa/ (shared stubs), and if unsuccessful then for
- <tt/libfoo.a/ (static). For ELF, it looks for <tt/libfoo.so/ then
- <tt/libfoo.a/. <tt/libfoo.so/ is usually a symbolic link to
- <tt/libfoo.so.x/.
-
- <!-- n+1) How/when to recompile libc -->
-
- <sect1> Building your own libraries
-
- <sect2> Version control
-
- <p> As any other program, libraries tend to have bugs which get fixed
- over time. They also may introduce new features, change the effect of
- existing ones, or remove old ones. This could be a problem for
- programs using them; what if it was depending on that old feature?
-
- So, we introduce library versioning. We categorise the changes that
- might be made to a library as `minor' or `major', and we rule that a
- `minor' change is not allowed to break old programs that are using the
- library. You can tell the version of a library by looking at its
- filename (actually, this is, strictly speaking, a lie for
- ELF; keep reading to find out why) : <tt/libfoo.so.1.2/ has
- major version 1, minor version 2. The minor version number can be
- more or less anything --- libc puts a `patchlevel' in it, giving
- library names like <tt/libc.so.5.2.18/, and it's also reasonable to
- put letters, underscores, or more or less any printable ASCII in it.
-
- One of the major differences between ELF and a.out format is in
- building shared libraries. We look at ELF first, because it's
- simpler.
-
- <sect2> ELF? What is it then, anyway?
- <label id="index.71"> <!-- elf -->
-
- <p> ELF (Executable and Linking Format) is a binary format originally
- developed by USL (UNIX System Laboratories) and currently used in
- Solaris and System V Release 4. Because of its increased flexibility
- over the older a.out format that Linux was using, the GCC and C
- library developers decided last year to move to using ELF as the Linux
- standard binary format also.
-
- <sect3> Come again?
-
- <p> This section is from the document '/news-archives/comp.sys.sun.misc'.
-
- <quote>
- ELF ("Executable Linking Format) is the "new, improved" object file
- format introduced in SVR4. ELF is much more powerful than straight
- COFF, in that it *is* user-extensible. ELF views an object-file as
- an arbitarily long list of sections (rather than an array of fixed
- size entities), these sections, unlike in COFF, do not HAVE to be in
- a certain place and do not HAVE to come in any specific order etc.
- Users can add new sections to object-files if they wish to
- capture new data. ELF also has a far more powerful debugging format
- called DWARF (Debugging With Attribute Record Format) - not currently
- fully supported on linux (but work is underway). A linked list
- of DWARF DIEs (or Debugging Information Entries) forms the .debug
- section in ELF. Instead of being a collection of small, fixed-size
- information records, DWARF DIEs each contain an arbitrarily long
- list of complex attributes and are written out as a scope-based tree
- of program data. DIEs can capture a large amount of information that
- the COFF .debug section simply couldn't (like C++ inheritance graphs
- etc.).
- </quote>
- <quote>
- ELF files are accessed via the SVR4 (Solaris 2.0 ?) ELF access
- library, which provides an easy and fast interface to the more gory
- parts of ELF. One of the major boons in using the ELF access library
- is that you will never need to look at an ELF file qua. UNIX file, it
- is accessed as an Elf *, after an elf_open() call and from then on,
- you perform elf_foobar() calls on its components instead of messing
- about with its actual on-disk image (something many COFFers did with
- impunity).
- </quote>
-
- The case for/against ELF, and the necessary contortions to upgrade an
- a.out system to support it, are covered in the ELF-HOWTO and I don't
- propose to cut/paste them here. The HOWTO should be available in the
- same place as you found this one.
-
- <sect3> ELF shared libraries
-
- <p> To build <tt/libfoo.so/ as a shared library, the basic steps look
- like this:
-
- <tscreen><verb>
- $ gcc -fPIC -c *.c
- $ gcc -shared -Wl,-soname,libfoo.so.1 -o libfoo.so.1.0 *.o
- $ ln -s libfoo.so.1.0 libfoo.so.1
- $ ln -s libfoo.so.1 libfoo.so
- $ LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH ; export LD_LIBRARY_PATH
- </verb></tscreen>
-
- This will generate a shared library called <tt>libfoo.so.1.0</tt>, and
- the appropriate links for ld (<tt>libfoo.so</tt>) and the dynamic
- loader (<tt>libfoo.so.1</tt>) to find it. To test, we add the current
- directory to <tt/LD_LIBRARY_PATH/.
-
- <label id="index.72"> <!-- weird things -->
- When you're happpy that the library works, you'll have to move it to,
- say, <tt>/usr/local/lib</tt>, and recreate the appropriate links. The
- link from <tt/libfoo.so.1/ to <tt/libfoo.so.1.0/ is kept up to date by
- <tt>ldconfig</tt>, which on most systems is run as part of the boot
- process. The <tt>libfoo.so</tt> link must be updated manually. If you are
- scrupulous about upgrading all the parts of a library (e.g. the header
- files) at the same time, the simplest thing to do is make
- <tt>libfoo.so -> libfoo.so.1</tt>, so that ldconfig will keep both
- links current for you. If you <em/aren't/, you're setting yourself up
- to have <em/all kinds of weird things/ happen at a later date. Don't say
- you weren't warned.
-
- <tscreen><verb>
- $ su
- # cp libfoo.so.1.0 /usr/local/lib
- # /sbin/ldconfig
- # ( cd /usr/local/lib ; ln -s libfoo.so.1 libfoo.so )
- </verb></tscreen>
-
- <sect3> Version numbering, sonames and symlinks
- <label id="index.73"> <!-- soname -->
- <label id="index.74"> <!-- version numbers -->
-
- <p> Each library has a <em>soname</em>. When the linker finds one of
- these in a library it is searching, it embeds the soname into the
- binary instead of the actual filename it is looking at. At runtime,
- the dynamic loader will then search for a file with the name of the
- soname, not the library filename. Thus a library called
- <tt/libfoo.so/ could have a soname <tt/libbar.so/, and all programs
- linked to it would look for <tt/libbar.so/ instead when they started.
-
- <p>This sounds like a pointless feature, but it is key to
- understanding how multiple versions of the same library can coexist on
- a system. The de facto naming standard for libraries in Linux is to
- call the library, say, <tt>libfoo.so.1.2</tt>, and give it a soname of
- <tt>libfoo.so.1</tt>. If it's added to a `standard' library directory
- (e.g. <tt>/usr/lib</tt>), <tt>ldconfig</tt> will create a symlink
- <tt>libfoo.so.1 -> libfoo.so.1.2</tt> so that the appropriate image
- is found at runtime. You also need a link <tt>libfoo.so ->
- libfoo.so.1</tt> so that ld will find the right soname to use at link
- time.</p>
-
- <p> So, when you fix bugs in the library, or add new functions (any
- changes that won't adversely affect existing programs), you rebuild
- it, keeping the soname as it was, and changing the filename. When you
- make changes to the library that would break existing binaries, you
- simply increment the number in the soname --- in this case, call the
- new version <tt>libfoo.so.2.0</tt>, and give it a soname of
- <tt>libfoo.so.2</tt>. Now switch the <tt>libfoo.so</tt> link to point
- to the new version and all's well with the world again.
-
- Note that you don't <em/have/ to name libraries this way, but it's a
- good convention. ELF gives you the flexibility to name libraries in
- ways that will confuse the pants off people, but that doesn't mean you
- have to use it.
-
- Executive summary: supposing that you observe the tradition that major
- upgrades may break compatibility, minor upgrades may not, then link
- with
-
- <tscreen><verb>
- gcc -shared -Wl,-soname,libfoo.so.major -o libfoo.so.major.minor
- </verb></tscreen>
-
- and everything will be all right.
-
- <sect2> a.out. Ye olde traditional format
-
- <p> The ease of building shared libraries is a major reason for
- upgrading to ELF. That said, it's still possible in a.out. Get
- <url url=
- "ftp://tsx-11.mit.edu/pub/linux/packages/GCC/src/tools-2.17.tar.gz">
- and read the 20 page document that you will find after unpacking it.
- I hate to be so transparently partisan, but it should be clear from
- context that I never bothered myself :-)
-
- <sect3> ZMAGIC vs QMAGIC
- <label id="index.75"> <!-- ZMAGIC -->
- <label id="index.76"> <!-- QMAGIC -->
-
- <p> QMAGIC is an executable format just like the old a.out (also known
- as ZMAGIC) binaries, but which leaves the first page unmapped. This
- allows for easier NULL dereference trapping as no mapping exists in
- the range 0-4096. As a side effect your binaries are nominally smaller
- as well (by about 1K).
-
- Obsolescent linkers support ZMAGIC only, semi-obsolescent support both
- formats, and current versions support QMAGIC only. This doesn't
- actually matter, though, as the kernel can still run both formats.
-
- Your `file' command should be able to identify whether a program is
- QMAGIC.
-
- <sect3>File Placement
-
- <p> An a.out (DLL) shared library consists of two real files and a
- symlink. For the `foo' library used throughout this document as an
- example, these files would be <tt/libfoo.sa/ and <tt/libfoo.so.1.2/;
- the symlink would be <tt/libfoo.so.1/ and would point at the latter of
- the files. What are these for?
-
- At compile time, <tt/ld/ looks for <tt/libfoo.sa/. This is the `stub'
- file for the library, and contains all exported data and pointers to
- the functions required for run time linking.
-
- At run time, the dynamic loader looks for <tt/libfoo.so.1/. This is a
- symlink rather than a real file so that libraries can be updated with
- newer, bugfixed versions without crashing any application that was
- using the library at the time. After the new version --- say,
- <tt/libfoo.so.1.3/ --- is completely there, running ldconfig will
- switch the link to point to it in one atomic operation, leaving any
- program which had the old version still perfectly happy.
-
- DLL libraries (I know that's a tautology --- so sue me) often appear
- bigger than their static counterparts. They reserve space for future
- expansion in the form of `holes' which can be made to take no disk
- space. A simple <tt/cp/ call or using the program <tt/makehole/ will
- achieve this. You can also strip them after building, as the
- addresses are in fixed locations. <bf/Do not attempt to strip ELF
- libraries/.
-
- <sect3> ``libc-lite''?
-
- <p> A libc-lite is a light-weight version of the libc library built
- such that it will fit on a floppy and suffice for all of the most
- menial of UNIX tasks. It does <em/not/ include curses, dbm, termcap
- etc code. If your <tt>/lib/libc.so.4</tt> is linked to a lite lib, you are
- advised to replace it with a full version.
-
- <sect2> Linking: common problems
-
- <p> Send me your linking problems! I probably won't do anything about
- them, but I will write them up if I get enough ...
-
- <descrip>
-
- <tag> Programs link static when you wanted them shared</tag>
- <label id="index.77"> <!-- binaries too big -->
- <label id="index.78"> <!-- statically linked binaries, unexpected -->
-
- Check that you have the right links for <tt/ld/ to find each shared
- library. For ELF this means a <tt>libfoo.so</tt> symlink to the image,
- for a.out a <tt>libfoo.sa</tt> file. A lot of people had this problem
- after moving from ELF binutils 2.5 to 2.6 --- the earlier version
- searched more `intelligently' for shared libraries, so they hadn't
- created all the links. The intelligent behaviour was removed for
- compatibility with other architectures, and because quite often it got
- its assumptions wrong and caused more trouble than it solved.
-
- <tag> The DLL tool `mkimage' fails to find libgcc, or </tag>
- <label id="index.79"> <!-- libgcc -->
-
- As of <tt/libc.so.4.5.x/ and above, libgcc is no longer shared. Hence
- you must replace occurrences of `<tt/-lgcc/' on the offending line with
- <tt/`gcc -print-libgcc-file-name`/ (complete with the backquotes).
-
- Also, delete all <tt>/usr/lib/libgcc*</tt> files. This is important.
-
- <tag> <tt>__NEEDS_SHRLIB_libc_4 multiply defined</tt> messages </tag>
-
- are another consequence of the same problem.
-
- <tag> ``Assertion failure'' message when rebuilding a DLL ?</tag>
-
- This cryptic message most probably means that one of your jump table
- slots has overflowed because too little space has been reserved in the
- original <tt/jump.vars/ file. You can locate the culprit(s) by
- running the `<tt/getsize/' command provided in the tools-2.17.tar.gz
- package. Probably the only solution, though, is to bump the major
- version number of the library, forcing it to be backward incompatible.
-
- <tag> <tt/ld: output file needs shared library libc.so.4/ </tag>
-
- This usually happens when you are linking with libraries other than
- libc (e.g. X libraries), and use the <tt/-g/ switch on the link line
- without also using <tt/-static/.
-
- The <tt/.sa/ stubs for the shared libraries usually have an undefined
- symbol <tt/_NEEDS_SHRLIB_libc_4/ which gets resolved from the
- <tt/libc.sa/ stub. However with <tt/-g/ you end up linking with
- <tt/libg.a/ or <tt/libc.a/ and thus this symbol never gets resolved,
- leading to the above error message.
-
- In conclusion, add <tt/-static/ when compiling with the <tt/-g/ flag,
- or don't link with <tt/-g/. Quite often you can get enough debugging
- information by compiling the individual files with <tt/-g/, and
- linking <em/without/ it.
-
- </descrip>
-
- <!-- *********************** SECTION ************************** -->
- <!-- * Dynamic Loading -->
-
- <sect>Dynamic Loading
-
- <p> <em>This section is a tad short right now; it will be expanded
- over time as I gut the ELF howto </em>
-
- <sect1>Concepts
-
- <p> Linux has shared libraries, as you will by now be sick of hearing
- if you read the whole of the last section at a sitting. Some of the
- matching-names-to-places work which was traditionally done at link
- time must be deferred to load time.
-
- <sect1> Error messages
-
- <p> Send me your link errors! I won't do anything about them, but I
- might write them up ...
-
- <descrip>
-
- <tag> <tt>can't load library: /lib/libxxx.so, Incompatible version</tt></tag>
-
- (a.out only) This means that you don't have the correct major version
- of the xxx library. No, you can't just make a symlink to another
- version that you do have; if you are lucky this will cause your
- program to segfault. Get the new version. A similar situation with
- ELF will result in a message like
-
- <tscreen><verb>
- ftp: can't load library 'libreadline.so.2'
- </verb></tscreen>
-
- <tag><tt/warning using incompatible library version xxx/</tag>
-
- (a.out only) You have an older minor version of the library than the
- person who compiled the program used. The program will still run.
- Probably. An upgrade wouldn't hurt, though.
-
- </descrip>
-
- <sect1> Controlling the operation of the dynamic loader
- <label id="index.80"> <!-- <tt/LD_*/ environment variables -->
- <label id="index.81"> <!-- ldd -->
-
- <p> There are a range of environment variables that the dynamic loader
- will respond to. Most of these are more use to <tt/ldd/ than they are
- to the average user, and can most conveniently be set by running ldd
- with various switches. They include
-
- <itemize>
-
- <item> <tt/LD_BIND_NOW/ --- normally, functions are not `looked up' in
- libraries until they are called. Setting this flag causes all the
- lookups to happen when the library is loaded, giving a slower startup
- time. It's useful when you want to test a program to make sure that
- everything is linked.
-
- <item> <tt/LD_PRELOAD/ can be set to a file containing `overriding'
- function definitions. For example, if you were testing memory
- allocation strategies, and wanted to replace `malloc', you could write
- your replacement routine, compile it into <tt/malloc.o/ and then
- <tscreen><verb>
- $ LD_PRELOAD=malloc.o; export LD_PRELOAD
- $ some_test_program
- </verb></tscreen>
-
- <tt/LD_ELF_PRELOAD/ and <tt/LD_AOUT_PRELOAD/ are similar, but only
- apply to the appropriate type of binary. If
- <tt/LD_/<em/something/<tt/_PRELOAD/ and <tt/LD_PRELOAD/ are set, the
- more specific one is used.
-
- <item> <tt/LD_LIBRARY_PATH/ is a colon-separated list of directories
- in which to look for shared libraries. It does <em/not/ affect ld; it
- only has effect at runtime. Also, it is disabled for programs that
- run setuid or setgid. Again, <tt/LD_ELF_LIBRARY_PATH/ and
- <tt/LD_AOUT_LIBRARY_PATH/ can also be used to direct the search
- differently for different flavours of binary. <tt/LD_LIBRARY_PATH/
- shouldn't be necessary in normal operation; add the directories to
- <tt>/etc/ld.so.conf/</tt> and rerun ldconfig instead.
-
- <item> <tt/LD_NOWARN/ applies to a.out only. When set (e.g. with
- <tt/LD_NOWARN=true; export LD_NOWARN/) it stops the loader from
- issuing non-fatal warnings (such as minor version incompatibility
- messages).
-
- <item> <tt/LD_WARN/ applies to ELF only. When set, it turns the
- usually fatal ``Can't find library'' messages into warnings. It's not
- much use in normal operation, but important for ldd.
-
- <item> <tt/LD_TRACE_LOADED_OBJECTS/ applies to ELF only, and causes
- programs to think they're being run under <tt/ldd/:
-
- <tscreen><verb>
- $ LD_TRACE_LOADED_OBJECTS=true /usr/bin/lynx
- libncurses.so.1 => /usr/lib/libncurses.so.1.9.6
- libc.so.5 => /lib/libc.so.5.2.18
- </verb></tscreen>
-
- </itemize>
-
- <sect1> Writing programs with dynamic loading
- <label id="index.82"> <!-- <tt/dlopen()/ -->
- <label id="index.83"> <!-- <tt/dlsym()/ -->
-
- <p> This is very close to the way that Solaris 2.x dynamic loading
- support works, if you're familiar with that. It is covered
- extensively in H J Lu's ELF programming document, and the
- <tt>dlopen(3)</tt> manual page, which can be found in the ld.so
- package. Here's a nice simple example though: link it with
- <tt>-ldl</tt>
-
- <tscreen><verb>
- #include <dlfcn.h>
- #include <stdio.h>
-
- main()
- {
- void *libc;
- void (*printf_call)();
-
- if(libc=dlopen("/lib/libc.so.5",RTLD_LAZY))
- {
- printf_call=dlsym(libc,"printf");
- (*printf_call)("hello, world\n");
- }
-
- }
- </verb></tscreen>
-
- <!-- *********************** SECTION ************************** -->
- <!-- * The developers -->
-
- <sect> Contacting the developers
-
- <sect1> Bug reports
- <label id="index.84"> <!-- gcc, bugs -->
-
- <p> Start by <bf>narrowing the problem down</bf>. Is it specific to
- Linux, or does it happen with gcc on other systems? Is it specific to
- the kernel version? Library version? Does it go away if you link
- static? Can you trim the program down to something <bf/short/ that
- demonstrates the bug?
-
- Having done that, you'll know what program(s) the bug is in. For
- GCC, the bug reporting procedure is explained in the info file. For
- ld.so or the C or maths libraries, send mail to
- <tt/linux-gcc@vger.rutgers.edu/. If possible, include a short and
- self-contained program that exhibits the bug, and a description both
- of what you want it to do, and what it actually does.
-
- <sect1> Helping with development
-
- <p> If you want to help with the development effort for GCC or the C
- library, the first thing to do is join the
- <tt/linux-gcc@vger.rutgers.edu/ mailing list. If you just want to see
- what the discussion is about, there are list archives at <url
- url="http://homer.ncm.com/linux-gcc/">. The second and subsequent
- things depend on what you want to do!
-
- <!-- Maybe there should be a TODO list for gcc/libc/whatever, for -->
- <!-- people who want to play with it? Moot the idea on the list -->
-
- <!-- *********************** SECTION ************************** -->
- <!-- * Clearing up -->
-
- <sect> The Remains
-
- <sect1> The Credits
-
- <p><quote>
- Only presidents, editors, and people with tapeworms have the right to
- use the editorial ``we''.
- </quote>
- (Mark Twain)
-
- <p> This HOWTO is based very closely on Mitchum DSouza's GCC-FAQ; most
- of the information (not to mention a reasonable amount of the text) in
- it comes directly from that document. Instances of the first person
- pronoun in this HOWTO could refer to either of us; generally the ones
- that say ``I have not tested this; don't blame me if it toasts your
- hard disk/system/spouse'' apply to both of us.
-
- Contributors to this document have included (in ASCII ordering by
- first name)
- Andrew Tefft,
- Axel Boldt,
- Bill Metzenthen,
- Bruce Evans,
- Bruno Haible,
- Daniel Barlow,
- Daniel Quinlan,
- David Engel,
- Dirk Hohndel,
- Eric Youngdale,
- Fergus Henderson,
- H.J. Lu,
- Jens Schweikhardt,
- Kai Petzke,
- Michael Meissner,
- Mitchum DSouza,
- Olaf Flebbe,
- Paul Gortmaker,
- Rik Faith,
- Steven S. Dick,
- Tuomas J Lukka,
- and of course Linus Torvalds, without whom the whole exercise would
- have been pointless, let alone impossible :-)
-
- Please do not feel offended if your name has not appeared here and you
- have contributed to this document (either as HOWTO or as FAQ). Email
- me and I will rectify it.
-
- <!-- of course, lots of this is due to other people; the copyright had -->
- <!-- better be looked at -->
-
- <sect1> Translations
-
- <p> At this time, there are no known translations of this work. If
- you wish to produce one, please go right ahead, but do tell me about
- it! The chances are (sadly) several hundred to one against that I
- speak the language you wish to translate to, but that aside I am happy
- to help in whatever way I can.
-
- <sect1> Feedback
-
- is welcomed. Mail me at <htmlurl
- url="mailto:dan@detached.demon.co.uk"
- name="dan@detached.demon.co.uk">. My PGP public key (ID 5F263625) is
- available from my <url url="http://ftp.linux.org.uk/~barlow/"
- name="web pages">, if you feel the need to be secretive about things.
-
- <sect1> Legalese
-
- <p> All trademarks used in this document are acknowledged as being
- owned by their respective owners.
-
- This document is copyright (C) 1996 Daniel Barlow
- <tt/<dan@detached.demon.co.uk>/ It may be reproduced and
- distributed in whole or in part, in any medium physical or electronic,
- as long as this copyright notice is retained on all copies. Commercial
- redistribution is allowed and encouraged; however, the author would
- like to be notified of any such distributions.
-
- All translations, derivative works, or aggregate works incorporating
- any Linux HOWTO documents must be covered under this copyright notice.
- That is, you may not produce a derivative work from a HOWTO and impose
- additional restrictions on its distribution. Exceptions to these rules
- may be granted under certain conditions; please contact the Linux
- HOWTO coordinator at the address given below.
-
- In short, we wish to promote dissemination of this information through
- as many channels as possible. However, we do wish to retain copyright
- on the HOWTO documents, and would like to be notified of any plans to
- redistribute the HOWTOs.
-
- If you have questions, please contact Greg Hankins, the Linux HOWTO
- coordinator, at <tt/gregh@sunsite.unc.edu/ via email.
-
- <sect>Index
-
- <p>Entries starting with a non-alphabetical character are listed in ASCII
- order.
-
- <itemize>
-
-
- <item> <tt/-fwritable-strings/ <ref id="index.39" name="39"> <ref id="index.56" name="56">
- <item> /lib/cpp <ref id="index.16" name="16">
- <item> a.out <ref id="index.1" name="1">
- <item> <tt/ar/ <ref id="index.10" name="10">
- <item> <tt/as/ <ref id="index.8" name="8">
- <item> <asm/*.h> <ref id="index.19" name="19">
- <item> <tt/atoi()/ <ref id="index.40" name="40">
- <item> <tt/atol()/ <ref id="index.41" name="41">
- <item> binaries too big <ref id="index.63" name="63"> <ref id="index.65" name="65"> <ref id="index.77" name="77">
- <item> chewing gum <ref id="index.3" name="3">
- <item> <tt/cos()/ <ref id="index.68" name="68">
- <item> debugging <ref id="index.59" name="59">
- <item> <tt/dlopen()/ <ref id="index.82" name="82">
- <item> <tt/dlsym()/ <ref id="index.83" name="83">
- <item> documentation <ref id="index.4" name="4">
- <item> EINTR <ref id="index.52" name="52">
- <item> elf <ref id="index.0" name="0"> <ref id="index.71" name="71">
- <item> <tt/execl()/ <ref id="index.57" name="57">
- <item> <tt/fcntl/ <ref id="index.47" name="47">
- <item> <tt/FD_CLR/ <ref id="index.44" name="44">
- <item> <tt/FD_ISSET/ <ref id="index.45" name="45">
- <item> <tt/FD_SET/ <ref id="index.43" name="43">
- <item> <tt/FD_ZERO/ <ref id="index.46" name="46">
- <item> <tt/file/ <ref id="index.2" name="2">
- <item> <float.h> <ref id="index.20" name="20">
- <item> gcc <ref id="index.6" name="6">
- <item> <tt/gcc -fomit-frame-pointer/ <ref id="index.61" name="61">
- <item> <tt/gcc -g/ <ref id="index.60" name="60">
- <item> gcc -v <ref id="index.14" name="14">
- <item> gcc, bugs <ref id="index.15" name="15"> <ref id="index.28" name="28"> <ref id="index.29" name="29"> <ref id="index.84" name="84">
- <item> gcc, flags <ref id="index.13" name="13"> <ref id="index.25" name="25"> <ref id="index.26" name="26">
- <item> gdb <ref id="index.64" name="64">
- <item> header files <ref id="index.17" name="17">
- <item> interrupted system calls <ref id="index.51" name="51">
- <item> <tt/ld/ <ref id="index.9" name="9">
- <item> <tt/LD_*/ environment variables <ref id="index.80" name="80">
- <item> ldd <ref id="index.81" name="81">
- <item> libc <ref id="index.7" name="7">
- <item> <tt/libg.a/ <ref id="index.62" name="62">
- <item> libgcc <ref id="index.79" name="79">
- <item> <limits.h> <ref id="index.21" name="21">
- <item> lint <ref id="index.58" name="58">
- <item> <linux/*.h> <ref id="index.18" name="18">
- <item> manual pages <ref id="index.5" name="5">
- <item> <tt/<math.h>/ <ref id="index.70" name="70">
- <item> maths <ref id="index.69" name="69">
- <item> <tt/mktemp()/ <ref id="index.55" name="55">
- <item> optimisation <ref id="index.27" name="27">
- <item> QMAGIC <ref id="index.76" name="76">
- <item> segmentation fault <ref id="index.30" name="30"> <ref id="index.54" name="54">
- <item> segmentation fault, in GCC <ref id="index.33" name="33">
- <item> select() <ref id="index.50" name="50">
- <item> <tt/SIGBUS/ <ref id="index.34" name="34">
- <item> <tt/SIGEMT/ <ref id="index.35" name="35">
- <item> <tt/SIGIOT/ <ref id="index.36" name="36">
- <item> SIGSEGV <ref id="index.31" name="31"> <ref id="index.53" name="53">
- <item> SIGSEGV, in gcc <ref id="index.32" name="32">
- <item> <tt/SIGSYS/ <ref id="index.38" name="38">
- <item> <tt/SIGTRAP/ <ref id="index.37" name="37">
- <item> <tt/sin()/ <ref id="index.67" name="67">
- <item> soname <ref id="index.73" name="73">
- <item> <tt/sprintf()/ <ref id="index.42" name="42">
- <item> statically linked binaries, unexpected <ref id="index.66" name="66"> <ref id="index.78" name="78">
- <item> <stdarg.h> <ref id="index.23" name="23">
- <item> <stddef.h> <ref id="index.24" name="24">
- <item> <tt/strings/ <ref id="index.11" name="11">
- <item> <tt><sys/time.h></tt> <ref id="index.48" name="48">
- <item> <tt><unistd.h></tt> <ref id="index.49" name="49">
- <item> <varargs.h> <ref id="index.22" name="22">
- <item> version numbers <ref id="index.12" name="12"> <ref id="index.74" name="74">
- <item> weird things <ref id="index.72" name="72">
- <item> ZMAGIC <ref id="index.75" name="75">
- </itemize>
-
- <!-- ************** E N D O F G C C - H O W T O **************** -->
- </article>
-