BFD is a package which allows applications to use the same routines to operate on object files whatever the object file format. A new object file format can be supported simply by creating a new BFD back end and adding it to the library.
BFD is split into two parts: the front end, and the back ends (one for each object file format).
One spur behind BFD was the desire, on the part of the GNU 960 team at Intel Oregon, for interoperability of applications on their COFF and b.out file formats. Cygnus was providing GNU support for the team, and was contracted to provide the required functionality.
The name came from a conversation David Wallace was having with Richard Stallman about the library: RMS said that it would be quite hard--David said "BFD". Stallman was right, but the name stuck.
At the same time, Ready Systems wanted much the same thing, but for different object file formats: IEEE-695, Oasys, Srecords, a.out and 68k coff.
BFD was first implemented by members of Cygnus Support; Steve
Chamberlain (sac@cygnus.com
), John Gilmore
(gnu@cygnus.com
), K. Richard Pixley (rich@cygnus.com
)
and David Henkel-Wallace (gumby@cygnus.com
).
To use the library, include `bfd.h' and link with `libbfd.a'.
BFD provides a common interface to the parts of an object file for a calling application.
When an application sucessfully opens a target file (object, archive, or
whatever), a pointer to an internal structure is returned. This pointer
points to a structure called bfd
, described in
`bfd.h'. Our convention is to call this pointer a BFD, and
instances of it within code abfd
. All operations on
the target object file are applied as methods to the BFD. The mapping is
defined within bfd.h
in a set of macros, all beginning
with `bfd_' to reduce namespace pollution.
For example, this sequence does what you would probably expect:
return the number of sections in an object file attached to a BFD
abfd
.
#include "bfd.h" unsigned int number_of_sections(abfd) bfd *abfd; { return bfd_count_sections(abfd); }
The abstraction used within BFD is that an object file has:
Also, BFDs opened for archives have the additional attribute of an index and contain subordinate BFDs. This approach is fine for a.out and coff, but loses efficiency when applied to formats such as S-records and IEEE-695.
When an object file is opened, BFD subroutines automatically determine the format of the input object file. They then build a descriptor in memory with pointers to routines that will be used to access elements of the object file's data structures.
As different information from the the object files is required, BFD reads from different sections of the file and processes them. For example, a very common operation for the linker is processing symbol tables. Each BFD back end provides a routine for converting between the object file's representation of symbols and an internal canonical format. When the linker asks for the symbol table of an object file, it calls through a memory pointer to the routine from the relevant BFD back end which reads and converts the table into a canonical form. The linker then operates upon the canonical form. When the link is finished and the linker writes the output file's symbol table, another BFD back end routine is called to take the newly created symbol table and convert it into the chosen output format.
Information can be lost during output. The output formats
supported by BFD do not provide identical facilities, and
information which can be described in one form has nowhere to go in
another format. One example of this is alignment information in
b.out
. There is nowhere in an a.out
format file to store
alignment information on the contained data, so when a file is linked
from b.out
and an a.out
image is produced, alignment
information will not propagate to the output file. (The linker will
still use the alignment information internally, so the link is performed
correctly).
Another example is COFF section names. COFF files may contain an
unlimited number of sections, each one with a textual section name. If
the target of the link is a format which does not have many sections (e.g.,
a.out
) or has sections without names (e.g., the Oasys format), the
link cannot be done simply. You can circumvent this problem by
describing the desired input-to-output section mapping with the linker command
language.
Information can be lost during canonicalization. The BFD internal canonical form of the external formats is not exhaustive; there are structures in input formats for which there is no direct representation internally. This means that the BFD back ends cannot maintain all possible data richness through the transformation between external to internal and back to external formats.
This limitation is only a problem when an application reads one
format and writes another. Each BFD back end is responsible for
maintaining as much data as possible, and the internal BFD
canonical form has structures which are opaque to the BFD core,
and exported only to the back ends. When a file is read in one format,
the canonical form is generated for BFD and the application. At the
same time, the back end saves away any information which may otherwise
be lost. If the data is then written back in the same format, the back
end routine will be able to use the canonical form provided by the
BFD core as well as the information it prepared earlier. Since
there is a great deal of commonality between back ends,
there is no information lost when
linking or copying big endian COFF to little endian COFF, or a.out
to
b.out
. When a mixture of formats is linked, the information is
only lost from the files whose format differs from the destination.
The greatest potential for loss of information occurs when there is the least overlap between the information provided by the source format, that stored by the canonical format, and that needed by the destination format. A brief description of the canonical form may help you understand which kinds of data you can count on preserving across conversions.
ZMAGIC
file would have both the demand pageable bit and the write protected
text bit set. The byte order of the target is stored on a per-file
basis, so that big- and little-endian object files may be used with one
another.
ld
can
operate on a collection of symbols of wildly different formats without
problems.
Normal global and simple local symbols are maintained on output, so an
output file (no matter its format) will retain symbols pointing to
functions and to global, static, and common variables. Some symbol
information is not worth retaining; in a.out
, type information is
stored in the symbol table as long symbol names. This information would
be useless to most COFF debuggers; the linker has command line switches
to allow users to throw it away.
There is one word of type information within the symbol, so if the
format supports symbol type information within symbols (for example, COFF,
IEEE, Oasys) and the type is simple enough to fit within one word
(nearly everything but aggregates), the information will be preserved.
Go to the first, previous, next, last section, table of contents.