IRIX 6.5 » Books » Developer »
MIPSpro N32/64 Compiling and Performance Tuning Guide
(document number: 007-2360-010 / published: 2003-08-15)
table of contents | additional info | download find in page
Chapter 2. Using the MIPSpro Compiler System
This chapter provides information about the MIPSpro compiler system
and describes the object file format and dynamic linking. Specifically, this
chapter covers the topics listed below:
“Selecting Compilation Modes”, explains how to specify
n32, 64, or o32 compilation mode and how to set up a compiler.defaults
file.
“Object File Format and Dynamic Linking”, discusses object files,
including executable and linking format, dynamic shared objects, and position-independent
code.
“Source File Considerations”, explains source file
naming conventions and the procedure for including header files.
“Compiler Drivers”, lists and explains general
compiler-driver options.
“Linking”, explains how to link
programs manually (using ld or a compiler) and how to compile
multilanguage programs. It also covers Dynamic Shared Objects (DSOs) and how
to link them into a program.
“Getting Information About Object Files”, provides information
on how to use the object file tools to analyze object files.
“Using the Archiver to Create Libraries”, explains how to use
the archiver, ar.
“Debugging”, describes the compiler-driver
options for debugging.
For further information on DSOs, see Chapter 3, “Using Dynamic Shared Objects”.
For information on optimizing your program, see Chapter 4, “Optimizing Program Performance”.
Selecting Compilation Modes
You can select compilation modes by explicitly specifying them on a
compiler command line, defining an environment variable, or specifying a file
that defines some of the defaults. This section covers the following topics:
Using a Defaults Specification File
You can set the following options without explicitly specifying them
every time you invoke a compiler. The Application Binary Interface (ABI)
The instruction set architecture (ISA)
The processor type
The optimization level
The IEEE arithmetic level
Just set the environment variable COMPILER_DEFAULTS_PATH
to a colon-separated list of paths designating where the compiler is to look
for the compiler.defaults file. If no compiler.defaults
file is found, or if the environment variable is not set, the
compiler looks in /etc/compiler.defaults
. If this file is not found, the compiler resorts to the built-in
defaults.
The compiler.defaults file contains a
-DEFAULT: option group specifier that
specifies the default ABI, ISA, and processor. The compiler issues a warning
if you specify anything other than -DEFAULT:
option in the compiler.defaults file.
The format of the -DEFAULT: option
group is specified in each of the language manuals.
Use the -show_defaults
option to print the compiler.defaults being used (if
any) and their values. This option is for diagnostic purposes and does not
compile any code.
Explicit command-line options override all compiler default settings,
and the SGI_ABI environment variable overrides the ABI
setting in the compiler.defaults file. The following
command overrides a compiler.defaults file that sets
-DEFAULT:abi=n32:isa=mips4:proc=r10k and compiles -64
-mips4 -r10000:
The following command overrides the compiler.defaults
file and sets the ABI to -o32 and the ISA to
-mips2. The -o32 ABI supports only
-mips2 (the default) and -mips1 compilations.
The processor type is ignored by -o32 compilations.
Refer to the release notes and man pages for your compiler for information
about default settings. Refer to the man pages for your command-line options.
Setting an Environment Variable
You can set an environment variable (shown in Table 2-1)
to specify the compilation mode to use.
Table 2-1. Compilation Mode Environment Variable Specifications
Environment Variable
| Description
|
|---|
setenv SGI_ABI -n32
| Sets the environment for new 32-bit
compilation.
| setenv SGI_ABI -64
| Sets the environment for 64-bit compilation.
| setenv SGI_ABI -o32
| Sets the environment for old 32-bit
compilation.
|
How do you know when to use -n32 or -64
to compile your code? Compile -n32 when you
want:
To generate smaller executables than -64.
Executables to have fewer data cache misses and less memory
paging than -64.
To access 64 bits: long long and
INTEGER*8 are 64-bits long.
Compile -64 if your program:
Object File Format and Dynamic Linking
This section describes how the compiler system:
Uses executable and linking format (ELF) for object
files.
Uses shared libraries called dynamic shared
objects (DSOs).
Creates position-independent code (PIC) by
default to support dynamic linking.
Executable and Linking Format
The compiler system produces ELF object files. ELF is the format specified
by the System V Release 4 Applications Binary Interface (the SVR4 ABI). ELF
provides support for DSOs, described in the following section.
Types of ELF object files are as follows:
Relocatable files, which contain code and data in a format
suitable for linking with other object files to make a shared object or executable.
DSOs, which contain code and data suitable for dynamic linking.
Relocatable files may be linked with DSOs to create a dynamic executable.
At run time, the run-time linker combines the executable and DSOs to produce
a process image.
Executable files ready for execution. They may or may not
be dynamically linked.
You can use this version of the compiler system to construct ABI-compliant
executables that run on any operating system supporting the MIPS ABI. Be careful
to avoid referencing symbols that are not defined as part of the MIPS ABI
specification. For more information, see the following publications:
System V Applications Binary Interface--Revised
First Edition. Prentice Hall, ISBN 0-13-880410-9
System V Application Binary Interface MIPS Processor
Supplement. Prentice Hall, ISBN 0-13-880170-3.
IRIX uses shared objects called Dynamic Shared Objects, or DSOs. The object code
of a DSO is position-independent code (PIC), which can be mapped into the
virtual address space of several different processes at once. DSOs are loaded
at run time instead of at linking time by the run-time loader, rld
. As is true of static shared libraries, the code for DSOs is not
included in executable files; thus, executables built with DSOs are smaller
than those built with non-shared libraries, and multiple programs may use
the same DSO at the same time. For more information on DSOs, see Chapter 3, “Using Dynamic Shared Objects”.
Position-Independent Code
Dynamic linking requires that all object code used in the executable
be position-independent code (PIC). For source files in high-level languages,
you just need to recompile to produce PIC. Assembly language files must be
modified to produce PIC; see the
MIPSpro Assembly Language Programmer's Guide for details.
Position-independent code satisfies references indirectly by using a global offset table
(GOT), which allows code to be relocated simply by updating the GOT. Each
executable and each DSO has its own GOT. For more information on DSOs, see Chapter 3, “Using Dynamic Shared Objects”.
The compiler system produces PIC by default when compiling higher-level
language files. All of the standard libraries are provided as DSOs and therefore
contain PIC code; if you compile a program into non-PIC, you will be unable
to use those DSOs. One of the few reasons to compile non-PIC is to build a
device driver, which does not rely on standard libraries.
Source File Considerations
This section describes conventions for naming source files and including
header files.
Source File Naming Conventions
Each compiler driver recognizes the type of an input file by the suffix
assigned to the file name. Table 2-2 describes the possible file name suffixes.
Table 2-2. Driver Input File Suffixes
Suffix
| Description
|
|---|
.s
| Assembly source
| .i
| Preprocessed source code in the language
of the processing driver
| .c
| C source
| .C,
.c++, .CC,
.cc,
.CPP, .cpp,
.CXX,
.cxx
| C++ source
| .f.F
.for.FOR
.f.f90.F90
| FORTRAN 77 source
Fortran
90 source
| .p
| Pascal source
| .o
| Object file
| .a
| Object library archive
| .so
| DSO library
|
The following example compiles preprocessed source code:
The f77 compiler also assumes the file has already
been preprocessed (because the suffix is .i) and therefore
does not invoke the preprocessor.
Header files, also called include
files, contain code that is inserted into the program.
C header files contain information about the libraries with which they
are associated. They define such things as data types, data structures, symbolic
constants, and prototypes for functions exported by the library. To use those
definitions without having to type them into each of your source files, you
can use the #include directive to tell the macro preprocessor
to include the complete text of the given header file in the current source
file. When you include header files in your source files, you can specify
definitions conveniently and consistently in each source file that uses any
of the library routines.
Fortran include files are specified by the INCLUDE
line, which names a file containing source text. That source text is substituted
for the INCLUDE line during compilation. The source text
can be any Fortran code that is valid in the context of its location in the
program.
By convention, C header file names have a .h suffix.
Each programming language handles these files the same way, via the macro
preprocessor. For example, the stdio.h
header file describes, among other things, the data types of the parameters
required by the C language printf() function.
For detailed information about standard header files and libraries,
see the International Standard ISO/IEC, Programming languages--C,
9899, 1990. Also see “Using Typedefs ” in Chapter 6, for
information about the inttypes.h header file.
The
#include directive in C and C++ or the INCLUDE
line in Fortran tells the preprocessor to replace the directive or line with
the text of the indicated header file. The usual way to specify a header file
in C is with the following line:
The filename is the name of the header file
to be included. The angle brackets (< >) surrounding
the filename tell the macro preprocessor to search for the specified file
only in directories specified by command-line options and in the default header
file directory (/usr/include and /usr/include/CC
for C++).
In another specification format, filename
is given between double quotation marks (“ ”).
In this case, the macro preprocessor searches for the specified header file
in the current directory first (that is, the directory containing the main
program file). If the preprocessor does not find the requested file, it searches
the other directories as in the angle-bracket specification.
In Fortran, included text is specified as follows:
In an f90(1) program, the directory containing
filename can be specified on the command line with the
-I option. In an f77(1) program,
filename must be in the current directory.
Creating a Header File for Multiple Languages
A single header file can contain definitions for multiple languages;
this setup allows you to use the same header file for all programs that use
a given library, no matter what language those programs are in.
To set up a shareable header file, create a .h
file and enter the definitions for the various languages as follows:
#ifdef _LANGUAGE_C
C Definitions
#endif
#ifdef _LANGUAGE_C_PLUS_PLUS
C++ definitions
#endif
#ifdef _LANGUAGE_FORTRAN
Fortran definitions
#endif |
 | Note: You must specify _LANGUAGE_ before the language
name. To indicate C++ definitions, you must use _LANGUAGE_C_PLUS_PLUS
, not _LANGUAGE_C++.
|
You can specify language definitions in any order.
Using Precompiled Headers in C and C++
This section describes the precompiled header mechanism that is available
with the n32 and 64-bit C and C++ compilers. This mechanism is also available
for C++ (but not C) in o32-bit mode.
This section contains the following topics:
About Precompiled Headers
The precompiled header (PCH) file mechanism is available through the
C and C++ compilers front ends: fec and fecc.
Use PCH to avoid recompiling a set of header files. This is particularly useful
when your header files introduce many lines of code, and the primary source
files that included them are relatively small.
In effect, fec and fecc take a
snapshot of the state of the compilation at a particular point and write it
to a file before completing the compilation. When you recompile the same source
file or another file with the same set of header files, the PCH mechanism
recognizes the snapshot point, verifies that the corresponding PCH file is
usable, and reads it back in.
The PCH mechanism can give you a dramatic improvement in compile-time
performance. The trade-off is that PCH files may take a lot of disk space.
Automatic Precompiled Header Processing
This section covers the following topics:
You can enable precompiled header processing by using the
-pch option (-Wf, -pch in 32-bit mode) on the
command line. With the PCH mechanism enabled, fec or
fecc searches for a qualifying PCH file to read in or creates one
for use on a subsequent compilation.
The PCH file contains a snapshot of all the code preceding the header
stop point. The header stop point is typically the first token in the primary
source file that does not belong to a preprocessing directive. The header
stop point can also be specified directly by inserting a #pragma
hdrstop. For example, consider the following C++ code:
#include “xxx.h”
#include “yyy.h”
int i; |
In this case, the header stop point is int i (the
first non-preprocessor token), and the PCH file will contain a snapshot reflecting
the inclusion of xxx.h and yyy.h.
If the first non-preprocessor token or the #pragma hdrstop
appears within a #if block, the header stop point is the
outermost enclosing #if. For example, consider the following
C++ code:
#include “xxx.h”
#ifndef YYY_H
#define YYY_H 1
#include “yyy.h”
#endif
#if TEST
int i;
#endif |
In this case, the first token that does not belong to a preprocessing
directive is again int i, but the header stop point is
the start of the #if block containing the int
. The PCH file reflects the inclusion of xxx.h
and conditionally the definition of YYY_H and inclusion
of yyy.h. The file does not contain the state produced
by #if TEST.
PCH File Requirements
A PCH file is produced only if the header stop point and the code preceding
it (generally the header files themselves) meet the following requirements:
The header stop point must appear at file scope; it may not
be within an unclosed scope established by a header file. For example, a PCH
file is not created in the following case:
// xxx.h
class A {
// xxx.C
#include "xxx.h"
int i; }; |
The header stop point cannot be inside a declaration started
within a header file, and it cannot be part of a declaration list of a linkage
specification. For example, a PCH file is not created in the following case:
// yyy.h
static
// yyy.C
#include "yyy.h"
int i; |
In this case, the header stop point is int i, but
since it is not the start of a new declaration, a PCH file is not created
The header stop point cannot be inside a #if
block or a #define started within a header file.
The processing preceding the header stop must not have produced
any errors. (Note that warnings and other diagnostics are not reproduced when
the PCH file is reused.)
References to predefined macros __DATE__
or __TIME__ cannot be included.
Use of the #line preprocessing directive
cannot be included.
#pragma no_pch cannot be included.
Reusing PCH Files
When a precompiled header file is produced, in addition to the snapshot
of the compiler state, it contains some information that can be checked to
determine under what circumstances it can be reused. This information includes
the following:
The compiler version, including the date and time the compiler
was built.
The current directory (in other words, the directory in which
the compilation is occurring).
The command-line options.
The initial sequence of preprocessing directives from the
primary source file, including #include directives.
The date and time of the header files specified in
#include directives.
This information comprises the PCH prefix. The prefix information of
a given source file can be compared to the prefix information of a PCH file
to determine whether or not the latter is applicable to the current compilation.
For example, consider the following C++ code:
// a.C
#include "xxx.h"
... // Start of code
// b.C
#include "xxx.h"
... // Start of code |
When you compiled a.C with the -pch
option, the PCH file a.pch is created. When you compile
b.C (or recompile a.C), the prefix section
of a.pch is read in for comparison with the current source
file. If the command line options are identical and xxx.h
has not been modified, fec or fecc reads
in the rest of a.pch rather than opening xxx.h
and processing it line by line. This establishes the state for
the rest of the compilation.
It may be that more than one PCH file is applicable to a given compilation.
If so, the largest (in other words, the one representing the most preprocessing
directives from the primary source file) is used. For instance, consider a
primary source file that begins with the following code:
#include "xxx.h"
#include "yyy.h"
#include "zzz.h" |
If one PCH file exists for xxx.h and a second for
xxx.h and yyy.h, the latter will be selected
(assuming both are applicable to the current compilation). After the PCH file
for the first two headers is read in and the third is compiled, a new PCH
file for all three headers may be created.
When a precompiled header file is created, it takes the name of the
primary source file, with the suffix replaced by pch. Unless
-pch_dir is specified, the PCH file is created in the directory
of the primary source file.
When a precompiled header file is created or used, a message similar
to the following is issued:
"test.C": creating precompiled header file "test.pch" |
Obsolete File Deletion Mechanism
In automatic mode (when
-pch is used), the front end considers a PCH file obsolete and deletes
it under the following circumstances:
The file is based on at least one out-of-date header file
but is otherwise applicable for the current compilation.
The file has the same base name as the source file being compiled
(for example, xxx.pch and xxx.C)
but is not applicable for the current compilation (for example, because of
different command-line options).
You must manually clean up any other PCH file.
Support for PCH processing is not available when multiple source files
are specified in a single compilation. If the command line includes a request
for precompiled header processing and specifies more than one primary source
file, an error is issued and the compilation is aborted.
Other Ways to Control Precompiled Headers
You can use the following ways to control and tune how precompiled headers
are created and used:
You can insert a #pragma hdrstop in the
primary source file at a point prior to the first token that does not belong
to a preprocessing directive. Thus you can specify where the set of header
files subject to precompilation ends, as in the following:
#include "xxx.h"
#include "yyy.h"
#pragma hdrstop
#include "zzz.h" |
In this case, the precompiled header file includes the processing state
for xxx.h and yyy.h but not
zzz.h. This is useful if you decide that the information added
by what follows the #pragma hdrstop does not justify the
creation of another PCH file.
You can use a #pragma no_pch to suppress
the precompiled header processing for a given source file.
You can use the command-line option -pch_dir
directoryname to specify the directory in which to search for
and create a PCH file.
The relative overhead incurred in writing out and reading in a precompiled
header file is quite small for reasonably large header files.
In general, writing out a precompiled header file does not cost much,
even if it does not end up being used, and, if it is used, it almost always
produces a significant speedup in compilation. The problem is that the precompiled
header files can be quite large (from a minimum of about 250 Kbytes to several
Mbytes or more), and so you probably do not want many of them sitting around.
You can see that, despite the faster recompilations, precompiled header
processing is not likely to be justified for an arbitrary set of files with
nonuniform initial sequences of preprocessing directives. The greatest benefit
occurs when a number of source files can share the same PCH file. The more
sharing, the less disk space is consumed. With sharing, the disadvantage of
large precompiled header files can be minimized without giving up the advantage
of a significant speedup in compilation times.
To take full advantage of header file precompilation, you should reorder
the #include sections of your source files and group the
#include directives within a commonly used header file.
The fecc source provides an example of how this can
be done. A common idiom is the following:
#include "fe_common.h"
#pragma hdrstop
#include ... |
In this example, fe_common.h pulls in, directly
and indirectly, a few dozen header files. The #pragma hdrstop
is inserted to get better sharing with fewer PCH files. The PCH file produced
for fe_common.h is slightly over a megabyte in size.
Another example, used by the source files involved in declaration processing,
is the following:
#include "fe_common.h"
#include "decl_hdrs.h"
#pragma hdrstop
#include ... |
decl_hdrs.h pulls in another dozen header files,
and a second, somewhat larger, PCH file is created. In all, the fifty-odd
source files of fecc share just six precompiled header
files. If disk space is at a premium, you can decide to make fe_common.h
pull in all the header files used. In that case, a single PCH
file can be used in building fecc.
Different environments and different projects have different needs.
You should, however, be aware that making the best use of the precompiled
header support will require some experimentation and probably some minor changes
to your source code.
The driver commands cc(1),
CC(1), f90(1), and
f77(1) call subsystems that compile, optimize, assemble, and link your
programs. This section describes the default behavior for compiler drivers.
At compilation time, you can select one or more options that affect
a variety of program development functions, including debugging, profiling,
and optimizing. You can also specify the names assigned to output files. Note
that some options have default values that apply if you do not specify them.
When you invoke a compiler driver with source files as arguments, the
driver calls other commands that compile your source code into object code.
It then optimizes the object code (if requested to do so) and links together
the object files, the default libraries, and any other libraries you specify.
Given a source file foo.c, the default name for
the object file is foo.o. The default name for an executable
file is a.out. The following example compiles source
files foo.c and bar.c with the default
options:
This example produces two object files, foo.o and
bar.o, and links them with the default C library, libc
, to produce an executable called a.out.
 | Note: If you compile a single source directly to an executable, the
compiler does not create an object file.
|
The command-line options for MIPSpro compiler drivers are listed and
explained in the man page for your compiler.
The linker, ld, combines one or more object files
and libraries (in the order specified) into one executable file, performing
relocation, external symbol resolutions, and all other required processing.
Unless directed otherwise, the linker names the executable file
a.out. See the ld(1) man page for
complete information on the linker.
This section summarizes the functions of the linker. It also covers
how to link a program manually (without using a compiler driver) and how to
compile multilanguage programs. Specifically, this section describes:
Usually the compiler invokes the linker as the final step in compilation.
If object files produced by previous compilations exist and you want to link
them, invoke the linker by using a compiler driver instead of calling
ld directly. Just pass the object file names to the compiler driver
in place of source file names. If the original source files are in one language,
invoke the associated driver and specify the list of object files.
In some cases you may need to invoke ld directly,
such as when you are building a shared object or doing special linking not
supported by compiler drivers (such as building an embedded system).
For information on the options available to the linker, see the
ld man page.
The following command tells the linker to search for the DSO libcurses.so in the directory
/usr/lib. If it does not find that DSO, the linker then looks for
libcurses.a in /lib. The linker does not look
for DSOs in /usr/local/lib, so do not put shared objects
there.
% ld foiled.o again.o -lcurses |
If found in any of these places, the DSO or library is linked with the
objects foiled.o and again.o; if
they are not found, an error is generated.
Linking Assembly Language Programs
The assembler driver, as, does not run the linker.
To link a program written in assembly language, use one of these procedures:
Assemble and link using one of the other driver commands (
cc, for example). The .s suffix of the assembly
language source file causes the driver to invoke the assembler.
Assemble the file using as. Then link the
resulting object file with the ld command.
The linker processes its arguments from left to right as they appear
on the command line. Arguments to
ld can be object files, DSOs, or libraries. Be sure to list object
files before DSOs.
When ld reads a DSO, it adds all the symbols from
that DSO to a cumulative symbol table. If it encounters a symbol that is already
in the symbol table, it does not change the symbol table entry. If you define
the same symbol in more than one DSO, only the first definition is used.
When ld reads an archive, usually denoted by a file
name ending in .a, it uses only the object files from
that archive that can resolve currently unresolved symbol references. When
a symbol is referred to but not defined in any of the object files that have
been loaded so far, it is called unresolved.
Once a library has been searched in this way, it is never searched again.
Therefore, place libraries after object files on the command line in order
to resolve as many references as possible. If a symbol is already in the cumulative
symbol table from having been encountered in a DSO, its definition in any
subsequent archive or DSO is ignored.
Specifying Libraries and DSOs
You can specify libraries and DSOs either by explicitly stating a path
name or by using the library search rules. To specify a library or DSO by
path (either relative to the current directory or absolute), simply include
that path on the command line:
% ld myprog.o /usr/lib/libc.so.1 mylib.so |
 | Note:
libc.so.1 is the name
of the standard C DSO, replacing the older libc.a. Similarly,
libX11.so.1 is the X11 DSO. Most other DSOs are simply named
name.so, without a .1 extension.
|
To use the linker's library search rules, specify the library with the
-lname option:
When the -lmylib argument is processed,
ld searches for a file called libmylib.so.
If it cannot find libmylib.so in a given directory, it
tries to find libmylib.a there; if it cannot find that
either, it moves on to the next directory in its search order.
The default search order uses the path appropriate to the compilation
mode:
For -n32, the default search order is
/usr/lib32:/lib32.
For -64, the default search order is
/usr/lib64:/lib64.
For -o32, the default search order is
/usr/lib:/lib.
If ld is invoked from one of the compiler drivers,
all -L and -nostdlib options are moved
up on the command line so that they appear before any -l
name options. For example, consider the command:
% cc file1.o -lm -L mydir |
This command invokes, at the linking stage of compilation, the following:
% ld -L mydir file1.o -lm |
 | Note: There are three different kinds of files that contain object code
files: non-shared libraries, PIC archives, and DSOs. Non-shared libraries
are the old-style library. PIC archives are the default, built using
ar from .o files compiled with -KPIC
(the default option). They can be linked with other PIC files.
DSOs are built from PIC .o files by using ld
-shared; see Chapter 3, “Using Dynamic Shared Objects”, for details.
|
If the linker tells you that a reference to a certain function is unresolved,
check that function's man page to find out which library the function is in.
If it is not in one of the standard libraries that ld links
in by default, you may need to specify the appropriate library on the command
line. For an alternative method of finding out where a function is defined,
see “Finding an Unresolved Symbol with ld”.
 | Note: Simply including the header file associated with a library routine
is not enough; you must also specify the library when linking (unless it is
a standard library). No automatic connection exists between header files and
libraries. Header files only give prototypes for library routines, not the
library code itself.
|
To link a sample program foo.c with the math DSO,
libm.so, enter:
To specify the appropriate DSOs for a graphics program foogl.c
, enter:
 | Note: When linking, you must specify the source file name before the
linker options.
|
Linking to Previously Built Dynamic Shared Objects
This section describes how to link your source files with previously
built DSOs; for more information about how to build your own DSOs, see Chapter 3, “Using Dynamic Shared Objects”.
To build an executable that uses a DSO, simply call a compiler driver.
For instance, the following command links the resulting object file,
needle.o, with the previously built DSO, libthread.so
, and the standard C DSO, libc.so.1, if available.
If no libthread.so exists, but a PIC archive named
libthread.a exists, that archive is used with libc.so.1
. So you still get dynamic (run-time) linking. Note that even
.a libraries contain position-independent code by default, though
it is also possible to build non-shared .a libraries
that do not contain PIC.
Linking Multilanguage Programs
The source language of the main program may differ from that of a subprogram.
Follow the steps below to link multilanguage programs. For an illustration
of the process, see Figure 2-1.
Compile object files from the source files of
each language separately by using the -c option.
For example, if the source consists of a Fortran main program,
main.f, and two files of C functions, more.c
and rest.c, use the commands:
% cc -c more.c rest.c
% f77 -c main.f |
These commands produce the object files main.o,
more.o, and rest.o.
Use the compiler associated with the language of
the main program to link the objects:
% f77 main.o more.o rest.o |
The compiler drivers supply the default set of libraries necessary to
produce an executable from the source of the associated language. However,
when producing executables from source code in several languages, you may
need to specify the default libraries explicitly for one or more of the languages.
For instructions on specifying libraries, see “Linking Libraries”.
 | Note: Use caution when passing pointers and longs between languages,
since some languages use different type sizes and structures for data types.
|
For specific details about compiling multilanguage programs, see the
programming guides for the appropriate languages.
Finding an Unresolved Symbol with ld
You can use
ld to locate unresolved symbols. For example, suppose you are compiling
a program, and
ld tells you that you are using an unresolved symbol. You may not
know where the unresolved symbol is referenced.
To find the unresolved symbol, enter:
% ld -ysymbol file1 ... filen |
You can also enter:
The output lists the source file that references symbol
.
Getting Information About Object Files
Several tools provide information on object files and are described
in the following sections:
dis disassembles an object file
into machine instructions.
dwarfdump lists headers, tables, and other
selected parts of a DWARF-format object file or archive file.
elfdump lists the contents, including the
symbol table and header information, of an ELF-format object file.
file provides descriptive information on
the properties of a file.
nm lists symbol
table information.
size prints the size of each section of
an object file.
strip removes symbol table and relocation bits.
You can trace system call and scheduling activity by using the
par command. For more information, see the
par(1) man page.
Disassembling Object Files with dis
The dis tool disassembles object files
into machine instructions. You can disassemble an object, archive library,
or executable file.
See the dis(1) man page for descriptions
of its options.
Listing Parts of DWARF Object Files with dwarfdump
The dwarfdump tool provides debugging information
from selected parts of DWARF symbolic information in an ELF object file. For
more information on DWARF, including option descriptions, see the dwarfdump(1) and dwarf(4)
man pages.
Listing Parts of ELF Object Files and Libraries with elfdump
The elfdump tool lists headers, tables, and other
selected parts of an ELF-format object file or archive file. See the elfdump(1) man page for option descriptions and other
information.
Determining File Type with file
The file tool lists the properties of program source,
text, object, and other files. This tool attempts to identify the contents
of files using various heuristics. It is not exact and often erroneously recognizes
command files as C programs. For more information, including option descriptions,
see the file(1) man page.
Listing Symbol Table Information: nm
The nm
tool lists symbol table information for object files and archive
files. To get XPG4 (X/Open Portability Group) format, set the environment
variable, _XPG in your environment.
For more information and option descriptions, see the
nm(1) man page.
This example demonstrates how to obtain a symbol table listing. Consider
the following program, tnm.c:
#include <stdio.h>
#include <math.h>
#define LIMIT 12
int unused_item = 14;
double mydata[LIMIT];
main()
{
int i;
for(i = 0; i < LIMIT; i++) {
mydata[i] = sqrt((double)i);
}
return 0;
} |
Compile the program into an object file by entering:
To obtain symbol table information for the object file tnm.o
in BSD format, use the nm -B command:
0000000000 T main
0000000000 B mydata
0000000000 U sqrt
0000000000 D unused_item
0000000000 N _bufendtab |
To obtain symbol table information for the object file tnm.o
in SVR4 format, use the nm command without
any options:
Symbols from tnm.o:
[Index] Value Size Class Type Section Name
[0] | 0| |File |ref=4 |Text | tnm.c
[1] | 0| |Proc |end=3 int |Text | main
[2] | 116| |End |ref=1 |Text | main
[3] | 0| |End |ref=0 |Text | tnm.c
[4] | 0| |File |ref=6 |Text | /usr/include/math.h
[5] | 0| |End |ref=4 |Text | /usr/include/math.h
[6] | 0| |Global | |Data | unused_item
[7] | 0| |Global | |Bss | mydata
[8] | 0| |Proc |ref=1 |Text | main
[9] | 0| |Proc | |Undefined| sqrt
[10] | 0| |Global | |Undefined| _gp_disp |
Determining Section Sizes with size
The size tool prints information about
the sections (such as text, rdata,
and sbss) of the specified object or archive files. The elf(4) man page describes the format of these sections,
and the size(1) man page describes the options
accepted by the size command.
An example of the
size command and the listings produced follows:
% size a.out
Section Size Physical Virtual
Address Address
.interp 21 268435856 268435856
.MIPS.options 104 268435880 268435880
.dynamic 464 268435984 268435984
.liblist 20 268436448 268436448
.MIPS.symlib 30 268436468 268436468
.msym 240 268436500 268436500
.dynstr 312 268436744 268436744
.dynsym 720 268437056 268437056
.hash 256 268437776 268437776
.MIPS.stubs 56 268438032 268438032
.text 460 268438088 268438088
.init 24 268438548 268438548
.data 17 268505088 268505088
.sdata 8 268505108 268505108
.got 112 268505120 268505120
.bss 36 268505232 268505232 |
Removing Symbol Table and Relocation Bits with strip
The strip tool removes symbol table and
relocation bits that are attached to the assembler and loader. Use
strip to save space after you debug a program. The effect of
strip is the same as that of using the -s option
to ld.
See the strip(1) man page for descriptions
of the options.
Using the .s Assembly Language File
The MIPSpro compilers can produce a .s file rather
than a .o file. The file is produced by specifying the
-S option on the command line instead of the -c
option.
The assembly language file that is produced contains exactly the same
set of instructions that would have been produced in the .o
object file, and inputting the .s file to the assembler
produces an object file with the same instructions that the compiler would
have produced. The .s file is a listing of the instructions,
but does not contain all the object information that a .o
file contains. Therefore, a .o file generated by a
.s file will not be exactly the same as one generated directly by
the compiler and they are not guaranteed to work identically (for example,
reorg_common information is lost).
In addition to the program's instructions, the .s
file contains comments indicating the effects of various optimization transformations
that were made by the compiler.
For details about this file, see the
MIPSpro Assembly Language Programmer's Guide.
Using the Archiver to Create Libraries
An archive library is a file that includes the contents of one or more
object (.o) files. When the linker (ld)
searches for a symbol in an archive library, it loads only that object file
where that symbol was defined (not the entire library) and links it with the
calling program.
The archiver (ar) creates and maintains archive libraries
and has these main functions:
Copying new objects into the library
Replacing existing objects in the library
Moving objects around within the library
Extracting individual objects from the library
Creating a symbol table for the linker to search symbols
The following section explains the syntax of the ar
command and lists some options and examples of how to use it. See the ar(1) man page for details.
To create a new library, libtest.a, and add object
files to it, enter:
% ar -cq libtest.a mcount.o mon1.o string.o |
The -c option suppresses an archiver message during
the creation process. The -q option creates the library
and puts mcount.o, mon1.o, and
string.o into it.
To replace an object file in an existing library, enter:
The -r option replaces mon1.o
in the library libtest.a. If mon1.o
does not already exist in the library libtest.a, it is
added.
 | Note: If you specify the same file twice in an argument list of files
to be added to an archive, that file appears twice in the archive.
|
The compiler system provides the dbx(1)
debugging tool, which is described in detail in the
dbx User's Guide, and cvd(1),
which is part of the ProDev WorkShop suite of performance tools. For information
about the WorkShop tools, see the ProDev
WorkShop: Overview.
Before using one of the debuggers, specify the -g
driver option to produce executables containing information that the debugger
can use (see the dbx(1) or cvd
man page).
MIPSpro N32/64 Compiling and Performance Tuning Guide
(document number: 007-2360-010 / published: 2003-08-15)
table of contents | additional info | download
Front Matter
New Features in This Manual
About This Guide
Chapter 1. About the MIPSpro Compiler System
Chapter 2. Using the MIPSpro Compiler System
Chapter 3. Using Dynamic Shared Objects
Chapter 4. Optimizing Program Performance
Chapter 5. Coding for 64-Bit Programs
Chapter 6. Porting Code to N32 and 64-Bit SGI Systems
Index
home/search |
what's new |
help
|