+Fri Nov 5 10:41:07 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * aoutx.h, archive.c, archures.c, bfd.c, cache.c, coffcode.h,
+ core.c, ctor.c, format.c, init.c, libbfd.c, opncls.c, reloc.c,
+ section.c, syms.c, targets.c:
+ Doc cleanup (spelling, punctuation, grammar, formatting).
+ * bfd-in2.h, libbfd.h: Rebuild.
+ * reloc.c (bfd_get_reloc_upper_bound, bfd_canonicalize_reloc,
+ bfd_set_reloc): Moved from bfd.c.
+
Thu Nov 4 14:46:14 1993 John Gilmore (gnu@rtl.cygnus.com)
* bfd-in.h (bfd_get_cacheable, bfd_set_cacheable): New accessors.
* som.c: Add comment about how abort() on corrupt executable is evil.
+Sat Oct 30 12:27:09 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * aoutx.h (aout,slurp_reloc_table): Avoid a goto.
+
Fri Oct 29 16:04:33 1993 David J. Mackenzie (djm@thepub.cygnus.com)
* gen-aout.c, libbfd.c: exit(1) instead of exit(-1).
BFD supports a number of different flavours of a.out format,
though the major differences are only the sizes of the
structures on disk, and the shape of the relocation
- information.
+ information.
- The support is split into a basic support file @code{aoutx.h}
+ The support is split into a basic support file @file{aoutx.h}
and other files which derive functions from the base. One
- derivation file is @code{aoutf1.h} (for a.out flavour 1), and
+ derivation file is @file{aoutf1.h} (for a.out flavour 1), and
adds to the basic a.out functions support for sun3, sun4, 386
and 29k a.out files, to create a target jump vector for a
- specific target.
+ specific target.
This information is further split out into more specific files
- for each machine, including @code{sunos.c} for sun3 and sun4,
- @code{newsos3.c} for the Sony NEWS, and @code{demo64.c} for a
+ for each machine, including @file{sunos.c} for sun3 and sun4,
+ @file{newsos3.c} for the Sony NEWS, and @file{demo64.c} for a
demonstration of a 64 bit a.out format.
- The base file @code{aoutx.h} defines general mechanisms for
- reading and writing records to and from disk, and various
+ The base file @file{aoutx.h} defines general mechanisms for
+ reading and writing records to and from disk and various
other methods which BFD requires. It is included by
- @code{aout32.c} and @code{aout64.c} to form the names
- aout_32_swap_exec_header_in, aout_64_swap_exec_header_in, etc.
+ @file{aout32.c} and @file{aout64.c} to form the names
+ <<aout_32_swap_exec_header_in>>, <<aout_64_swap_exec_header_in>>, etc.
As an example, this is what goes on to make the back end for a
- sun4, from aout32.c
+ sun4, from @file{aout32.c}:
| #define ARCH_SIZE 32
| #include "aoutx.h"
| aout_32_get_reloc_upper_bound
| ...
- from sunos.c
+ from @file{sunos.c}:
| #define ARCH 32
| #define TARGET_NAME "a.out-sunos-big"
| #define VECNAME sunos_big_vec
| #include "aoutf1.h"
- requires all the names from aout32.c, and produces the jump vector
+ requires all the names from @file{aout32.c}, and produces the jump vector
| sunos_big_vec
- The file host-aout.c is a special case. It is for a large set
+ The file @file{host-aout.c} is a special case. It is for a large set
of hosts that use ``more or less standard'' a.out files, and
for which cross-debugging is not interesting. It uses the
standard 32-bit a.out support routines, but determines the
sections, the machine architecture and machine type, and the
entry point address, in a host-dependent manner. Once these
values have been determined, generic code is used to handle
- the object file.
+ the object file.
When porting it to run on a new system, you must supply:
values, plus the structures and macros defined in <<a.out.h>> on
your host system, will produce a BFD target that will access
ordinary a.out files on your host. To configure a new machine
- to use <<host-aout.c>., specify:
+ to use <<host-aout.c>., specify:
| TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
| TDEPFILES= host-aout.o trad-core.o
- in the <<config/mt-XXX>> file, and modify configure.in to use the
+ in the <<config/mt-XXX>> file, and modify @file{configure.in} to use the
<<mt-XXX>> file (by setting "<<bfd_target=XXX>>") when your
configuration is selected.
relocations
DESCRIPTION
- The file @code{aoutx.h} caters for both the @emph{standard}
+ The file @file{aoutx.h} provides for both the @emph{standard}
and @emph{extended} forms of a.out relocation records.
- The standard records are characterised by containing only an
- address, a symbol index and a type field. The extended records
+ The standard records contain only an
+ address, a symbol index, and a type field. The extended records
(used on 29ks and sparcs) also have a full integer for an
- addend.
+ addend.
*/
#define CTOR_TABLE_RELOC_IDX 2
#define howto_table_ext NAME(aout,ext_howto_table)
#define howto_table_std NAME(aout,std_howto_table)
-reloc_howto_type howto_table_ext[] =
+reloc_howto_type howto_table_ext[] =
{
/* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
HOWTO(RELOC_8, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", false, 0,0x000000ff, false),
/* Convert standard reloc records to "arelent" format (incl byte swap). */
reloc_howto_type howto_table_std[] = {
- /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
-HOWTO( 0, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", true, 0x000000ff,0x000000ff, false),
+ /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
+HOWTO( 0, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", true, 0x000000ff,0x000000ff, false),
HOWTO( 1, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", true, 0x0000ffff,0x0000ffff, false),
HOWTO( 2, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", true, 0xffffffff,0xffffffff, false),
-HOWTO( 3, 0, 3, 64, false, 0, complain_overflow_bitfield,0,"64", true, 0xdeaddead,0xdeaddead, false),
-HOWTO( 4, 0, 0, 8, true, 0, complain_overflow_signed,0,"DISP8", true, 0x000000ff,0x000000ff, false),
-HOWTO( 5, 0, 1, 16, true, 0, complain_overflow_signed,0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
-HOWTO( 6, 0, 2, 32, true, 0, complain_overflow_signed,0,"DISP32", true, 0xffffffff,0xffffffff, false),
-HOWTO( 7, 0, 3, 64, true, 0, complain_overflow_signed,0,"DISP64", true, 0xfeedface,0xfeedface, false),
+HOWTO( 3, 0, 4, 64, false, 0, complain_overflow_bitfield,0,"64", true, 0xdeaddead,0xdeaddead, false),
+HOWTO( 4, 0, 0, 8, true, 0, complain_overflow_signed, 0,"DISP8", true, 0x000000ff,0x000000ff, false),
+HOWTO( 5, 0, 1, 16, true, 0, complain_overflow_signed, 0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
+HOWTO( 6, 0, 2, 32, true, 0, complain_overflow_signed, 0,"DISP32", true, 0xffffffff,0xffffffff, false),
+HOWTO( 7, 0, 4, 64, true, 0, complain_overflow_signed, 0,"DISP64", true, 0xfeedface,0xfeedface, false),
+{ -1 },
+HOWTO( 9, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"BASE16", false,0xffffffff,0xffffffff, false),
+HOWTO(10, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"BASE32", false,0xffffffff,0xffffffff, false),
};
+#define TABLE_SIZE(TABLE) (sizeof(TABLE)/sizeof(TABLE[0]))
+
CONST struct reloc_howto_struct *
DEFUN(NAME(aout,reloc_type_lookup),(abfd,code),
bfd *abfd AND
EXT (BFD_RELOC_HI22, 8);
EXT (BFD_RELOC_LO10, 11);
EXT (BFD_RELOC_32_PCREL_S2, 6);
+ EXT (BFD_RELOC_SPARC_WDISP22, 7);
default: return (CONST struct reloc_howto_struct *) 0;
}
else
STD (BFD_RELOC_8_PCREL, 4);
STD (BFD_RELOC_16_PCREL, 5);
STD (BFD_RELOC_32_PCREL, 6);
+ STD (BFD_RELOC_16_BASEREL, 9);
+ STD (BFD_RELOC_32_BASEREL, 10);
default: return (CONST struct reloc_howto_struct *) 0;
}
}
Internal Entry Points
DESCRIPTION
- @code{aoutx.h} exports several routines for accessing the
+ @file{aoutx.h} exports several routines for accessing the
contents of an a.out file, which are gathered and exported in
turn by various format specific files (eg sunos.c).
/*
FUNCTION
- aout_<size>_swap_exec_header_in
-
-DESCRIPTION
- Swaps the information in an executable header taken from a raw
- byte stream memory image, into the internal exec_header
- structure.
+ aout_@var{size}_swap_exec_header_in
SYNOPSIS
- void aout_<size>_swap_exec_header_in,
+ void aout_@var{size}_swap_exec_header_in,
(bfd *abfd,
struct external_exec *raw_bytes,
struct internal_exec *execp);
+
+DESCRIPTION
+ Swap the information in an executable header @var{raw_bytes} taken
+ from a raw byte stream memory image into the internal exec header
+ structure @var{execp}.
*/
-
+
#ifndef NAME_swap_exec_header_in
void
DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
/*
FUNCTION
- aout_<size>_swap_exec_header_out
-
-DESCRIPTION
- Swaps the information in an internal exec header structure
- into the supplied buffer ready for writing to disk.
+ aout_@var{size}_swap_exec_header_out
SYNOPSIS
- void aout_<size>_swap_exec_header_out
+ void aout_@var{size}_swap_exec_header_out
(bfd *abfd,
struct internal_exec *execp,
struct external_exec *raw_bytes);
+
+DESCRIPTION
+ Swap the information in an internal exec header structure
+ @var{execp} into the buffer @var{raw_bytes} ready for writing to disk.
*/
void
DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes),
bfd *abfd AND
- struct internal_exec *execp AND
+ struct internal_exec *execp AND
struct external_exec *raw_bytes)
{
struct external_exec *bytes = (struct external_exec *)raw_bytes;
/*
FUNCTION
- aout_<size>_some_aout_object_p
-
-DESCRIPTION
- Some A.OUT variant thinks that the file whose format we're
- checking is an a.out file. Do some more checking, and set up
- for access if it really is. Call back to the calling
- environments "finish up" function just before returning, to
- handle any last-minute setup.
+ aout_@var{size}_some_aout_object_p
SYNOPSIS
- bfd_target *aout_<size>_some_aout_object_p
+ bfd_target *aout_@var{size}_some_aout_object_p
(bfd *abfd,
bfd_target *(*callback_to_real_object_p)());
+
+DESCRIPTION
+ Some a.out variant thinks that the file open in @var{abfd}
+ checking is an a.out file. Do some more checking, and set up
+ for access if it really is. Call back to the calling
+ environment's "finish up" function just before returning, to
+ handle any last-minute setup.
*/
-
+
bfd_target *
DEFUN(NAME(aout,some_aout_object_p),(abfd, execp, callback_to_real_object_p),
bfd *abfd AND
if (execp->a_drsize || execp->a_trsize)
abfd->flags |= HAS_RELOC;
/* Setting of EXEC_P has been deferred to the bottom of this function */
- if (execp->a_syms)
+ if (execp->a_syms)
abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
if (N_MAGIC (*execp) == ZMAGIC)
#ifdef THIS_IS_ONLY_DOCUMENTATION
/* The common code can't fill in these things because they depend
on either the start address of the text segment, the rounding
- up of virtual addersses between segments, or the starting file
+ up of virtual addersses between segments, or the starting file
position of the text segment -- all of which varies among different
versions of a.out. */
- /* Call back to the format-dependent code to fill in the rest of the
+ /* Call back to the format-dependent code to fill in the rest of the
fields and do any further cleanup. Things that should be filled
in by the callback: */
on the architecture and the a.out variant. Finally, the return value
is the bfd_target vector in use. If an error occurs, return zero and
set bfd_error to the appropriate error code.
-
+
Formats such as b.out, which have additional fields in the a.out
header, should cope with them in this callback as well. */
#endif /* DOCUMENTATION */
guess at whether the file is executable. If the entry point
is within the text segment, assume it is. (This makes files
executable even if their entry point address is 0, as long as
- their text starts at zero.)
+ their text starts at zero.)
At some point we should probably break down and stat the file and
declare it executable if (one of) its 'x' bits are on... */
/*
FUNCTION
- aout_<size>_mkobject
-
-DESCRIPTION
- This routine initializes a BFD for use with a.out files.
+ aout_@var{size}_mkobject
SYNOPSIS
- boolean aout_<size>_mkobject, (bfd *);
+ boolean aout_@var{size}_mkobject, (bfd *abfd);
+
+DESCRIPTION
+ Initialize BFD @var{abfd} for use with a.out files.
*/
boolean
/* Use an intermediate variable for clarity */
rawptr = (struct aout_data_struct *)bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
-
+
if (rawptr == NULL) {
bfd_error = no_memory;
return false;
}
-
+
abfd->tdata.aout_data = rawptr;
exec_hdr (abfd) = &(rawptr->e);
-
+
/* For simplicity's sake we just make all the sections right here. */
-
+
obj_textsec (abfd) = (asection *)NULL;
obj_datasec (abfd) = (asection *)NULL;
obj_bsssec (abfd) = (asection *)NULL;
bfd_make_section (abfd, BFD_ABS_SECTION_NAME);
bfd_make_section (abfd, BFD_UND_SECTION_NAME);
bfd_make_section (abfd, BFD_COM_SECTION_NAME);
-
+
return true;
}
/*
FUNCTION
- aout_<size>_machine_type
+ aout_@var{size}_machine_type
+
+SYNOPSIS
+ enum machine_type aout_@var{size}_machine_type
+ (enum bfd_architecture arch,
+ unsigned long machine));
DESCRIPTION
Keep track of machine architecture and machine type for
- a.out's. Return the machine_type for a particular
- arch&machine, or M_UNKNOWN if that exact arch&machine can't be
- represented in a.out format.
+ a.out's. Return the <<machine_type>> for a particular
+ architecture and machine, or <<M_UNKNOWN>> if that exact architecture
+ and machine can't be represented in a.out format.
If the architecture is understood, machine type 0 (default)
- should always be understood.
-
-SYNOPSIS
- enum machine_type aout_<size>_machine_type
- (enum bfd_architecture arch,
- unsigned long machine));
+ is always understood.
*/
enum machine_type
unsigned long machine)
{
enum machine_type arch_flags;
-
+
arch_flags = M_UNKNOWN;
-
+
switch (arch) {
case bfd_arch_sparc:
if (machine == 0) arch_flags = M_SPARC;
break;
-
+
case bfd_arch_m68k:
switch (machine) {
case 0: arch_flags = M_68010; break;
default: arch_flags = M_UNKNOWN; break;
}
break;
-
+
case bfd_arch_i386:
if (machine == 0) arch_flags = M_386;
break;
-
+
case bfd_arch_a29k:
if (machine == 0) arch_flags = M_29K;
break;
-
+
case bfd_arch_mips:
switch (machine) {
case 0:
/*
FUNCTION
- aout_<size>_set_arch_mach
-
-DESCRIPTION
- Sets the architecture and the machine of the BFD to those
- values supplied. Verifies that the format can support the
- architecture required.
+ aout_@var{size}_set_arch_mach
SYNOPSIS
- boolean aout_<size>_set_arch_mach,
+ boolean aout_@var{size}_set_arch_mach,
(bfd *,
- enum bfd_architecture,
+ enum bfd_architecture arch,
unsigned long machine));
+
+DESCRIPTION
+ Set the architecture and the machine of the BFD @var{abfd} to the
+ values @var{arch} and @var{machine}. Verify that @var{abfd}'s format
+ can support the architecture required.
*/
boolean
bfd *abfd AND bfd_size_type *text_size AND file_ptr *text_end)
{
struct internal_exec *execp = exec_hdr (abfd);
- if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
+ if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
{
bfd_error = invalid_operation;
return false;
}
if (adata(abfd).magic != undecided_magic) return true;
- obj_textsec(abfd)->_raw_size =
+ obj_textsec(abfd)->_raw_size =
align_power(obj_textsec(abfd)->_raw_size,
obj_textsec(abfd)->alignment_power);
/*
FUNCTION
- aout_<size>_new_section_hook
-
-DESCRIPTION
- Called by the BFD in response to a @code{bfd_make_section}
- request.
+ aout_@var{size}_new_section_hook
SYNOPSIS
- boolean aout_<size>_new_section_hook,
+ boolean aout_@var{size}_new_section_hook,
(bfd *abfd,
asection *newsect));
+
+DESCRIPTION
+ Called by the BFD in response to a @code{bfd_make_section}
+ request.
*/
boolean
DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
/* align to double at least */
newsect->alignment_power = bfd_get_arch_info(abfd)->section_align_power;
-
- if (bfd_get_format (abfd) == bfd_object)
+
+ if (bfd_get_format (abfd) == bfd_object)
{
if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
obj_textsec(abfd)= newsect;
newsect->target_index = N_TEXT | N_EXT;
return true;
}
-
+
if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
obj_datasec(abfd) = newsect;
newsect->target_index = N_DATA | N_EXT;
return true;
}
-
+
if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
obj_bsssec(abfd) = newsect;
newsect->target_index = N_BSS | N_EXT;
}
}
-
+
/* We allow more than three sections internally */
return true;
}
}
/* regardless, once we know what we're doing, we might as well get going */
- if (section != obj_bsssec(abfd))
+ if (section != obj_bsssec(abfd))
{
bfd_seek (abfd, section->filepos + offset, SEEK_SET);
-
+
if (count) {
return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
true : false;
/* Symbol is debugger info if any bits outside N_TYPE or N_EXT
are on. */
#define sym_is_debugger_info(sym) \
- ((sym)->type & ~(N_EXT | N_TYPE))
+ (((sym)->type & ~(N_EXT | N_TYPE)) || (sym)->type == N_FN)
#define sym_is_fortrancommon(sym) \
(((sym)->type == (N_EXT)) && (sym)->symbol.value != 0)
/* Only in their own functions for ease of debugging; when sym flags have
stabilised these should be inlined into their (single) caller */
-
+
static void
DEFUN (translate_from_native_sym_flags, (sym_pointer, cache_ptr, abfd),
struct external_nlist *sym_pointer AND
to another */
sym_pointer->e_type[0] &= ~N_TYPE;
-
+
/* We attempt to order these tests by decreasing frequency of success,
according to tcov when linking the linker. */
if (bfd_get_output_section(cache_ptr) == &bfd_abs_section) {
else if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
sym_pointer->e_type[0] |= N_BSS;
}
- else if (bfd_get_output_section(cache_ptr) == &bfd_und_section)
+ else if (bfd_get_output_section(cache_ptr) == &bfd_und_section)
{
sym_pointer->e_type[0] = (N_UNDF | N_EXT);
}
- else if (bfd_get_output_section(cache_ptr) == &bfd_ind_section)
+ else if (bfd_get_output_section(cache_ptr) == &bfd_ind_section)
{
sym_pointer->e_type[0] = N_INDR;
}
else if (bfd_is_com_section (bfd_get_output_section (cache_ptr))) {
sym_pointer->e_type[0] = (N_UNDF | N_EXT);
- }
- else {
- if (cache_ptr->section->output_section)
+ }
+ else {
+ if (cache_ptr->section->output_section)
{
-
+
bfd_error_vector.nonrepresentable_section(abfd,
bfd_get_output_section(cache_ptr)->name);
}
- else
+ else
{
bfd_error_vector.nonrepresentable_section(abfd,
cache_ptr->section->name);
-
+
}
-
+
}
/* Turn the symbol from section relative to absolute again */
-
+
value += cache_ptr->section->output_section->vma + cache_ptr->section->output_offset ;
if (cache_ptr->flags & (BSF_WARNING)) {
(sym_pointer+1)->e_type[0] = 1;
- }
-
+ }
+
if (cache_ptr->flags & BSF_DEBUGGING) {
sym_pointer->e_type[0] = ((aout_symbol_type *)cache_ptr)->type;
}
/* Run through table and copy values */
for (sym_pointer = syms, cache_ptr = cached;
- sym_pointer < sym_end; sym_pointer ++, cache_ptr++)
+ sym_pointer < sym_end; sym_pointer ++, cache_ptr++)
{
long x = GET_WORD(abfd, sym_pointer->e_strx);
cache_ptr->symbol.the_bfd = abfd;
r_length = g->howto->size ; /* Size as a power of two */
r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
- /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
- r_baserel = 0;
+ /* XXX This relies on relocs coming from a.out files. */
+ r_baserel = (g->howto->type & 8) != 0;
+ /* r_jmptable, r_relative??? FIXME-soon */
r_jmptable = 0;
r_relative = 0;
-
+
r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
-
+
/* name was clobbered by aout_write_syms to be symbol index */
- /* If this relocation is relative to a symbol then set the
+ /* If this relocation is relative to a symbol then set the
r_index to the symbols index, and the r_extern bit.
Absolute symbols can come in in two ways, either as an offset
from the abs section, or as a symbol which has an abs value.
check for that here
*/
-
+
if (bfd_is_com_section (output_section)
|| output_section == &bfd_abs_section
- || output_section == &bfd_und_section)
+ || output_section == &bfd_und_section)
{
if (bfd_abs_section.symbol == sym)
{
r_index = 0;
r_extern = 0;
}
- else
+ else
{
/* Fill in symbol */
r_extern = 1;
r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT);
-
+
}
}
- else
+ else
{
/* Just an ordinary section */
r_extern = 0;
- r_index = output_section->target_index;
+ r_index = output_section->target_index;
}
/* now the fun stuff */
int r_extern;
unsigned int r_type;
unsigned int r_addend;
- asymbol *sym = *(g->sym_ptr_ptr);
+ asymbol *sym = *(g->sym_ptr_ptr);
asection *output_section = sym->section->output_section;
-
+
PUT_WORD (abfd, g->address, natptr->r_address);
-
+
r_type = (unsigned int) g->howto->type;
-
- r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
+ r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
- /* If this relocation is relative to a symbol then set the
+ /* If this relocation is relative to a symbol then set the
r_index to the symbols index, and the r_extern bit.
Absolute symbols can come in in two ways, either as an offset
from the abs section, or as a symbol which has an abs value.
- check for that here
- */
-
+ check for that here. */
+
if (bfd_is_com_section (output_section)
|| output_section == &bfd_abs_section
|| output_section == &bfd_und_section)
r_index = 0;
r_extern = 0;
}
- else
+ else
{
r_extern = 1;
r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT);
}
}
- else
+ else
{
/* Just an ordinary section */
r_extern = 0;
- r_index = output_section->target_index;
+ r_index = output_section->target_index;
}
-
-
+
/* now the fun stuff */
if (abfd->xvec->header_byteorder_big_p != false) {
natptr->r_index[0] = r_index >> 16;
natptr->r_index[1] = r_index >> 8;
natptr->r_index[2] = r_index;
natptr->r_type[0] =
- (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
- | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
+ ((r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
+ | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG));
} else {
natptr->r_index[2] = r_index >> 16;
natptr->r_index[1] = r_index >> 8;
/* BFD deals internally with all things based from the section they're
in. so, something in 10 bytes into a text section with a base of
- 50 would have a symbol (.text+10) and know .text vma was 50.
+ 50 would have a symbol (.text+10) and know .text vma was 50.
Aout keeps all it's symbols based from zero, so the symbol would
contain 60. This macro subs the base of each section from the value
int r_pcrel;
int r_baserel, r_jmptable, r_relative;
struct aoutdata *su = &(abfd->tdata.aout_data->a);
+ int howto_idx;
cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
- r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
+ r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
>> RELOC_STD_BITS_LENGTH_SH_BIG;
} else {
r_index = (bytes->r_index[2] << 16)
r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
- r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
+ r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
>> RELOC_STD_BITS_LENGTH_SH_LITTLE;
}
- cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
- /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
+ howto_idx = r_length + 4 * r_pcrel + 8 * r_baserel;
+ BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
+ cache_ptr->howto = howto_table_std + howto_idx;
+ BFD_ASSERT (cache_ptr->howto->type != -1);
+ BFD_ASSERT (r_jmptable == 0);
+ BFD_ASSERT (r_relative == 0);
+ /* FIXME-soon: Roll jmptable, relative bits into howto setting */
MOVE_ADDRESS(0);
}
if (asect == obj_datasec (abfd)) {
reloc_size = exec_hdr(abfd)->a_drsize;
- goto doit;
- }
-
- if (asect == obj_textsec (abfd)) {
+ } else if (asect == obj_textsec (abfd)) {
reloc_size = exec_hdr(abfd)->a_trsize;
- goto doit;
+ } else {
+ bfd_error = invalid_operation;
+ return false;
}
- bfd_error = invalid_operation;
- return false;
-
- doit:
bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
each_size = obj_reloc_entry_size (abfd);
NAME(aout,swap_ext_reloc_in)(abfd, rptr, cache_ptr, symbols);
}
} else {
- register struct reloc_std_external *rptr = (struct reloc_std_external*) relocs;
+ register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
unsigned int counter = 0;
arelent *cache_ptr = reloc_cache;
for (; counter < count; counter++, rptr++, cache_ptr++) {
- NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
+ NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
}
}
generic = section->orelocation;
- if (each_size == RELOC_EXT_SIZE)
+ if (each_size == RELOC_EXT_SIZE)
{
for (natptr = native;
count != 0;
--count, natptr += each_size, ++generic)
NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
}
- else
+ else
{
for (natptr = native;
count != 0;
tblptr = section->relocation;
if (!tblptr) return 0;
- for (count = 0; count++ < section->reloc_count;)
+ for (count = 0; count++ < section->reloc_count;)
{
*relptr++ = tblptr++;
}
return (alent *)NULL;
}
-void
+void
DEFUN(NAME(aout,get_symbol_info),(ignore_abfd, symbol, ret),
bfd *ignore_abfd AND
asymbol *symbol AND
}
}
-void
+void
DEFUN(NAME(aout,print_symbol),(ignore_abfd, afile, symbol, how),
bfd *ignore_abfd AND
PTR afile AND
}
}
-/*
+/*
provided a BFD, a section and an offset into the section, calculate
and return the name of the source file and the line nearest to the
wanted location.
*/
-
+
boolean
DEFUN(NAME(aout,find_nearest_line),(abfd,
section,
}
-int
+int
DEFUN(NAME(aout,sizeof_headers),(abfd, execable),
bfd *abfd AND
boolean execable)
Archives
DESCRIPTION
- Archives are supported in BFD in <<archive.c>>.
-
An archive (or library) is just another BFD. It has a symbol
table, although there's not much a user program will do with it.
The big difference between an archive BFD and an ordinary BFD
is that the archive doesn't have sections. Instead it has a
- chain of BFDs considered its contents. These BFDs can be
- manipulated just like any other. The BFDs contained in an
- archive opened for reading will all be opened for reading; you
+ chain of BFDs that are considered its contents. These BFDs can
+ be manipulated like any other. The BFDs contained in an
+ archive opened for reading will all be opened for reading. You
may put either input or output BFDs into an archive opened for
- output; it will be handled correctly when the archive is closed.
+ output; they will be handled correctly when the archive is closed.
- Use <<bfd_openr_next_archived_file>> to step through all
- the contents of an archive opened for input. It's not
- required that you read the entire archive if you don't want
+ Use <<bfd_openr_next_archived_file>> to step through
+ the contents of an archive opened for input. You don't
+ have to read the entire archive if you don't want
to! Read it until you find what you want.
Archive contents of output BFDs are chained through the
<<next>> pointer in a BFD. The first one is findable through
the <<archive_head>> slot of the archive. Set it with
- <<set_archive_head>> (q.v.). A given BFD may be in only one
+ <<bfd_set_archive_head>> (q.v.). A given BFD may be in only one
open output archive at a time.
As expected, the BFD archive code is more general than the
This can cause unexpected confusion, since some archive
formats are more expressive than others. For instance, Intel
- COFF archives can preserve long filenames; Sun a.out archives
+ COFF archives can preserve long filenames; SunOS a.out archives
cannot. If you move a file from the first to the second
format and back again, the filename may be truncated.
Likewise, different a.out environments have different
Beware: most of these formats do not react well to the
presence of spaces in filenames. We do the best we can, but
- can't always handle this due to restrctions in the format of
- archives. Many unix utilities are braindead in regards to
+ can't always handle this case due to restrictions in the format of
+ archives. Many Unix utilities are braindead in regards to
spaces and such in filenames anyway, so this shouldn't be much
of a restriction.
+
+ Archives are supported in BFD in <<archive.c>>.
+
*/
/* Assumes:
*/
/* Some formats provide a way to cram a long filename into the short
- (16 chars) space provided by a bsd archive. The trick is: make a
+ (16 chars) space provided by a BSD archive. The trick is: make a
special "file" in the front of the archive, sort of like the SYMDEF
entry. If the filename is too long to fit, put it in the extended
name table, and use its index as the filename. To prevent
confusion prepend the index with a space. This means you can't
- have filenames that start with a space, but then again, many unix
+ have filenames that start with a space, but then again, many Unix
utilities can't handle that anyway.
This scheme unfortunately requires that you stand on your head in
BSD 4.4 uses a third scheme: It writes a long filename
directly after the header. This allows 'ar q' to work.
- We current can read BSD 4.4 archives, but not write them.
+ We currently can read BSD 4.4 archives, but not write them.
*/
/* Summary of archive member names:
#define BFD_GNU960_ARMAG(abfd) (BFD_COFF_FILE_P((abfd)) ? ARMAG : ARMAGB)
#endif
+/* Can't define this in hosts/foo.h, because (e.g. in gprof) the hosts file
+ is included, then obstack.h, which thinks if offsetof is defined, it
+ doesn't need to include stddef.h. */
+/* Define offsetof for those systems which lack it */
+
+#if !defined (offsetof)
+#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
+#endif
+
/* We keep a cache of archive filepointers to archive elements to
speed up searching the archive by filepos. We only add an entry to
the cache when we actually read one. We also don't sort the cache;
bfd_get_next_mapent
SYNOPSIS
- symindex bfd_get_next_mapent(bfd *, symindex previous, carsym ** sym);
+ symindex bfd_get_next_mapent(bfd *abfd, symindex previous, carsym **sym);
DESCRIPTION
- This function steps through an archive's symbol table (if it
- has one). Successively updates <<sym>> with the next symbol's
+ Step through archive @var{abfd}'s symbol table (if it
+ has one). Successively update @var{sym} with the next symbol's
information, returning that symbol's (internal) index into the
symbol table.
- Supply BFD_NO_MORE_SYMBOLS as the <<previous>> entry to get
+ Supply BFD_NO_MORE_SYMBOLS as the @var{previous} entry to get
the first one; returns BFD_NO_MORE_SYMBOLS when you're already
got the last one.
}
/* To be called by backends only */
+
bfd *
_bfd_create_empty_archive_element_shell (obfd)
bfd *obfd;
bfd *nbfd;
nbfd = new_bfd_contained_in(obfd);
- if (nbfd == NULL) {
- bfd_error = no_memory;
- return NULL;
- }
+ if (nbfd == NULL)
+ {
+ bfd_error = no_memory;
+ return NULL;
+ }
return nbfd;
}
boolean bfd_set_archive_head(bfd *output, bfd *new_head);
DESCRIPTION
- Used whilst processing archives. Sets the head of the chain of
- BFDs contained in an archive to @var{new_head}.
+ Set the head of the chain of
+ BFDs contained in the archive @var{output} to @var{new_head}.
*/
boolean
*/
bfd *
-DEFUN (get_elt_at_filepos, (archive, filepos),
- bfd *archive AND
- file_ptr filepos)
+get_elt_at_filepos (archive, filepos)
+ bfd *archive;
+ file_ptr filepos;
{
struct areltdata *new_areldata;
bfd *n_nfd;
n_nfd = look_for_bfd_in_cache (archive, filepos);
- if (n_nfd) return n_nfd;
+ if (n_nfd)
+ return n_nfd;
- if (0 > bfd_seek (archive, filepos, SEEK_SET)) {
- bfd_error = system_call_error;
- return NULL;
- }
+ if (0 > bfd_seek (archive, filepos, SEEK_SET))
+ {
+ bfd_error = system_call_error;
+ return NULL;
+ }
- if ((new_areldata = snarf_ar_hdr (archive)) == NULL) return NULL;
+ if ((new_areldata = snarf_ar_hdr (archive)) == NULL)
+ return NULL;
n_nfd = _bfd_create_empty_archive_element_shell (archive);
- if (n_nfd == NULL) {
- bfd_release (archive, (PTR)new_areldata);
- return NULL;
- }
+ if (n_nfd == NULL)
+ {
+ bfd_release (archive, (PTR)new_areldata);
+ return NULL;
+ }
+
n_nfd->origin = bfd_tell (archive);
n_nfd->arelt_data = (PTR) new_areldata;
n_nfd->filename = new_areldata->filename;
bfd_get_elt_at_index
SYNOPSIS
- bfd *bfd_get_elt_at_index(bfd * archive, int index);
+ bfd *bfd_get_elt_at_index(bfd *archive, int index);
DESCRIPTION
- Return the bfd which is referenced by the symbol indexed by <<index>>.
- <<index>> should have been returned by <<bfd_get_next_mapent>> (q.v.).
+ Return the BFD which is referenced by the symbol in @var{archive}
+ indexed by @var{index}. @var{index} should have been returned by
+ <<bfd_get_next_mapent>> (q.v.).
*/
bfd *
bfd_openr_next_archived_file
SYNOPSIS
- bfd* bfd_openr_next_archived_file(bfd *archive, bfd *previous);
+ bfd *bfd_openr_next_archived_file(bfd *archive, bfd *previous);
DESCRIPTION
- Initially provided a BFD containing an archive and NULL, opens
- an inpout BFD on the first contained element and returns that.
- Subsequent calls to bfd_openr_next_archived_file should pass
+ Provided a BFD, @var{archive}, containing an archive and NULL, open
+ an input BFD on the first contained element and returns that.
+ Subsequent calls should pass
the archive and the previous return value to return a created
BFD to the next contained element. NULL is returned when there
are no more.
*/
bfd *
-DEFUN(bfd_openr_next_archived_file,(archive, last_file),
- bfd *archive AND
- bfd*last_file)
+bfd_openr_next_archived_file (archive, last_file)
+ bfd *archive;
+ bfd *last_file;
{
+ if ((bfd_get_format (archive) != bfd_archive) ||
+ (archive->direction == write_direction))
+ {
+ bfd_error = invalid_operation;
+ return NULL;
+ }
- if ((bfd_get_format (archive) != bfd_archive) ||
- (archive->direction == write_direction)) {
- bfd_error = invalid_operation;
- return NULL;
- }
-
-
- return BFD_SEND (archive,
- openr_next_archived_file,
- (archive,
- last_file));
-
+ return BFD_SEND (archive,
+ openr_next_archived_file,
+ (archive,
+ last_file));
}
-bfd *bfd_generic_openr_next_archived_file(archive, last_file)
+bfd *
+bfd_generic_openr_next_archived_file (archive, last_file)
bfd *archive;
bfd *last_file;
{
syms[src_count]->section;
if ((flags & BSF_GLOBAL ||
+ flags & BSF_WEAK ||
flags & BSF_INDIRECT ||
bfd_is_com_section (sec))
&& (sec != &bfd_und_section)) {
sprintf (hdr.ar_name, RANLIBMAG);
/* Remember the timestamp, to keep it holy. But fudge it a little. */
bfd_ardata(arch)->armap_timestamp = statbuf.st_mtime + ARMAP_TIME_OFFSET;
- bfd_ardata(arch)->armap_datepos = SARMAG + offsetof(struct ar_hdr, ar_date);
+ bfd_ardata(arch)->armap_datepos = SARMAG +
+ offsetof(struct ar_hdr, ar_date[0]);
sprintf (hdr.ar_date, "%ld", bfd_ardata(arch)->armap_timestamp);
sprintf (hdr.ar_uid, "%d", getuid());
sprintf (hdr.ar_gid, "%d", getgid());
SECTION
Architectures
- BFD's idea of an architecture is implimented in
- <<archures.c>>. BFD keeps one atom in a BFD describing the
- architecture of the data attached to the BFD; a pointer to a
+ BFD keeps one atom in a BFD describing the
+ architecture of the data attached to the BFD: a pointer to a
<<bfd_arch_info_type>>.
- Pointers to structures can be requested independently of a bfd
+ Pointers to structures can be requested independently of a BFD
so that an architecture's information can be interrogated
- without access to an open bfd.
+ without access to an open BFD.
- The arch information is provided by each architecture package.
- The set of default architectures is selected by the #define
+ The architecture information is provided by each architecture package.
+ The set of default architectures is selected by the macro
<<SELECT_ARCHITECTURES>>. This is normally set up in the
<<config/target.mt>> file of your choice. If the name is not
defined, then all the architectures supported are included.
insert as many items into the list of architectures as it wants to;
generally this would be one for each machine and one for the
default case (an item with a machine field of 0).
+
+ BFD's idea of an architecture is implemented in <<archures.c>>.
*/
/*
DESCRIPTION
This enum gives the object file's CPU architecture, in a
- global sense --- i.e., what processor family does it belong to?
- There is another field, which indicates what processor within
+ global sense---i.e., what processor family does it belong to?
+ Another field indicates which processor within
the family is in use. The machine gives a number which
- distingushes different versions of the architecture,
- containing for example 2 and 3 for Intel i960 KA and i960 KB,
+ distinguishes different versions of the architecture,
+ containing, for example, 2 and 3 for Intel i960 KA and i960 KB,
and 68020 and 68030 for Motorola 68020 and 68030.
.enum bfd_architecture
DESCRIPTION
Return a printable string representing the architecture and machine
- from the pointer to the arch info structure
+ from the pointer to the architecture info structure.
*/
bfd_scan_arch
SYNOPSIS
- bfd_arch_info_type *bfd_scan_arch(CONST char *);
+ bfd_arch_info_type *bfd_scan_arch(CONST char *string);
DESCRIPTION
- This routine is provided with a string and tries to work out
- if bfd supports any cpu which could be described with the name
- provided. The routine returns a pointer to an arch_info
+ Figure out if BFD supports any cpu which could be described with
+ the name @var{string}. Return a pointer to an <<arch_info>>
structure if a machine is found, otherwise NULL.
*/
CONST bfd *bbfd);
DESCRIPTION
- This routine is used to determine whether two BFDs'
- architectures and achine types are compatible. It calculates
+ Determine whether two BFDs'
+ architectures and machine types are compatible. Calculates
the lowest common denominator between the two architectures
and machine types implied by the BFDs and returns a pointer to
- an arch_info structure describing the compatible machine.
+ an <<arch_info>> structure describing the compatible machine.
*/
CONST bfd_arch_info_type *
bfd_set_arch_info
SYNOPSIS
- void bfd_set_arch_info(bfd *, bfd_arch_info_type *);
+ void bfd_set_arch_info(bfd *abfd, bfd_arch_info_type *arg);
+DESCRIPTION
+ Set the architecture info of @var{abfd} to @var{arg}.
*/
void DEFUN(bfd_set_arch_info,(abfd, arg),
unsigned long mach);
DESCRIPTION
- Set the architecture and machine type in a bfd. This finds the
- correct pointer to structure and inserts it into the arch_info
+ Set the architecture and machine type in BFD @var{abfd}
+ to @var{arch} and @var{mach}. Find the correct
+ pointer to a structure and insert it into the <<arch_info>>
pointer.
*/
}
-
-
-
/*
FUNCTION
bfd_get_arch
enum bfd_architecture bfd_get_arch(bfd *abfd);
DESCRIPTION
- Returns the enumerated type which describes the supplied bfd's
- architecture
+ Return the enumerated type which describes the BFD @var{abfd}'s
+ architecture.
*/
unsigned long bfd_get_mach(bfd *abfd);
DESCRIPTION
- Returns the long type which describes the supplied bfd's
- machine
+ Return the long type which describes the BFD @var{abfd}'s
+ machine.
*/
unsigned long
unsigned int bfd_arch_bits_per_byte(bfd *abfd);
DESCRIPTION
- Returns the number of bits in one of the architectures bytes
+ Return the number of bits in one of the BFD @var{abfd}'s
+ architecture's bytes.
*/
unsigned int DEFUN(bfd_arch_bits_per_byte, (abfd), bfd *abfd)
- {
- return abfd->arch_info->bits_per_byte;
- }
+{
+ return abfd->arch_info->bits_per_byte;
+}
/*
FUNCTION
unsigned int bfd_arch_bits_per_address(bfd *abfd);
DESCRIPTION
- Returns the number of bits in one of the architectures addresses
+ Return the number of bits in one of the BFD @var{abfd}'s
+ architecture's addresses.
*/
unsigned int DEFUN(bfd_arch_bits_per_address, (abfd), bfd *abfd)
- {
- return abfd->arch_info->bits_per_address;
- }
-
+{
+ return abfd->arch_info->bits_per_address;
+}
+extern void bfd_a29k_arch PARAMS ((void));
+extern void bfd_alpha_arch PARAMS ((void));
extern void bfd_h8300_arch PARAMS ((void));
-extern void bfd_sh_arch PARAMS ((void));
extern void bfd_h8500_arch PARAMS ((void));
-extern void bfd_alpha_arch PARAMS ((void));
+extern void bfd_hppa_arch PARAMS ((void));
+extern void bfd_i386_arch PARAMS ((void));
extern void bfd_i960_arch PARAMS ((void));
-extern void bfd_empty_arch PARAMS ((void));
-extern void bfd_sparc_arch PARAMS ((void));
-extern void bfd_m88k_arch PARAMS ((void));
extern void bfd_m68k_arch PARAMS ((void));
-extern void bfd_vax_arch PARAMS ((void));
-extern void bfd_a29k_arch PARAMS ((void));
+extern void bfd_m88k_arch PARAMS ((void));
extern void bfd_mips_arch PARAMS ((void));
-extern void bfd_i386_arch PARAMS ((void));
extern void bfd_rs6000_arch PARAMS ((void));
-extern void bfd_hppa_arch PARAMS ((void));
-extern void bfd_z8k_arch PARAMS ((void));
+extern void bfd_sh_arch PARAMS ((void));
+extern void bfd_sparc_arch PARAMS ((void));
+extern void bfd_vax_arch PARAMS ((void));
extern void bfd_we32k_arch PARAMS ((void));
+extern void bfd_z8k_arch PARAMS ((void));
static void (*archures_init_table[]) PARAMS ((void)) =
{
bfd_arch_init
SYNOPSIS
- void bfd_arch_init(void);
+ void bfd_arch_init(void);
DESCRIPTION
- This routine initializes the architecture dispatch table by
+ Initialize the architecture dispatch table by
calling all installed architecture packages and getting them
to poke around.
*/
bfd_arch_linkin
SYNOPSIS
- void bfd_arch_linkin(bfd_arch_info_type *);
+ void bfd_arch_linkin(bfd_arch_info_type *ptr);
DESCRIPTION
- Link the provided arch info structure into the list
+ Link the architecture info structure @var{ptr} into the list.
*/
void DEFUN(bfd_arch_linkin,(ptr),
bfd_default_scan
SYNOPSIS
- boolean bfd_default_scan(CONST struct bfd_arch_info *, CONST char *);
+ boolean bfd_default_scan(CONST struct bfd_arch_info *info, CONST char *string);
DESCRIPTION
The default function for working out whether this is an
}
-
-
/*
FUNCTION
bfd_get_arch_info
-
SYNOPSIS
- bfd_arch_info_type * bfd_get_arch_info(bfd *);
+ bfd_arch_info_type * bfd_get_arch_info(bfd *abfd);
+DESCRIPTION
+ Return the architecture info struct in @var{abfd}.
*/
bfd_arch_info_type *
long machine);
DESCRIPTION
- Look for the architecure info struct which matches the
- arguments given. A machine of 0 will match the
+ Look for the architecure info structure which matches the
+ arguments @var{arch} and @var{machine}. A machine of 0 matches the
machine/architecture structure which marks itself as the
default.
*/
}
-
/*
FUNCTION
bfd_printable_arch_mach
SYNOPSIS
- CONST char * bfd_printable_arch_mach
+ CONST char *bfd_printable_arch_mach
(enum bfd_architecture arch, unsigned long machine);
DESCRIPTION
Return a printable string representing the architecture and
machine type.
- NB. The use of this routine is depreciated.
+ This routine is depreciated.
*/
CONST char *
bfd_init PARAMS ((void));
bfd *
-bfd_openr PARAMS ((CONST char *filename, CONST char*target));
+bfd_openr PARAMS ((CONST char *filename, CONST char *target));
bfd *
bfd_fdopenr PARAMS ((CONST char *filename, CONST char *target, int fd));
bfd_openw PARAMS ((CONST char *filename, CONST char *target));
boolean
-bfd_close PARAMS ((bfd *));
+bfd_close PARAMS ((bfd *abfd));
boolean
bfd_close_all_done PARAMS ((bfd *));
typedef struct sec
{
- /* The name of the section, the name isn't a copy, the pointer is
+ /* The name of the section; the name isn't a copy, the pointer is
the same as that passed to bfd_make_section. */
CONST char *name;
- /* Which section is it 0.nth */
+ /* Which section is it; 0..nth. */
int index;
struct sec *next;
- /* The field flags contains attributes of the section. Some of
+ /* The field flags contains attributes of the section. Some
flags are read in from the object file, and some are
synthesized from other information. */
#define SEC_NO_FLAGS 0x000
- /* Tells the OS to allocate space for this section when loaded.
- This would clear for a section containing debug information
+ /* Tells the OS to allocate space for this section when loading.
+ This is clear for a section containing debug information
only. */
#define SEC_ALLOC 0x001
/* Tells the OS to load the section from the file when loading.
- This would be clear for a .bss section */
+ This is clear for a .bss section. */
#define SEC_LOAD 0x002
- /* The section contains data still to be relocated, so there will
- be some relocation information too. */
+ /* The section contains data still to be relocated, so there is
+ some relocation information too. */
#define SEC_RELOC 0x004
#if 0 /* Obsolete ? */
type is used by the linker to create lists of constructors and
destructors used by <<g++>>. When a back end sees a symbol
which should be used in a constructor list, it creates a new
- section for the type of name (eg <<__CTOR_LIST__>>), attaches
- the symbol to it and builds a relocation. To build the lists
+ section for the type of name (e.g., <<__CTOR_LIST__>>), attaches
+ the symbol to it, and builds a relocation. To build the lists
of constructors, all the linker has to do is catenate all the
- sections called <<__CTOR_LIST__>> and relocte the data
+ sections called <<__CTOR_LIST__>> and relocate the data
contained within - exactly the operations it would peform on
standard data. */
#define SEC_CONSTRUCTOR 0x100
#define SEC_CONSTRUCTOR_BSS 0x3100
/* The section has contents - a data section could be
- <<SEC_ALLOC>> | <<SEC_HAS_CONTENTS>>, a debug section could be
+ <<SEC_ALLOC>> | <<SEC_HAS_CONTENTS>>; a debug section could be
<<SEC_HAS_CONTENTS>> */
#define SEC_HAS_CONTENTS 0x200
- /* An instruction to the linker not to output sections
- containing this flag even if they have information which
- would normally be written. */
+ /* An instruction to the linker to not output the section
+ even if it has information which would normally be written. */
#define SEC_NEVER_LOAD 0x400
/* The section is a shared library section. The linker must leave
boolean user_set_vma;
/* The load address of the section - where it would be in a
- rom image, really only used for writing section header
+ rom image; really only used for writing section header
information. */
bfd_vma lma;
/* The size of the section in bytes, as it will be output.
- contains a value even if the section has no contents (eg, the
+ contains a value even if the section has no contents (e.g., the
size of <<.bss>>). This will be filled in after relocation */
bfd_size_type _cooked_size;
- /* The size on disk of the section in bytes originally. Normally this
+ /* The original size on disk of the section, in bytes. Normally this
value is the same as the size, but if some relaxing has
been done, then this value will be bigger. */
/* If this section is going to be output, then this value is the
offset into the output section of the first byte in the input
- section. Eg, if this was going to start at the 100th byte in
+ section. E.g., if this was going to start at the 100th byte in
the output section, this value would be 100. */
bfd_vma output_offset;
struct sec *output_section;
- /* The alignment requirement of the section, as an exponent - eg
- 3 aligns to 2^3 (or 8) */
+ /* The alignment requirement of the section, as an exponent of 2 -
+ e.g., 3 aligns to 2^3 (or 8). */
unsigned int alignment_power;
file_ptr moving_line_filepos;
- /* what the section number is in the target world */
+ /* What the section number is in the target world */
int target_index;
bfd_get_section_by_name PARAMS ((bfd *abfd, CONST char *name));
asection *
-bfd_make_section_old_way PARAMS ((bfd *, CONST char *name));
+bfd_make_section_old_way PARAMS ((bfd *abfd, CONST char *name));
asection *
-bfd_make_section_anyway PARAMS ((bfd *, CONST char *name));
+bfd_make_section_anyway PARAMS ((bfd *abfd, CONST char *name));
asection *
bfd_make_section PARAMS ((bfd *, CONST char *name));
boolean
-bfd_set_section_flags PARAMS ((bfd *, asection *, flagword));
+bfd_set_section_flags PARAMS ((bfd *abfd, asection *sec, flagword flags));
void
bfd_map_over_sections PARAMS ((bfd *abfd,
PTR obj));
boolean
-bfd_set_section_size PARAMS ((bfd *, asection *, bfd_size_type val));
+bfd_set_section_size PARAMS ((bfd *abfd, asection *sec, bfd_size_type val));
boolean
bfd_set_section_contents
bfd_printable_name PARAMS ((bfd *abfd));
bfd_arch_info_type *
-bfd_scan_arch PARAMS ((CONST char *));
+bfd_scan_arch PARAMS ((CONST char *string));
CONST bfd_arch_info_type *
bfd_arch_get_compatible PARAMS ((
CONST bfd *bbfd));
void
-bfd_set_arch_info PARAMS ((bfd *, bfd_arch_info_type *));
+bfd_set_arch_info PARAMS ((bfd *abfd, bfd_arch_info_type *arg));
enum bfd_architecture
bfd_get_arch PARAMS ((bfd *abfd));
bfd_arch_bits_per_address PARAMS ((bfd *abfd));
bfd_arch_info_type *
-bfd_get_arch_info PARAMS ((bfd *));
+bfd_get_arch_info PARAMS ((bfd *abfd));
bfd_arch_info_type *
bfd_lookup_arch
arch,
long machine));
-CONST char *
+CONST char *
bfd_printable_arch_mach
PARAMS ((enum bfd_architecture arch, unsigned long machine));
/* Used by special functions */
bfd_reloc_continue,
- /* Unused */
+ /* Unsupported relocation size requested. */
bfd_reloc_notsupported,
- /* Unsupported relocation size requested. */
+ /* Unused */
bfd_reloc_other,
/* The symbol to relocate against was undefined. */
complain_overflow_unsigned
};
-typedef CONST struct reloc_howto_struct
+typedef struct reloc_howto_struct
{
/* The type field has mainly a documetary use - the back end can
- to what it wants with it, though the normally the back end's
- external idea of what a reloc number would be would be stored
- in this field. For example, the a PC relative word relocation
- in a coff environment would have the type 023 - because that's
+ do what it wants with it, though normally the back end's
+ external idea of what a reloc number is stored
+ in this field. For example, a PC relative word relocation
+ in a coff environment has the type 023 - because that's
what the outside world calls a R_PCRWORD reloc. */
unsigned int type;
relocations rather than the data - this flag signals this.*/
boolean partial_inplace;
- /* The src_mask is used to select what parts of the read in data
+ /* The src_mask selects which parts of the read in data
are to be used in the relocation sum. E.g., if this was an 8 bit
bit of data which we read and relocated, this would be
0x000000ff. When we have relocs which have an addend, such as
the mask would be 0x00000000. */
bfd_vma src_mask;
- /* The dst_mask is what parts of the instruction are replaced
+ /* The dst_mask selects which parts of the instruction are replaced
into the instruction. In most cases src_mask == dst_mask,
except in the above special case, where dst_mask would be
0x000000ff, and src_mask would be 0x00000000. */
slot of the instruction, so that a PC relative relocation can
be made just by adding in an ordinary offset (e.g., sun3 a.out).
Some formats leave the displacement part of an instruction
- empty (e.g., m88k bcs), this flag signals the fact.*/
+ empty (e.g., m88k bcs); this flag signals the fact.*/
boolean pcrel_offset;
} reloc_howto_type;
bfd_reloc_status_type
bfd_perform_relocation
- PARAMS ((bfd * abfd,
+ PARAMS ((bfd *abfd,
arelent *reloc_entry,
PTR data,
asection *input_section,
bfd_reloc_type_lookup PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
+unsigned int
+bfd_get_reloc_upper_bound PARAMS ((bfd *abfd, asection *sect));
+
+unsigned int
+bfd_canonicalize_reloc
+ PARAMS ((bfd *abfd,
+ asection *sec,
+ arelent **loc,
+ asymbol **syms));
+
+void
+bfd_set_reloc
+ PARAMS ((bfd *abfd, sec_ptr *sec, arelent **rel, unsigned int count)
+
+ );
+
typedef struct symbol_cache_entry
{
struct _bfd *the_bfd; /* Use bfd_asymbol_bfd(sym) to access this field. */
- /* The text of the symbol. The name is left alone, and not copied - the
+ /* The text of the symbol. The name is left alone, and not copied; the
application may not alter it. */
CONST char *name;
value is the offset into the section of the data. */
#define BSF_GLOBAL 0x02
- /* The symbol has global scope, and is exported. The value is
+ /* The symbol has global scope and is exported. The value is
the offset into the section of the data. */
#define BSF_EXPORT BSF_GLOBAL /* no real difference */
BFD_SEND (abfd, _bfd_canonicalize_symtab,\
(abfd, location))
boolean
-bfd_set_symtab PARAMS ((bfd *, asymbol **, unsigned int ));
+bfd_set_symtab PARAMS ((bfd *abfd, asymbol **location, unsigned int count));
void
bfd_print_symbol_vandf PARAMS ((PTR file, asymbol *symbol));
boolean cacheable;
/* Marks whether there was a default target specified when the
- BFD was opened. This is used to select what matching algorithm
- to use to chose the back end. */
+ BFD was opened. This is used to select which matching algorithm
+ to use to choose the back end. */
boolean target_defaulted;
struct _bfd *lru_prev, *lru_next;
/* When a file is closed by the caching routines, BFD retains
- state information on the file here:
- */
+ state information on the file here: */
file_ptr where;
- /* and here:*/
+ /* and here: (``once'' means at least once) */
boolean opened_once;
int ifd;
- /* The format which belongs to the BFD.*/
+ /* The format which belongs to the BFD. (object, core, etc.) */
bfd_format format;
file_ptr origin;
/* Remember when output has begun, to stop strange things
- happening. */
+ from happening. */
boolean output_has_begun;
/* Pointer to linked list of sections*/
/* Used for input and output*/
unsigned int symcount;
- /* Symbol table for output BFD*/
+ /* Symbol table for output BFD (with symcount entries) */
struct symbol_cache_entry **outsymbols;
/* Pointer to structure which contains architecture information*/
/* Stuff only useful for archives:*/
PTR arelt_data;
- struct _bfd *my_archive;
- struct _bfd *next;
- struct _bfd *archive_head;
+ struct _bfd *my_archive; /* The containing archive BFD. */
+ struct _bfd *next; /* The next BFD in the archive. */
+ struct _bfd *archive_head; /* The first BFD in the archive. */
boolean has_armap;
/* Used by the back end to hold private data. */
asymbol **ld_symbols;
};
-unsigned int
-bfd_get_reloc_upper_bound PARAMS ((bfd *abfd, asection *sect));
-
-unsigned int
-bfd_canonicalize_reloc
- PARAMS ((bfd *abfd,
- asection *sec,
- arelent **loc,
- asymbol **syms));
-
boolean
bfd_set_file_flags PARAMS ((bfd *abfd, flagword flags));
-void
-bfd_set_reloc
- PARAMS ((bfd *abfd, asection *sec, arelent **rel, unsigned int count)
-
- );
-
boolean
-bfd_set_start_address PARAMS ((bfd *, bfd_vma));
+bfd_set_start_address PARAMS ((bfd *abfd, bfd_vma vma));
long
-bfd_get_mtime PARAMS ((bfd *));
+bfd_get_mtime PARAMS ((bfd *abfd));
long
-bfd_get_size PARAMS ((bfd *));
+bfd_get_size PARAMS ((bfd *abfd));
int
-bfd_get_gp_size PARAMS ((bfd *));
+bfd_get_gp_size PARAMS ((bfd *abfd));
void
-bfd_set_gp_size PARAMS ((bfd *, int));
+bfd_set_gp_size PARAMS ((bfd *abfd, int i));
bfd_vma
bfd_scan_vma PARAMS ((CONST char *string, CONST char **end, int base));
#define bfd_seclet_link(abfd, data, relocateable) \
BFD_SEND (abfd, _bfd_seclet_link, (abfd, data, relocateable))
symindex
-bfd_get_next_mapent PARAMS ((bfd *, symindex previous, carsym ** sym));
+bfd_get_next_mapent PARAMS ((bfd *abfd, symindex previous, carsym **sym));
boolean
bfd_set_archive_head PARAMS ((bfd *output, bfd *new_head));
bfd *
-bfd_get_elt_at_index PARAMS ((bfd * archive, int index));
+bfd_get_elt_at_index PARAMS ((bfd *archive, int index));
-bfd*
+bfd *
bfd_openr_next_archived_file PARAMS ((bfd *archive, bfd *previous));
CONST char *
-bfd_core_file_failing_command PARAMS ((bfd *));
+bfd_core_file_failing_command PARAMS ((bfd *abfd));
int
-bfd_core_file_failing_signal PARAMS ((bfd *));
+bfd_core_file_failing_signal PARAMS ((bfd *abfd));
boolean
core_file_matches_executable_p
PTR backend_data;
} bfd_target;
bfd_target *
-bfd_find_target PARAMS ((CONST char *, bfd *));
+bfd_find_target PARAMS ((CONST char *target_name, bfd *abfd));
CONST char **
bfd_target_list PARAMS ((void));
bfd_check_format PARAMS ((bfd *abfd, bfd_format format));
boolean
-bfd_set_format PARAMS ((bfd *, bfd_format));
+bfd_set_format PARAMS ((bfd *abfd, bfd_format format));
CONST char *
-bfd_format_string PARAMS ((bfd_format));
+bfd_format_string PARAMS ((bfd_format format));
#endif
SECTION
<<typedef bfd>>
- A BFD is has type <<bfd>>; objects of this type are the
- cornerstone of any application using <<libbfd>>. References
- though the BFD and to data in the BFD give the entire BFD
- functionality.
+ A BFD has type <<bfd>>; objects of this type are the
+ cornerstone of any application using <<libbfd>>. Using BFD
+ consists of making references though the BFD and to data in the BFD.
- Here is the struct used to define the type <<bfd>>. This
- contains the major data about the file, and contains pointers
+ Here is the structure that defines the type <<bfd>>. It
+ contains the major data about the file and pointers
to the rest of the data.
CODE_FRAGMENT
. boolean cacheable;
.
. {* Marks whether there was a default target specified when the
-. BFD was opened. This is used to select what matching algorithm
-. to use to chose the back end. *}
+. BFD was opened. This is used to select which matching algorithm
+. to use to choose the back end. *}
.
. boolean target_defaulted;
.
. struct _bfd *lru_prev, *lru_next;
.
. {* When a file is closed by the caching routines, BFD retains
-. state information on the file here:
-. *}
+. state information on the file here: *}
.
. file_ptr where;
.
-. {* and here:*}
+. {* and here: (``once'' means at least once) *}
.
. boolean opened_once;
.
.
. int ifd;
.
-. {* The format which belongs to the BFD.*}
+. {* The format which belongs to the BFD. (object, core, etc.) *}
.
. bfd_format format;
.
. file_ptr origin;
.
. {* Remember when output has begun, to stop strange things
-. happening. *}
+. from happening. *}
. boolean output_has_begun;
.
. {* Pointer to linked list of sections*}
. {* Used for input and output*}
. unsigned int symcount;
.
-. {* Symbol table for output BFD*}
+. {* Symbol table for output BFD (with symcount entries) *}
. struct symbol_cache_entry **outsymbols;
.
. {* Pointer to structure which contains architecture information*}
.
. {* Stuff only useful for archives:*}
. PTR arelt_data;
-. struct _bfd *my_archive;
-. struct _bfd *next;
-. struct _bfd *archive_head;
+. struct _bfd *my_archive; {* The containing archive BFD. *}
+. struct _bfd *next; {* The next BFD in the archive. *}
+. struct _bfd *archive_head; {* The first BFD in the archive. *}
. boolean has_armap;
.
. {* Used by the back end to hold private data. *}
}
}
- \f
-/** Symbols */
-
-
-/*
-FUNCTION
- bfd_get_reloc_upper_bound
-
-SYNOPSIS
- unsigned int bfd_get_reloc_upper_bound(bfd *abfd, asection *sect);
-
-DESCRIPTION
- This function return the number of bytes required to store the
- relocation information associated with section <<sect>>
- attached to bfd <<abfd>>
-
-*/
-
-
-unsigned int
-DEFUN(bfd_get_reloc_upper_bound,(abfd, asect),
- bfd *abfd AND
- sec_ptr asect)
-{
- if (abfd->format != bfd_object) {
- bfd_error = invalid_operation;
- return 0;
- }
-
- return BFD_SEND (abfd, _get_reloc_upper_bound, (abfd, asect));
-}
-
-/*
-FUNCTION
- bfd_canonicalize_reloc
-
-SYNOPSIS
- unsigned int bfd_canonicalize_reloc
- (bfd *abfd,
- asection *sec,
- arelent **loc,
- asymbol **syms);
-
-DESCRIPTION
- This function calls the back end associated with the open
- <<abfd>> and translates the external form of the relocation
- information attached to <<sec>> into the internal canonical
- form. The table is placed into memory at <<loc>>, which has
- been preallocated, usually by a call to
- <<bfd_get_reloc_upper_bound>>.
-
- The <<syms>> table is also needed for horrible internal magic
- reasons.
-
-
-*/
-unsigned int
-DEFUN(bfd_canonicalize_reloc,(abfd, asect, location, symbols),
- bfd *abfd AND
- sec_ptr asect AND
- arelent **location AND
- asymbol **symbols)
-{
- if (abfd->format != bfd_object) {
- bfd_error = invalid_operation;
- return 0;
- }
- return BFD_SEND (abfd, _bfd_canonicalize_reloc,
- (abfd, asect, location, symbols));
- }
-
/*
FUNCTION
boolean bfd_set_file_flags(bfd *abfd, flagword flags);
DESCRIPTION
- This function attempts to set the flag word in the referenced
- BFD structure to the value supplied.
+ Set the flag word in the BFD @var{abfd} to the value @var{flags}.
Possible errors are:
o wrong_format - The target bfd was not of object format.
o invalid_operation - The target bfd was open for reading.
o invalid_operation -
The flag word contained a bit which was not applicable to the
- type of file. eg, an attempt was made to set the D_PAGED bit
- on a bfd format which does not support demand paging
+ type of file. E.g., an attempt was made to set the D_PAGED bit
+ on a bfd format which does not support demand paging.
*/
return true;
}
-/*
-FUNCTION
- bfd_set_reloc
-
-SYNOPSIS
- void bfd_set_reloc
- (bfd *abfd, asection *sec, arelent **rel, unsigned int count)
-
-DESCRIPTION
- This function sets the relocation pointer and count within a
- section to the supplied values.
-
-*/
-/*ARGSUSED*/
-void
-bfd_set_reloc (ignore_abfd, asect, location, count)
- bfd *ignore_abfd;
- sec_ptr asect;
- arelent **location;
- unsigned int count;
-{
- asect->orelocation = location;
- asect->reloc_count = count;
-}
-
void
bfd_assert(file, line)
char *file;
FUNCTION
bfd_set_start_address
+SYNOPSIS
+ boolean bfd_set_start_address(bfd *abfd, bfd_vma vma);
+
DESCRIPTION
- Marks the entry point of an output BFD.
+ Make @var{vma} the entry point of output BFD @var{abfd}.
RETURNS
Returns <<true>> on success, <<false>> otherwise.
-
-SYNOPSIS
- boolean bfd_set_start_address(bfd *, bfd_vma);
*/
boolean
/*
FUNCTION
- The bfd_get_mtime function
+ bfd_get_mtime
SYNOPSIS
- long bfd_get_mtime(bfd *);
+ long bfd_get_mtime(bfd *abfd);
DESCRIPTION
- Return file modification time (as read from file system, or
- from archive header for archive members).
+ Return the file modification time (as read from the file system, or
+ from the archive header for archive members).
*/
/*
FUNCTION
- The bfd_get_size function
+ bfd_get_size
SYNOPSIS
- long bfd_get_size(bfd *);
+ long bfd_get_size(bfd *abfd);
DESCRIPTION
- Return file size (as read from file system) for the file
- associated with a bfd.
+ Return the file size (as read from file system) for the file
+ associated with BFD @var{abfd}.
- Note that the initial motivation for, and use of, this routine is not
- so we can get the exact size of the object the bfd applies to, since
- that might not be generally possible (archive members for example?).
- Although it would be ideal if someone could eventually modify
+ The initial motivation for, and use of, this routine is not
+ so we can get the exact size of the object the BFD applies to, since
+ that might not be generally possible (archive members for example).
+ It would be ideal if someone could eventually modify
it so that such results were guaranteed.
Instead, we want to ask questions like "is this NNN byte sized
object I'm about to try read from file offset YYY reasonable?"
- As as example of where we might want to do this, some object formats
- use string tables for which the first sizeof(long) bytes of the table
- contain the size of the table itself, including the size bytes.
+ As as example of where we might do this, some object formats
+ use string tables for which the first <<sizeof(long)>> bytes of the
+ table contain the size of the table itself, including the size bytes.
If an application tries to read what it thinks is one of these
string tables, without some way to validate the size, and for
some reason the size is wrong (byte swapping error, wrong location
- for the string table, etc), the only clue is likely to be a read
+ for the string table, etc.), the only clue is likely to be a read
error when it tries to read the table, or a "virtual memory
- exhausted" error when it tries to allocated 15 bazillon bytes
+ exhausted" error when it tries to allocate 15 bazillon bytes
of space for the 15 bazillon byte table it is about to read.
This function at least allows us to answer the quesion, "is the
size reasonable?".
/*
FUNCTION
- The bfd_get_gp_size function
+ bfd_get_gp_size
SYNOPSIS
- int bfd_get_gp_size(bfd *);
+ int bfd_get_gp_size(bfd *abfd);
DESCRIPTION
- Get the maximum size of objects to be optimized using the GP
+ Return the maximum size of objects to be optimized using the GP
register under MIPS ECOFF. This is typically set by the -G
argument to the compiler, assembler or linker.
*/
/*
FUNCTION
- The bfd_set_gp_size function
+ bfd_set_gp_size
SYNOPSIS
- void bfd_set_gp_size(bfd *, int);
+ void bfd_set_gp_size(bfd *abfd, int i);
DESCRIPTION
Set the maximum size of objects to be optimized using the GP
FUNCTION
bfd_scan_vma
+SYNOPSIS
+ bfd_vma bfd_scan_vma(CONST char *string, CONST char **end, int base);
+
DESCRIPTION
- Converts, like strtoul, a numerical expression as a
- string into a bfd_vma integer, and returns that integer.
- (Though without as many bells and whistles as strtoul.)
+ Convert, like <<strtoul>>, a numerical expression
+ @var{string} into a bfd_vma integer, and returns that integer.
+ (Though without as many bells and whistles as <<strtoul>>.)
The expression is assumed to be unsigned (i.e. positive).
- If given a base, it is used as the base for conversion.
+ If given a @var{base}, it is used as the base for conversion.
A base of 0 causes the function to interpret the string
in hex if a leading "0x" or "0X" is found, otherwise
in octal if a leading zero is found, otherwise in decimal.
Overflow is not detected.
-
-SYNOPSIS
- bfd_vma bfd_scan_vma(CONST char *string, CONST char **end, int base);
*/
bfd_vma
stuff
DESCRIPTION
- stuff which should be documented
+ Stuff which should be documented:
.#define bfd_sizeof_headers(abfd, reloc) \
. BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc))
/*
SECTION
- File Caching
+ File caching
The file caching mechanism is embedded within BFD and allows
the application to open as many BFDs as it wants without
limit (often as low as 20 open files). The module in
<<cache.c>> maintains a least recently used list of
<<BFD_CACHE_MAX_OPEN>> files, and exports the name
- <<bfd_cache_lookup>> which runs around and makes sure that
+ <<bfd_cache_lookup>>, which runs around and makes sure that
the required BFD is open. If not, then it chooses a file to
close, closes it and opens the one wanted, returning its file
handle.
*/
+static boolean
+bfd_cache_delete PARAMS ((bfd *));
+
+/* Number of bfds on the chain. All such bfds have their file open;
+ if it closed, they get snipd()d from the chain. */
+
static int open_files;
static bfd *cache_sentinel; /* Chain of BFDs with active fds we've
bfd *bfd_last_cache;
/*
- * INTERNAL_FUNCTION
- * bfd_cache_lookup
- *
- * DESCRIPTION
- * Checks to see if the required BFD is the same as the last one
- * looked up. If so then it can use the iostream in the BFD with
- * impunity, since it can't have changed since the last lookup,
- * otherwise it has to perform the complicated lookup function
- *
- * .#define bfd_cache_lookup(x) \
- * . ((x)==bfd_last_cache? \
- * . (FILE*)(bfd_last_cache->iostream): \
- * . bfd_cache_lookup_worker(x))
- *
- *
+ INTERNAL_FUNCTION
+ bfd_cache_lookup
+
+ DESCRIPTION
+ Check to see if the required BFD is the same as the last one
+ looked up. If so, then it can use the stream in the BFD with
+ impunity, since it can't have changed since the last lookup;
+ otherwise, it has to perform the complicated lookup function.
+
+ .#define bfd_cache_lookup(x) \
+ . ((x)==bfd_last_cache? \
+ . (FILE*)(bfd_last_cache->iostream): \
+ . bfd_cache_lookup_worker(x))
+
+
*/
-static boolean EXFUN(bfd_cache_delete,(bfd *));
-
-
static void
DEFUN_VOID(close_one)
{
}
\f
-/*
-INTERNAL_FUNCTION
- bfd_cache_init
-
-SYNOPSIS
- void bfd_cache_init (bfd *);
-
-DESCRIPTION
- Initialize a BFD by putting it on the cache LRU.
-*/
+/* Initialize a BFD by putting it on the cache LRU. */
void
DEFUN(bfd_cache_init,(abfd),
bfd *abfd)
{
+ if (open_files >= BFD_CACHE_MAX_OPEN)
+ close_one ();
cache_sentinel = insert(abfd, cache_sentinel);
+ ++open_files;
}
INTERNAL_FUNCTION
bfd_cache_close
+SYNOPSIS
+ boolean bfd_cache_close (bfd *abfd);
+
DESCRIPTION
- Remove the BFD from the cache. If the attached file is open,
+ Remove the BFD @var{abfd} from the cache. If the attached file is open,
then close it too.
-SYNOPSIS
- boolean bfd_cache_close (bfd *);
-
RETURNS
<<false>> is returned if closing the file fails, <<true>> is
returned if all is well.
INTERNAL_FUNCTION
bfd_open_file
+SYNOPSIS
+ FILE* bfd_open_file(bfd *abfd);
+
DESCRIPTION
- Call the OS to open a file for this BFD. Returns the FILE *
- (possibly null) that results from this operation. Sets up the
- BFD so that future accesses know the file is open. If the FILE
- * returned is null, then there is won't have been put in the
+ Call the OS to open a file for @var{abfd}. Return the <<FILE *>>
+ (possibly NULL) that results from this operation. Set up the
+ BFD so that future accesses know the file is open. If the <<FILE *>>
+ returned is NULL, then it won't have been put in the
cache, so it won't have to be removed from it.
-
-SYNOPSIS
- FILE* bfd_open_file(bfd *);
*/
FILE *
}
if (abfd->iostream) {
- open_files++;
bfd_cache_init (abfd);
}
INTERNAL_FUNCTION
bfd_cache_lookup_worker
+SYNOPSIS
+ FILE *bfd_cache_lookup_worker(bfd *abfd);
+
DESCRIPTION
Called when the macro <<bfd_cache_lookup>> fails to find a
- quick answer. Finds a file descriptor for this BFD. If
- necessary, it open it. If there are already more than
- BFD_CACHE_MAX_OPEN files open, it trys to close one first, to
+ quick answer. Find a file descriptor for @var{abfd}. If
+ necessary, it open it. If there are already more than
+ <<BFD_CACHE_MAX_OPEN>> files open, it tries to close one first, to
avoid running out of file descriptors.
-SYNOPSIS
- FILE *bfd_cache_lookup_worker(bfd *);
-
*/
FILE *
coff backends
BFD supports a number of different flavours of coff format.
- The major difference between formats are the sizes and
+ The major differences between formats are the sizes and
alignments of fields in structures on disk, and the occasional
extra field.
- Coff in all its varieties is implimented with a few common
+ Coff in all its varieties is implemented with a few common
files and a number of implementation specific files. For
example, The 88k bcs coff format is implemented in the file
- @code{coff-m88k.c}. This file @code{#include}s
- @code{coff/m88k.h} which defines the external structure of the
- coff format for the 88k, and @code{coff/internal.h} which
- defines the internal structure. @code{coff-m88k.c} also
+ @file{coff-m88k.c}. This file @code{#include}s
+ @file{coff/m88k.h} which defines the external structure of the
+ coff format for the 88k, and @file{coff/internal.h} which
+ defines the internal structure. @file{coff-m88k.c} also
defines the relocations used by the 88k format
@xref{Relocations}.
The Intel i960 processor version of coff is implemented in
- @code{coff-i960.c}. This file has the same structure as
- @code{coff-m88k.c}, except that it includes @code{coff/i960.h}
- rather than @code{coff-m88k.h}.
+ @file{coff-i960.c}. This file has the same structure as
+ @file{coff-m88k.c}, except that it includes @file{coff/i960.h}
+ rather than @file{coff-m88k.h}.
SUBSECTION
- Porting To A New Version of Coff
+ Porting to a new version of coff
The recommended method is to select from the existing
- implimentations the version of coff which is most like the one
- you want to use, for our purposes, we'll say that i386 coff is
+ implementations the version of coff which is most like the one
+ you want to use. For example, we'll say that i386 coff is
the one you select, and that your coff flavour is called foo.
- Copy the @code{i386coff.c} to @code{foocoff.c}, copy
- @code{../include/coff/i386.h} to @code{../include/coff/foo.h}
- and add the lines to @code{targets.c} and @code{Makefile.in}
+ Copy @file{i386coff.c} to @file{foocoff.c}, copy
+ @file{../include/coff/i386.h} to @file{../include/coff/foo.h},
+ and add the lines to @file{targets.c} and @file{Makefile.in}
so that your new back end is used. Alter the shapes of the
- structures in @code{../include/coff/foo.h} so that they match
+ structures in @file{../include/coff/foo.h} so that they match
what you need. You will probably also have to add
- @code{#ifdef}s to the code in @code{coff/internal.h} and
- @code{coffcode.h} if your version of coff is too wild.
+ @code{#ifdef}s to the code in @file{coff/internal.h} and
+ @file{coffcode.h} if your version of coff is too wild.
You can verify that your new BFD backend works quite simply by
- building @code{objdump} from the @code{binutils} directory,
- and making sure that its version of what's going on at your
- host systems idea (assuming it has the pretty standard coff
- dump utility (usually called @code{att-dump} or just
- @code{dump})) are the same. Then clean up your code, and send
+ building @file{objdump} from the @file{binutils} directory,
+ and making sure that its version of what's going on and your
+ host system's idea (assuming it has the pretty standard coff
+ dump utility, usually called @code{att-dump} or just
+ @code{dump}) are the same. Then clean up your code, and send
what you've done to Cygnus. Then your stuff will be in the
next release, and you won't have to keep integrating it.
SUBSECTION
- How The Coff Backend Works
+ How the coff backend works
SUBSUBSECTION
- File Layout
+ File layout
The Coff backend is split into generic routines that are
applicable to any Coff target and routines that are specific
structure, one of which exists for each target.
The essentially similar target-specific routines are in
- @file{coffcode.h}. This header file includes executable code.
+ @file{coffcode.h}. This header file includes executable C code.
The various Coff targets first include the appropriate Coff
header file, make any special defines that are needed, and
then include @file{coffcode.h}.
target.
SUBSUBSECTION
- Bit Twiddling
+ Bit twiddling
Each flavour of coff supported in BFD has its own header file
- descibing the external layout of the structures. There is also
- an internal description of the coff layout (in
- @code{coff/internal.h}). A major function of the
+ describing the external layout of the structures. There is also
+ an internal description of the coff layout, in
+ @file{coff/internal.h}. A major function of the
coff backend is swapping the bytes and twiddling the bits to
translate the external form of the structures into the normal
internal form. This is all performed in the
@code{bfd_swap}_@i{thing}_@i{direction} routines. Some
elements are different sizes between different versions of
- coff, it is the duty of the coff version specific include file
+ coff; it is the duty of the coff version specific include file
to override the definitions of various packing routines in
- @code{coffcode.h}. Eg the size of line number entry in coff is
+ @file{coffcode.h}. E.g., the size of line number entry in coff is
sometimes 16 bits, and sometimes 32 bits. @code{#define}ing
@code{PUT_LNSZ_LNNO} and @code{GET_LNSZ_LNNO} will select the
correct one. No doubt, some day someone will find a version of
- coff which has a varying field size not catered for at the
+ coff which has a varying field size not catered to at the
moment. To port BFD, that person will have to add more @code{#defines}.
Three of the bit twiddling routines are exported to
@code{gdb}; @code{coff_swap_aux_in}, @code{coff_swap_sym_in}
@code{coff_swap_scnhdr_out}. @code{Gas} currently keeps track
of all the symbol table and reloc drudgery itself, thereby
saving the internal BFD overhead, but uses BFD to swap things
- on the way out, making cross ports much safer. This also
+ on the way out, making cross ports much safer. Doing so also
allows BFD (and thus the linker) to use the same header files
as @code{gas}, which makes one avenue to disaster disappear.
SUBSUBSECTION
- Symbol Reading
+ Symbol reading
The simple canonical form for symbols used by BFD is not rich
enough to keep all the information available in a coff symbol
- table. The back end gets around this by keeping the original
+ table. The back end gets around this problem by keeping the original
symbol table around, "behind the scenes".
When a symbol table is requested (through a call to
- @code{bfd_canonicalize_symtab}, a request gets through to
+ @code{bfd_canonicalize_symtab}), a request gets through to
@code{coff_get_normalized_symtab}. This reads the symbol table from
the coff file and swaps all the structures inside into the
internal form. It also fixes up all the pointers in the table
(represented in the file by offsets from the first symbol in
the table) into physical pointers to elements in the new
internal table. This involves some work since the meanings of
- fields changes depending upon context; a field that is a
+ fields change depending upon context: a field that is a
pointer to another structure in the symbol table at one moment
- may be the size in bytes of a structure in the next. Another
+ may be the size in bytes of a structure at the next. Another
pass is made over the table. All symbols which mark file names
(<<C_FILE>> symbols) are modified so that the internal
string points to the value in the auxent (the real filename)
At this time the symbol names are moved around. Coff stores
all symbols less than nine characters long physically
- within the symbol table, longer strings are kept at the end of
+ within the symbol table; longer strings are kept at the end of
the file in the string table. This pass moves all strings
- into memory, and replaces them with pointers to the strings.
+ into memory and replaces them with pointers to the strings.
The symbol table is massaged once again, this time to create
the canonical table used by the BFD application. Each symbol
is inspected in turn, and a decision made (using the
@code{sclass} field) about the various flags to set in the
- @code{asymbol} @xref{Symbols}. The generated canonical table
+ @code{asymbol}. @xref{Symbols}. The generated canonical table
shares strings with the hidden internal symbol table.
Any linenumbers are read from the coff file too, and attached
to the symbols which own the functions the linenumbers belong to.
SUBSUBSECTION
- Symbol Writing
+ Symbol writing
Writing a symbol to a coff file which didn't come from a coff
file will lose any debugging information. The @code{asymbol}
- structure remembers the BFD from which was born, and on output
- the back end makes sure that the same destination target as
+ structure remembers the BFD from which the symbol was taken, and on
+ output the back end makes sure that the same destination target as
source target is present.
When the symbols have come from a coff file then all the
0x100, would have the value 0x20. Coff expects symbols to
contain their final value, so symbols have their values
changed at this point to reflect their sum with their owning
- section. Note that this transformation uses the
+ section. This transformation uses the
<<output_section>> field of the @code{asymbol}'s
@code{asection} @xref{Sections}.
- o coff_mangle_symbols
+ o <<coff_mangle_symbols>>
This routine runs though the provided symbol table and uses
the offsets generated by the previous pass and the pointers
generated when the symbol table was read in to create the
structured hierachy required by coff. It changes each pointer
- to a symbol to an index into the symbol table of the symbol
- being referenced.
+ to a symbol into the index into the symbol table of the asymbol.
- o coff_write_symbols
+ o <<coff_write_symbols>>
This routine runs through the symbol table and patches up the
symbols from their internal form into the coff way, calls the
- bit twiddlers and writes out the tabel to the file.
+ bit twiddlers, and writes out the table to the file.
*/
coff_symbol_type
DESCRIPTION
- The hidden information for an asymbol is described in a
- coff_ptr_struct, which is typedefed to a combined_entry_type
+ The hidden information for an <<asymbol>> is described in a
+ <<combined_entry_type>>:
CODE_FRAGMENT
.
CODE_FRAGMENT
-Special entry points for gdb to swap in coff symbol table parts
+Special entry points for gdb to swap in coff symbol table parts:
.typedef struct
.{
. void (*_bfd_coff_swap_aux_in) PARAMS ((
. PTR in));
.
-Special entry points for gas to swap coff parts
+Special entry points for gas to swap out coff parts:
. unsigned int (*_bfd_coff_swap_aux_out) PARAMS ((
. bfd *abfd,
.
Special entry points for generic COFF routines to call target
-dependent COFF routines
+dependent COFF routines:
. unsigned int _bfd_filhsz;
. unsigned int _bfd_aoutsz;
case I386MAGIC:
case I386PTXMAGIC:
case I386AIXMAGIC: /* Danbury PS/2 AIX C Compiler */
- case I386LYNXMAGIC:
+ case LYNXCOFFMAGIC: /* shadows the m68k Lynx number below, sigh */
arch = bfd_arch_i386;
machine = 0;
break;
#endif
#ifdef APOLLOM68KMAGIC
case APOLLOM68KMAGIC:
+#endif
+#ifdef LYNXCOFFMAGIC
+ case LYNXCOFFMAGIC:
#endif
arch = bfd_arch_m68k;
machine = 68020;
break;
#endif
+#ifdef SPARCMAGIC
+ case SPARCMAGIC:
+ arch = bfd_arch_sparc;
+ machine = 0;
+ break;
+#endif
+
default: /* Unreadable input file type */
arch = bfd_arch_obscure;
break;
/*
SUBSUBSECTION
- Writing Relocations
+ Writing relocations
- To write relocations, all the back end does is step though the
- canonical relocation table, and create an
+ To write relocations, the back end steps though the
+ canonical relocation table and create an
@code{internal_reloc}. The symbol index to use is removed from
- the @code{offset} field in the symbol table supplied, the
+ the @code{offset} field in the symbol table supplied. The
address comes directly from the sum of the section base
- address and the relocation offset and the type is dug directly
+ address and the relocation offset; the type is dug directly
from the howto field. Then the @code{internal_reloc} is
swapped into the shape of an @code{external_reloc} and written
out to disk.
#ifdef I386MAGIC
case bfd_arch_i386:
*magicp = I386MAGIC;
+#ifdef LYNXOS
+ /* Just overwrite the usual value if we're doing Lynx. */
+ *magicp = LYNXCOFFMAGIC;
+#endif
return true;
break;
#endif
*magicp = APOLLO_COFF_VERSION_NUMBER;
#else
*magicp = MC68MAGIC;
+#endif
+#ifdef LYNXOS
+ /* Just overwrite the usual value if we're doing Lynx. */
+ *magicp = LYNXCOFFMAGIC;
#endif
return true;
break;
break;
#endif
+#ifdef SPARCMAGIC
+ case bfd_arch_sparc:
+ *magicp = SPARCMAGIC;
+#ifdef LYNXOS
+ /* Just overwrite the usual value if we're doing Lynx. */
+ *magicp = LYNXCOFFMAGIC;
+#endif
+ return true;
+ break;
+#endif
+
#ifdef H8500MAGIC
case bfd_arch_h8500:
*magicp = H8500MAGIC;
/*
SUBSUBSECTION
- Reading Linenumbers
+ Reading linenumbers
Creating the linenumber table is done by reading in the entire
coff linenumber table, and creating another table for internal use.
- A coff line number table is structured so that each function
+ A coff linenumber table is structured so that each function
is marked as having a line number of 0. Each line within the
function is an offset from the first line in the function. The
base of the line number information for the table is stored in
/*
SUBSUBSECTION
- Reading Relocations
+ Reading relocations
Coff relocations are easily transformed into the internal BFD form
(@code{arelent}).
Reading a coff relocation table is done in the following stages:
- o The entire coff relocation table is read into memory.
+ o Read the entire coff relocation table into memory.
- o Each relocation is processed in turn, first it is swapped from the
+ o Process each relocation in turn; first swap it from the
external to the internal form.
- o The symbol referenced in the relocation's symbol index is
- turned intoa pointer into the canonical symbol table. Note
- that this table is the same as the one returned by a call to
- @code{bfd_canonicalize_symtab}. The back end will call the
+ o Turn the symbol referenced in the relocation's symbol index
+ into a pointer into the canonical symbol table.
+ This table is the same as the one returned by a call to
+ @code{bfd_canonicalize_symtab}. The back end will call that
routine and save the result if a canonicalization hasn't been done.
o The reloc index is turned into a pointer to a howto
Core files
DESCRIPTION
- Buff output this facinating topic
+ These are functions pertaining to core files.
*/
#include "bfd.h"
bfd_core_file_failing_command
SYNOPSIS
- CONST char *bfd_core_file_failing_command(bfd *);
+ CONST char *bfd_core_file_failing_command(bfd *abfd);
DESCRIPTION
- Returns a read-only string explaining what program was running
- when it failed and produced the core file being read
+ Return a read-only string explaining which program was running
+ when it failed and produced the core file @var{abfd}.
*/
bfd_core_file_failing_signal
SYNOPSIS
- int bfd_core_file_failing_signal(bfd *);
+ int bfd_core_file_failing_signal(bfd *abfd);
DESCRIPTION
Returns the signal number which caused the core dump which
- generated the file the BFD is attached to.
+ generated the file the BFD @var{abfd} is attached to.
*/
int
(bfd *core_bfd, bfd *exec_bfd);
DESCRIPTION
- Returns <<true>> if the core file attached to @var{core_bfd}
+ Return <<true>> if the core file attached to @var{core_bfd}
was generated by a run of the executable file attached to
@var{exec_bfd}, or else <<false>>.
*/
SECTION
Constructors
- Classes in C++ have `constructors' and `destructors'. These
+ Classes in C++ have @dfn{constructors} and @dfn{destructors}. These
are functions which are called automatically by the language
whenever data of a class is created or destroyed. Class data
- which is static data may also be have a type which requires
- `construction', the contructor must be called before the data
+ which is static may also be have a type which requires
+ `construction'; the contructor must be called before the data
can be referenced, so the contructor must be called before the
program begins.
The common solution to this problem is for the compiler to
- call a magic function as the first statement <<main>>.
- This magic function, (often called <<__main>>) runs around
+ call a magic function as the first statement before <<main>>.
+ This magic function (often called <<__main>>) runs around
calling the constructors for all the things needing it.
- With COFF the compile has a bargain with the linker et al.
- All constructors are given strange names, for example
+ With COFF, the compiler has a bargain with the linker et al.
+ All constructors are given strange names; for example,
<<__GLOBAL__$I$foo>> might be the label of a contructor for
the class @var{foo}. The solution on unfortunate systems
- (most system V machines) is to perform a partial link on all
+ (most System V machines) is to perform a partial link on all
the <<.o>> files, do an <<nm>> on the result, run <<awk>> or some
such over the result looking for strange <<__GLOBAL__$>>
- symbols, generate a C program from this, compile it and link
+ symbols, generate a C program from this, compile it, and link
with the partially linked input. This process is usually
called <<collect>>.
from the compiler with a special stab code saying that they
are constructors, and the linker can deal with them directly.
- BFD allows applications (ie the linker) to deal with
+ BFD allows applications (i.e., the linker) to deal with
constructor information independently of their external
- implimentation by providing a set of entry points for the
- indiviual object back ends to call which maintains a database
+ implementation by providing a set of entry points for the
+ indiviual object back ends to call to maintain a database
of the contructor information. The application can
interrogate the database to find out what it wants. The
construction data essential for the linker to be able to
The type of symbol, i.e., is it a constructor, a destructor or
something else someone dreamed up to make our lives difficult.
- This module takes this information and then builds extra
- sections attached to the bfds which own the entry points. It
+ The constructor module takes this information and builds extra
+ sections attached to the BFDs which own the entry points. It
creates these sections as if they were tables of pointers to
the entry points, and builds relocation entries to go with
them so that the tables can be relocated along with the data
they reference.
These sections are marked with a special bit
- (<<SEC_CONSTRUCTOR>>) which the linker notices and do with
+ (<<SEC_CONSTRUCTOR>>), which the linker notices and does with
what it wants.
*/
DESCRIPTION
- This function is called with an a symbol describing the
- function to be called, an string which descibes the xtor type,
- e.g., something like "CTOR" or "DTOR" would be fine. And the bfd
- which owns the function. Its duty is to create a section
- called "CTOR" or "DTOR" or whatever if the bfd doesn't already
+ @var{symbol_ptr_ptr} describes the
+ function to be called; @var{type} descibes the xtor type,
+ e.g., something like "CTOR" or "DTOR" would be fine. @var{abfd}
+ is the BFD which owns the function. Create a section
+ called "CTOR" or "DTOR" or whatever if the BFD doesn't already
have one, and grow a relocation table for the entry points as
they accumulate.
bfd *abfd AND
asymbol **symbol_ptr_ptr AND
CONST char *type)
-
{
/* Look up the section we're using to store the table in */
asection *rel_section = bfd_get_section_by_name (abfd, type);
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-/*doc*
-@section File Formats
-A format is a BFD concept of high level file contents. The
-formats supported by BFD are:
-@table @code
-@item bfd_object
-The BFD may contain data, symbols, relocations and debug info.
-@item bfd_archive
-The BFD contains other BFDs and an optional index.
-@item bfd_core
-The BFD contains the result of an executable core dump.
-@end table
+/*
+SECTION
+ File Formats
+
+ A format is a BFD concept of high level file contents type. The
+ formats supported by BFD are:
+
+ o <<bfd_object>>
+
+ The BFD may contain data, symbols, relocations and debug info.
+
+ o <<bfd_archive>>
+
+ The BFD contains other BFDs and an optional index.
+
+ o <<bfd_core>>
+
+ The BFD contains the result of an executable core dump.
+
+
*/
-#include "sysdep.h"
+
#include "bfd.h"
+#include "sysdep.h"
#include "libbfd.h"
-
extern bfd_target *target_vector[];
extern bfd_target *default_vector[];
-/*proto*
-*i bfd_check_format
-This routine is supplied a BFD and a format. It attempts to verify if
-the file attatched to the BFD is indeed compatible with the format
-specified (ie, one of @code{bfd_object}, @code{bfd_archive} or
-@code{bfd_core}).
-
-If the BFD has been set to a specific @var{target} before the call,
-only the named target and format combination will be checked. If the
-target has not been set, or has been set to @code{default} then all
-the known target backends will be interrogated to determine a match.
-
-The function returns @code{true} on success, otherwise @code{false}
-with one of the following error codes:
-@table @code
-@item
-invalid_operation
-if @code{format} is not one of @code{bfd_object}, @code{bfd_archive}
-or @code{bfd_core}.
-@item system_call_error
-if an error occured during a read - even some file mismatches can
-cause system_call_errros
-@item file_not_recognised
-none of the backends recognised the file format
-@item file_ambiguously_recognized
-more than one backend recognised the file format.
-@end table
-*; PROTO(boolean, bfd_check_format, (bfd *abfd, bfd_format format));
-*-*/
+/*
+FUNCTION
+ bfd_check_format
+
+SYNOPSIS
+ boolean bfd_check_format(bfd *abfd, bfd_format format);
+
+DESCRIPTION
+ Verify if the file attached to the BFD @var{abfd} is compatible
+ with the format @var{format} (i.e., one of <<bfd_object>>,
+ <<bfd_archive>> or <<bfd_core>>).
+
+ If the BFD has been set to a specific target before the
+ call, only the named target and format combination is
+ checked. If the target has not been set, or has been set to
+ <<default>>, then all the known target backends is
+ interrogated to determine a match. If the default target
+ matches, it is used. If not, exactly one target must recognize
+ the file, or an error results.
+
+ The function returns <<true>> on success, otherwise <<false>>
+ with one of the following error codes:
+
+ o invalid_operation -
+ if <<format>> is not one of <<bfd_object>>, <<bfd_archive>> or
+ <<bfd_core>>.
+
+ o system_call_error -
+ if an error occured during a read - even some file mismatches
+ can cause system_call_errors.
+
+ o file_not_recognised -
+ none of the backends recognised the file format.
+
+ o file_ambiguously_recognized -
+ more than one backend recognised the file format.
+
+*/
boolean
DEFUN(bfd_check_format,(abfd, format),
if (abfd->format != bfd_unknown)
return (abfd->format == format)? true: false;
+
+ /* Since the target type was defaulted, check them
+ all in the hope that one will be uniquely recognized. */
+
+ save_targ = abfd->xvec;
+ match_count = 0;
+ right_targ = 0;
+
+
/* presume the answer is yes */
abfd->format = format;
abfd->xvec = right_targ; /* Set the target as returned */
return true; /* File position has moved, BTW */
}
- abfd->format = bfd_unknown;
- return false; /* Specified target is not right */
}
- /* Since the target type was defaulted, check them
- all in the hope that one will be uniquely recognized. */
-
- save_targ = abfd->xvec;
- match_count = 0;
- right_targ = 0;
-
for (target = target_vector; *target != NULL; target++) {
bfd_target *temp;
abfd->xvec = *target; /* Change BFD's target temporarily */
bfd_seek (abfd, (file_ptr)0, SEEK_SET);
+ /* If _bfd_check_format neglects to set bfd_error, assume wrong_format.
+ We didn't used to even pay any attention to bfd_error, so I suspect
+ that some _bfd_check_format might have this problem. */
+ bfd_error = wrong_format;
temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
if (temp) { /* This format checks out as ok! */
right_targ = temp;
might match. People who want those other targets have to set
the GNUTARGET variable. */
if (temp == default_vector[0])
- break;
+ {
+ match_count = 1;
+ break;
+ }
#ifdef GNU960
/* Big- and little-endian b.out archives look the same, but it doesn't
* matter: there is no difference in their headers, and member file byte
*/
break;
#endif
+ } else if (bfd_error != wrong_format) {
+ abfd->xvec = save_targ;
+ abfd->format = bfd_unknown;
+ return false;
}
}
file_ambiguously_recognized);
return false;
}
-/*proto*
-*i bfd_set_format
-This function sets the file format of the supplied BFD to the format
-requested. If the target set in the BFD does not support the format
-requested, the format is illegal or the BFD is not open for writing
-than an error occurs.
-*; PROTO(boolean,bfd_set_format,(bfd *, bfd_format));
-*-*/
+
+
+/*
+FUNCTION
+ bfd_set_format
+
+SYNOPSIS
+ boolean bfd_set_format(bfd *abfd, bfd_format format);
+
+DESCRIPTION
+ This function sets the file format of the BFD @var{abfd} to the
+ format @var{format}. If the target set in the BFD does not
+ support the format requested, the format is invalid, or the BFD
+ is not open for writing, then an error occurs.
+
+*/
+
boolean
DEFUN(bfd_set_format,(abfd, format),
bfd *abfd AND
}
-/*proto*
-*i bfd_format_string
-This function takes one argument, and enumerated type (bfd_format) and
-returns a pointer to a const string "invalid", "object", "archive",
-"core" or "unknown" depending upon the value of the enumeration.
-*; PROTO(CONST char *, bfd_format_string, (bfd_format));
-*-*/
+/*
+FUNCTION
+ bfd_format_string
+
+SYNOPSIS
+ CONST char *bfd_format_string(bfd_format format);
+
+DESCRIPTION
+ Return a pointer to a const string
+ <<invalid>>, <<object>>, <<archive>>, <<core>>, or <<unknown>>,
+ depending upon the value of @var{format}.
+*/
CONST char *
DEFUN(bfd_format_string,(format),
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-#include <sysdep.h>
+
#include "bfd.h"
+#include "sysdep.h"
#include "libbfd.h"
+extern void DEFUN_VOID (bfd_section_init);
+
static boolean initialized = false;
-/*proto* bfd_init
+/*
+SECTION
+ Initialization
+
+ These are the functions that handle initializing a BFD.
+*/
+
+/*
+FUNCTION
+ bfd_init
-This routine must be called before any other bfd function to initialize
-magical internal data structures.
+SYNOPSIS
+ void bfd_init(void);
-*; void EXFUN(bfd_init,(void));
+DESCRIPTION
+ This routine must be called before any other libbfd function to
+ initialize magical internal data structures.
*/
-void DEFUN_VOID(bfd_init)
+void
+bfd_init ()
{
if (initialized == false) {
initialized = true;
}
-/*proto-internal* bfd_check_init
+/*
+INTERNAL_FUNCTION
+ bfd_check_init
-This routine is called before any other bfd function using initialized
-data is used to ensure that the structures have been initialized.
-Soon this function will go away, and the bfd library will assume that
-bfd_init has been called.
+SYNOPSIS
+ void bfd_check_init(void);
-*; void EXFUN(bfd_check_init,(void));
+DESCRIPTION
+ This routine is called before any other libbfd function using
+ initialized data. It ensures that the structures have
+ been initialized. Soon this function will go away, and the bfd
+ library will assume that <<bfd_init>> has been called.
*/
-void DEFUN_VOID(bfd_check_init)
+void
+bfd_check_init ()
{
if (initialized == false) {
- fprintf(stderr,"The bfd library now requires you to call bfd_init()\n");
- fprintf(stderr,"before any other calls to bfd routines. Please\n");
- fprintf(stderr,"change your source\n");
bfd_init();
}
}
libbfd
DESCRIPTION
- This file contains various routines which are used within BFD.
+ These routines are used within BFD.
They are not intended for export, but are documented here for
completeness.
*/
PTR bfd_xmalloc( bfd_size_type size);
DESCRIPTION
- Like malloc, but exit if no more memory.
+ Like <<malloc>>, but exit if no more memory.
*/
if (!ptr)
{
write (2, no_memory_message, sizeof(no_memory_message)-1);
- exit (-1);
+ exit (1);
}
return ptr;
}
PTR bfd_xmalloc_by_size_t ( size_t size);
DESCRIPTION
- Like malloc, but exit if no more memory.
- Uses size_t, so it's suitable for use as obstack_chunk_alloc.
+ Like <<malloc>>, but exit if no more memory.
+ Uses <<size_t>>, so it's suitable for use as <<obstack_chunk_alloc>>.
*/
PTR
DEFUN(bfd_xmalloc_by_size_t, (size),
void bfd_write_bigendian_4byte_int(bfd *abfd, int i);
DESCRIPTION
- Writes a 4 byte integer to the outputing bfd, in big endian
- mode regardless of what else is going on. This is useful in
+ Write a 4 byte integer @var{i} to the output BFD @var{abfd}, in big
+ endian order regardless of what else is going on. This is useful in
archives.
*/
/*
FUNCTION
bfd_h_put_size
-FUNCTION
bfd_h_get_size
DESCRIPTION
These macros have the same function as their <<bfd_get_x>>
- bretherin, except that they are used for removing information
+ bretheren, except that they are used for removing information
for the header records of object files. Believe it or not,
some object files keep their header records in big endian
- order, and their data in little endian order.
+ order and their data in little endian order.
.
.{* Byte swapping macros for file header data. *}
.
bfd_log2
DESCRIPTION
- Return the log base 2 of the value supplied, rounded up. eg an
- arg of 1025 would return 11.
+ Return the log base 2 of the value supplied, rounded up. E.g., an
+ @var{x} of 1025 returns 11.
SYNOPSIS
unsigned int bfd_log2(bfd_vma x);
carsym *symdefs; /* the symdef entries */
symindex symdef_count; /* how many there are */
char *extended_names; /* clever intel extension */
-
- time_t armap_timestamp; /* Timestamp value written into armap.
+ /* when more compilers are standard C, this can be a time_t */
+ long armap_timestamp; /* Timestamp value written into armap.
This is used for BSD archives to check
that the timestamp is recent enough
for the BSD linker to not complain,
(FILE*)(bfd_last_cache->iostream): \
bfd_cache_lookup_worker(x))
boolean
-bfd_cache_close PARAMS ((bfd *));
+bfd_cache_close PARAMS ((bfd *abfd));
FILE*
-bfd_open_file PARAMS ((bfd *));
+bfd_open_file PARAMS ((bfd *abfd));
FILE *
-bfd_cache_lookup_worker PARAMS ((bfd *));
+bfd_cache_lookup_worker PARAMS ((bfd *abfd));
void
bfd_constructor_entry PARAMS ((bfd *abfd,
enum bfd_architecture arch,
unsigned long mach));
-void
+void
bfd_arch_init PARAMS ((void));
void
-bfd_arch_linkin PARAMS ((bfd_arch_info_type *));
+bfd_arch_linkin PARAMS ((bfd_arch_info_type *ptr));
CONST bfd_arch_info_type *
bfd_default_compatible
CONST bfd_arch_info_type *b));
boolean
-bfd_default_scan PARAMS ((CONST struct bfd_arch_info *, CONST char *));
+bfd_default_scan PARAMS ((CONST struct bfd_arch_info *info, CONST char *string));
struct elf_internal_shdr *
bfd_elf_find_section PARAMS ((bfd *abfd, char *name));
bfd_openr
SYNOPSIS
- bfd *bfd_openr(CONST char *filename, CONST char*target);
+ bfd *bfd_openr(CONST char *filename, CONST char *target);
DESCRIPTION
- This function opens the file supplied (using <<fopen>>) with the target
- supplied, it returns a pointer to the created BFD.
+ Open the file @var{filename} (using <<fopen>>) with the target
+ @var{target}. Return a pointer to the created BFD.
If NULL is returned then an error has occured. Possible errors
are <<no_memory>>, <<invalid_target>> or <<system_call>> error.
+
+ Calls <<bfd_find_target>>, so @var{target} is interpreted as by
+ that function.
*/
bfd *
bfd *bfd_fdopenr(CONST char *filename, CONST char *target, int fd);
DESCRIPTION
- bfd_fdopenr is to bfd_fopenr much like fdopen is to fopen.
+ <<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to <<fopen>>.
It opens a BFD on a file already described by the @var{fd}
supplied.
- When the file is later bfd_closed, the file descriptor will be closed.
+ When the file is later <<bfd_close>>d, the file descriptor will be closed.
If the caller desires that this file descriptor be cached by BFD
(opened as needed, closed as needed to free descriptors for
file descriptor (but subject to closure at any time), call
bfd_set_cacheable(bfd, 1) on the returned BFD. The default is to
assume no cacheing; the file descriptor will remain open until
- bfd_close, and will not be affected by BFD operations on other
+ <<bfd_close>>, and will not be affected by BFD operations on other
files.
- Possible errors are no_memory, invalid_target and system_call
- error.
+ Possible errors are <<no_memory>>, <<invalid_target>> and <<system_call_error>>.
*/
bfd *
bfd *bfd_openw(CONST char *filename, CONST char *target);
DESCRIPTION
- Creates a BFD, associated with file @var{filename}, using the
- file format @var{target}, and returns a pointer to it.
+ Create a BFD, associated with file @var{filename}, using the
+ file format @var{target}, and return a pointer to it.
- Possible errors are system_call_error, no_memory,
- invalid_target.
+ Possible errors are <<system_call_error>>, <<no_memory>>,
+ <<invalid_target>>.
*/
bfd *
bfd_close
SYNOPSIS
- boolean bfd_close(bfd *);
+ boolean bfd_close(bfd *abfd);
DESCRIPTION
- This function closes a BFD. If the BFD was open for writing,
+ Close a BFD. If the BFD was open for writing,
then pending operations are completed and the file written out
and closed. If the created file is executable, then
<<chmod>> is called to mark it as such.
All memory attached to the BFD's obstacks is released.
The file descriptor associated with the BFD is closed (even
- if it was passed in to BFD by bfd_fdopenr).
+ if it was passed in to BFD by <<bfd_fdopenr>>).
RETURNS
<<true>> is returned if all is ok, otherwise <<false>>.
boolean bfd_close_all_done(bfd *);
DESCRIPTION
- This function closes a BFD. It differs from <<bfd_close>>
+ Close a BFD. Differs from <<bfd_close>>
since it does not complete any pending operations. This
routine would be used if the application had just used BFD for
swapping and didn't want to use any of the writing code.
bfd_size_type bfd_alloc_size(bfd *abfd);
DESCRIPTION
- Return the number of bytes in the obstacks connected to the
- supplied BFD.
+ Return the number of bytes in the obstacks connected to @var{abfd}.
*/
bfd *bfd_create(CONST char *filename, bfd *templ);
DESCRIPTION
- This routine creates a new BFD in the manner of
+ Create a new BFD in the manner of
<<bfd_openw>>, but without opening a file. The new BFD
takes the target from the target used by @var{template}. The
format is always set to <<bfd_object>>.
PTR bfd_alloc_by_size_t(bfd *abfd, size_t wanted);
DESCRIPTION
- This function allocates a block of memory in the obstack
- attatched to <<abfd>> and returns a pointer to it.
+ Allocate a block of @var{wanted} bytes of memory in the obstack
+ attatched to <<abfd>> and return a pointer to it.
*/
SECTION
Relocations
- BFD maintains relocations in much the same was as it maintains
- symbols; they are left alone until required, then read in
- en-mass and traslated into an internal form. There is a common
- routine <<bfd_perform_relocation>> which acts upon the
- canonical form to do the actual fixup.
+ BFD maintains relocations in much the same way it maintains
+ symbols: they are left alone until required, then read in
+ en-mass and translated into an internal form. A common
+ routine <<bfd_perform_relocation>> acts upon the
+ canonical form to do the fixup.
- Note that relocations are maintained on a per section basis,
- whilst symbols are maintained on a per BFD basis.
+ Relocations are maintained on a per section basis,
+ while symbols are maintained on a per BFD basis.
- All a back end has to do to fit the BFD interface is to create
- as many <<struct reloc_cache_entry>> as there are relocations
- in a particular section, and fill in the right bits:
+ All that a back end has to do to fit the BFD interface is to create
+ a <<struct reloc_cache_entry>> for each relocation
+ in a particular section, and fill in the right bits of the structures.
@menu
@* typedef arelent::
. {* Used by special functions *}
. bfd_reloc_continue,
.
-. {* Unused *}
+. {* Unsupported relocation size requested. *}
. bfd_reloc_notsupported,
.
-. {* Unsupported relocation size requested. *}
+. {* Unused *}
. bfd_reloc_other,
.
. {* The symbol to relocate against was undefined. *}
/*
DESCRIPTION
- Here is a description of each of the fields within a relent:
+ Here is a description of each of the fields within an <<arelent>>:
- o sym_ptr_ptr
+ o <<sym_ptr_ptr>>
The symbol table pointer points to a pointer to the symbol
- associated with the relocation request. This would naturally
- be the pointer into the table returned by the back end's
- get_symtab action. @xref{Symbols}. The symbol is referenced
+ associated with the relocation request. It is
+ the pointer into the table returned by the back end's
+ <<get_symtab>> action. @xref{Symbols}. The symbol is referenced
through a pointer to a pointer so that tools like the linker
can fix up all the symbols of the same name by modifying only
one pointer. The relocation routine looks in the symbol and
value of the symbol as the initial relocation offset. If the
symbol pointer is zero, then the section provided is looked up.
- o address
+ o <<address>>
- The address field gives the offset in bytes from the base of
+ The <<address>> field gives the offset in bytes from the base of
the section data which owns the relocation record to the first
byte of relocatable information. The actual data relocated
- will be relative to this point - for example, a relocation
+ will be relative to this point; for example, a relocation
type which modifies the bottom two bytes of a four byte word
would not touch the first byte pointed to in a big endian
world.
- o addend
+ o <<addend>>
- The addend is a value provided by the back end to be added (!)
+ The <<addend>> is a value provided by the back end to be added (!)
to the relocation offset. Its interpretation is dependent upon
the howto. For example, on the 68k the code:
| rts
- This could create a reloc pointing to foo, but leave the
- offset in the data (something like)
+ This could create a reloc pointing to <<foo>>, but leave the
+ offset in the data, something like:
|RELOCATION RECORDS FOR [.text]:
| jmp r1
- This should create two relocs, both pointing to _foo, and with
+ This should create two relocs, both pointing to <<_foo>>, and with
0x12340000 in their addend field. The data would consist of:
The relocation routine digs out the value from the data, adds
- it to the addend to get the original offset and then adds the
- value of _foo. Note that all 32 bits have to be kept around
+ it to the addend to get the original offset, and then adds the
+ value of <<_foo>>. Note that all 32 bits have to be kept around
somewhere, to cope with carry from bit 15 to bit 16.
One further example is the sparc and the a.out format. The
sparc has a similar problem to the 88k, in that some
instructions don't have room for an entire offset, but on the
- sparc the parts are created odd sized lumps. The designers of
- the a.out format chose not to use the data within the section
+ sparc the parts are created in odd sized lumps. The designers of
+ the a.out format chose to not use the data within the section
for storing part of the offset; all the offset is kept within
- the reloc. Any thing in the data should be ignored.
+ the reloc. Anything in the data should be ignored.
| save %sp,-112,%sp
| sethi %hi(_foo+0x12345678),%g2
| ret
| restore
- Both relocs contains a pointer to foo, and the offsets would
+ Both relocs contains a pointer to <<foo>>, and the offsets
contain junk.
|00000010 81e80000 ; restore
- o howto
+ o <<howto>>
- The howto field can be imagined as a
- relocation instruction. It is a pointer to a struct which
- contains information on what to do with all the other
+ The <<howto>> field can be imagined as a
+ relocation instruction. It is a pointer to a structure which
+ contains information on what to do with all of the other
information in the reloc record and data section. A back end
would normally have a relocation instruction set and turn
relocations into pointers to the correct structure on input -
<<reloc_howto_type>>
The <<reloc_howto_type>> is a structure which contains all the
- information that BFD needs to know to tie up a back end's data.
+ information that libbfd needs to know to tie up a back end's data.
CODE_FRAGMENT
.struct symbol_cache_entry; {* Forward declaration *}
.
-.typedef CONST struct reloc_howto_struct
+.typedef struct reloc_howto_struct
.{
. {* The type field has mainly a documetary use - the back end can
-. to what it wants with it, though the normally the back end's
-. external idea of what a reloc number would be would be stored
-. in this field. For example, the a PC relative word relocation
-. in a coff environment would have the type 023 - because that's
+. do what it wants with it, though normally the back end's
+. external idea of what a reloc number is stored
+. in this field. For example, a PC relative word relocation
+. in a coff environment has the type 023 - because that's
. what the outside world calls a R_PCRWORD reloc. *}
. unsigned int type;
.
. relocations rather than the data - this flag signals this.*}
. boolean partial_inplace;
.
-. {* The src_mask is used to select what parts of the read in data
+. {* The src_mask selects which parts of the read in data
. are to be used in the relocation sum. E.g., if this was an 8 bit
. bit of data which we read and relocated, this would be
. 0x000000ff. When we have relocs which have an addend, such as
. the mask would be 0x00000000. *}
. bfd_vma src_mask;
.
-. {* The dst_mask is what parts of the instruction are replaced
+. {* The dst_mask selects which parts of the instruction are replaced
. into the instruction. In most cases src_mask == dst_mask,
. except in the above special case, where dst_mask would be
. 0x000000ff, and src_mask would be 0x00000000. *}
. slot of the instruction, so that a PC relative relocation can
. be made just by adding in an ordinary offset (e.g., sun3 a.out).
. Some formats leave the displacement part of an instruction
-. empty (e.g., m88k bcs), this flag signals the fact.*}
+. empty (e.g., m88k bcs); this flag signals the fact.*}
. boolean pcrel_offset;
.
.} reloc_howto_type;
/*
FUNCTION
- the HOWTO macro
+ The HOWTO Macro
DESCRIPTION
The HOWTO define is horrible and will go away.
DESCRIPTION
And will be replaced with the totally magic way. But for the
- moment, we are compatible, so do it this way..
+ moment, we are compatible, so do it this way.
.#define NEWHOWTO( FUNCTION, NAME,SIZE,REL,IN) HOWTO(0,0,SIZE,0,REL,0,complain_overflow_dont,FUNCTION, NAME,false,0,0,IN)
/*
TYPEDEF
- reloc_chain
+ arelent_chain
DESCRIPTION
- How relocs are tied together
+ How relocs are tied together in an <<asection>>:
.typedef unsigned char bfd_byte;
.
SYNOPSIS
bfd_reloc_status_type
bfd_perform_relocation
- (bfd * abfd,
+ (bfd *abfd,
arelent *reloc_entry,
PTR data,
asection *input_section,
bfd *output_bfd);
DESCRIPTION
- If an output_bfd is supplied to this function the generated
- image will be relocatable, the relocations are copied to the
+ If @var{output_bfd} is supplied to this function, the generated
+ image will be relocatable; the relocations are copied to the
output file after they have been changed to reflect the new
state of the world. There are two ways of reflecting the
- results of partial linkage in an output file; by modifying the
+ results of partial linkage in an output file: by modifying the
output data in place, and by modifying the relocation record.
Some native formats (e.g., basic a.out and basic coff) have no
way of specifying an addend in the relocation type, so the
/* Add in supplied addend. */
relocation += reloc_entry->addend;
+ /* Here the variable relocation holds the final address of the
+ symbol we are relocating against, plus any addend. */
+
if (howto->pc_relative == true)
{
- /* Anything which started out as pc relative should end up that
- way too.
-
- There are two ways we can see a pcrel instruction. Sometimes
- the pcrel displacement has been partially calculated, it
- includes the distance from the start of the section to the
- instruction in it (e.g., sun3), and sometimes the field is
- totally blank - e.g., m88kbcs. */
+ /* This is a PC relative relocation. We want to set RELOCATION
+ to the distance between the address of the symbol and the
+ location. RELOCATION is already the address of the symbol.
+
+ We start by subtracting the address of the section containing
+ the location.
+
+ If pcrel_offset is set, we must further subtract the position
+ of the location within the section. Some targets arrange for
+ the addend to be the negative of the position of the location
+ within the section; for example, i386-aout does this. For
+ i386-aout, pcrel_offset is false. Some other targets do not
+ include the position of the location; for example, m88kbcs,
+ or ELF. For those targets, pcrel_offset is true.
+
+ If we are producing relocateable output, then we must ensure
+ that this reloc will be correctly computed when the final
+ relocation is done. If pcrel_offset is false we want to wind
+ up with the negative of the location within the section,
+ which means we must adjust the existing addend by the change
+ in the location within the section. If pcrel_offset is true
+ we do not want to adjust the existing addend at all.
+
+ FIXME: This seems logical to me, but for the case of
+ producing relocateable output it is not what the code
+ actually does. I don't want to change it, because it seems
+ far too likely that something will break. */
relocation -=
input_section->output_section->vma + input_section->output_offset;
/* WTF?? */
if (abfd->xvec->flavour == bfd_target_coff_flavour)
{
+#if 1
+ /* For m68k-coff, the addend was being subtracted twice during
+ relocation with -r. Removing the line below this comment
+ fixes that problem; see PR 2953.
+
+However, Ian wrote the following, regarding removing the line below,
+which explains why it is still enabled: --djm
+
+If you put a patch like that into BFD you need to check all the COFF
+linkers. I am fairly certain that patch will break coff-i386 (e.g.,
+SCO); see coff_i386_reloc in coff-i386.c where I worked around the
+problem in a different way. There may very well be a reason that the
+code works as it does.
+
+Hmmm. The first obvious point is that bfd_perform_relocation should
+not have any tests that depend upon the flavour. It's seem like
+entirely the wrong place for such a thing. The second obvious point
+is that the current code ignores the reloc addend when producing
+relocateable output for COFF. That's peculiar. In fact, I really
+have no idea what the point of the line you want to remove is.
+
+A typical COFF reloc subtracts the old value of the symbol and adds in
+the new value to the location in the object file (if it's a pc
+relative reloc it adds the difference between the symbol value and the
+location). When relocating we need to preserve that property.
+
+BFD handles this by setting the addend to the negative of the old
+value of the symbol. Unfortunately it handles common symbols in a
+non-standard way (it doesn't subtract the old value) but that's a
+different story (we can't change it without losing backward
+compatibility with old object files) (coff-i386 does subtract the old
+value, to be compatible with existing coff-i386 targets, like SCO).
+
+So everything works fine when not producing relocateable output. When
+we are producing relocateable output, logically we should do exactly
+what we do when not producing relocateable output. Therefore, your
+patch is correct. In fact, it should probably always just set
+reloc_entry->addend to 0 for all cases, since it is, in fact, going to
+add the value into the object file. This won't hurt the COFF code,
+which doesn't use the addend; I'm not sure what it will do to other
+formats (the thing to check for would be whether any formats both use
+the addend and set partial_inplace).
+
+When I wanted to make coff-i386 produce relocateable output, I ran
+into the problem that you are running into: I wanted to remove that
+line. Rather than risk it, I made the coff-i386 relocs use a special
+function; it's coff_i386_reloc in coff-i386.c. The function
+specifically adds the addend field into the object file, knowing that
+bfd_perform_relocation is not going to. If you remove that line, then
+coff-i386.c will wind up adding the addend field in twice. It's
+trivial to fix; it just needs to be done.
+
+The problem with removing the line is just that it may break some
+working code. With BFD it's hard to be sure of anything. The right
+way to deal with this is simply to build and test at least all the
+supported COFF targets. It should be straightforward if time and disk
+space consuming. For each target:
+ 1) build the linker
+ 2) generate some executable, and link it using -r (I would
+ probably use paranoia.o and link against newlib/libc.a, which
+ for all the supported targets would be available in
+ /usr/cygnus/progressive/H-host/target/lib/libc.a).
+ 3) make the change to reloc.c
+ 4) rebuild the linker
+ 5) repeat step 2
+ 6) if the resulting object files are the same, you have at least
+ made it no worse
+ 7) if they are different you have to figure out which version is
+ right
+*/
relocation -= reloc_entry->addend;
+#endif
reloc_entry->addend = 0;
}
else
the relocation to the reloc entry (probably because there isn't
any room in the output format to describe addends to relocs)
*/
- relocation >>= howto->rightshift;
+
+ /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler
+ (OSF version 1.3, compiler version 3.11). It miscompiles the
+ following program:
+
+ struct str
+ {
+ unsigned int i0;
+ } s = { 0 };
+
+ int
+ main ()
+ {
+ unsigned long x;
+
+ x = 0x100000000;
+ x <<= (unsigned long) s.i0;
+ if (x == 0)
+ printf ("failed\n");
+ else
+ printf ("succeeded (%lx)\n", x);
+ }
+ */
+
+ relocation >>= (bfd_vma) howto->rightshift;
/* Shift everything up to where it's going to be used */
- relocation <<= howto->bitpos;
+ relocation <<= (bfd_vma) howto->bitpos;
/* Wait for the day when all have the mask in them */
. {* 16 bit relocation relative to the global pointer. *}
. BFD_RELOC_MIPS_GPREL,
.
+. {* Relocation against a MIPS literal section. *}
+. BFD_RELOC_MIPS_LITERAL,
+.
+. {* MIPS ELF relocations. *}
+. BFD_RELOC_MIPS_GOT16,
+. BFD_RELOC_MIPS_CALL16,
+. BFD_RELOC_MIPS_GPREL32,
+.
. {* These are, so far, specific to HPPA processors. I'm not sure that some
. don't duplicate other reloc types, such as BFD_RELOC_32 and _32_PCREL.
. Also, many more were in the list I got that don't fit in well in the
/*
-SECTION
+FUNCTION
bfd_reloc_type_lookup
SYNOPSIS
bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code);
DESCRIPTION
- This routine returns a pointer to a howto struct which when
- invoked, will perform the supplied relocation on data from the
+ Return a pointer to a howto struct which, when
+ invoked, will perform the relocation @var{code} on data from the
architecture noted.
*/
return data;
+}
+
+ \f
+/** Symbols */
+
+
+/*
+FUNCTION
+ bfd_get_reloc_upper_bound
+
+SYNOPSIS
+ unsigned int bfd_get_reloc_upper_bound(bfd *abfd, asection *sect);
+
+DESCRIPTION
+ Return the number of bytes required to store the
+ relocation information associated with section @var{sect}
+ attached to bfd @var{abfd}.
+
+*/
+
+
+unsigned int
+DEFUN(bfd_get_reloc_upper_bound,(abfd, asect),
+ bfd *abfd AND
+ sec_ptr asect)
+{
+ if (abfd->format != bfd_object) {
+ bfd_error = invalid_operation;
+ return 0;
+ }
+
+ return BFD_SEND (abfd, _get_reloc_upper_bound, (abfd, asect));
+}
+
+/*
+FUNCTION
+ bfd_canonicalize_reloc
+
+SYNOPSIS
+ unsigned int bfd_canonicalize_reloc
+ (bfd *abfd,
+ asection *sec,
+ arelent **loc,
+ asymbol **syms);
+
+DESCRIPTION
+ Call the back end associated with the open BFD
+ @var{abfd} and translate the external form of the relocation
+ information attached to @var{sec} into the internal canonical
+ form. Place the table into memory at @var{loc}, which has
+ been preallocated, usually by a call to
+ <<bfd_get_reloc_upper_bound>>.
+
+ The @var{syms} table is also needed for horrible internal magic
+ reasons.
+
+
+*/
+unsigned int
+DEFUN(bfd_canonicalize_reloc,(abfd, asect, location, symbols),
+ bfd *abfd AND
+ sec_ptr asect AND
+ arelent **location AND
+ asymbol **symbols)
+{
+ if (abfd->format != bfd_object) {
+ bfd_error = invalid_operation;
+ return 0;
+ }
+ return BFD_SEND (abfd, _bfd_canonicalize_reloc,
+ (abfd, asect, location, symbols));
+}
+
+/*
+FUNCTION
+ bfd_set_reloc
+
+SYNOPSIS
+ void bfd_set_reloc
+ (bfd *abfd, sec_ptr *sec, arelent **rel, unsigned int count)
+
+DESCRIPTION
+ Set the relocation pointer and count within
+ section @var{sec} to the values @var{rel} and @var{count}.
+ The argument @var{abfd} is ignored.
+
+*/
+/*ARGSUSED*/
+void
+bfd_set_reloc (ignore_abfd, asect, location, count)
+ bfd *ignore_abfd;
+ sec_ptr asect;
+ arelent **location;
+ unsigned int count;
+{
+ asect->orelocation = location;
+ asect->reloc_count = count;
}
SECTION
Sections
- Sections are supported in BFD in <<section.c>>.
-
The raw data contained within a BFD is maintained through the
section abstraction. A single BFD may have any number of
- sections, and keeps hold of them by pointing to the first,
+ sections. It keeps hold of them by pointing to the first;
each one points to the next in the list.
+ Sections are supported in BFD in <<section.c>>.
+
@menu
@* Section Input::
@* Section Output::
created and attached to the BFD.
Each section has a name which describes the section in the
- outside world - for example, <<a.out>> would contain at least
+ outside world---for example, <<a.out>> would contain at least
three sections, called <<.text>>, <<.data>> and <<.bss>>.
- Sometimes a BFD will contain more than the 'natural' number of
+ Names need not be unique; for example a COFF file may have several
+ sections named <<.data>>.
+
+ Sometimes a BFD will contain more than the ``natural'' number of
sections. A back end may attach other sections containing
constructor data, or an application may add a section (using
- bfd_make_section) to the sections attached to an already open
- BFD. For example, the linker creates a supernumary section
+ <<bfd_make_section>>) to the sections attached to an already open
+ BFD. For example, the linker creates an extra section
<<COMMON>> for each input file's BFD to hold information about
common storage.
- The raw data is not necessarily read in at the same time as
+ The raw data is not necessarily read in when
the section descriptor is created. Some targets may leave the
data in place until a <<bfd_get_section_contents>> call is
- made. Other back ends may read in all the data at once - For
- example; an S-record file has to be read once to determine the
+ made. Other back ends may read in all the data at once. For
+ example, an S-record file has to be read once to determine the
size of the data. An IEEE-695 file doesn't contain raw data in
sections, but data and relocation expressions intermixed, so
the data area has to be parsed to get out the data and
To write a new object style BFD, the various sections to be
written have to be created. They are attached to the BFD in
- the same way as input sections, data is written to the
+ the same way as input sections; data is written to the
sections using <<bfd_set_section_contents>>.
Any program that creates or combines sections (e.g., the assembler
- and linker) must use the fields <<output_section>> and
+ and linker) must use the <<asection>> fields <<output_section>> and
<<output_offset>> to indicate the file sections to which each
section must be written. (If the section is being created from
scratch, <<output_section>> should probably point to the section
- itself, and <<output_offset>> should probably be zero.)
+ itself and <<output_offset>> should probably be zero.)
- The data to be written comes from input sections attached to
+ The data to be written comes from input sections attached
+ (via <<output_section>> pointers) to
the output sections. The output section structure can be
- considered a filter for the input section, the output section
+ considered a filter for the input section: the output section
determines the vma of the output data and the name, but the
input section determines the offset into the output section of
the data to be written.
E.g., to create a section "O", starting at 0x100, 0x123 long,
- containing two subsections, "A" at offset 0x0 (ie at vma
- 0x100) and "B" at offset 0x20 (ie at vma 0x120) the structures
- would look like:
+ containing two subsections, "A" at offset 0x0 (i.e., at vma
+ 0x100) and "B" at offset 0x20 (i.e., at vma 0x120) the <<asection>>
+ structures would look like:
| section name "A"
| output_offset 0x00
SUBSECTION
- Seglets
+ Seclets
- The data within a section is stored in a <<seglet>>. These
- are much like the fixups in <<gas>>. The seglet abstraction
- allows the a section to grow and shrink within itself.
+ The data within a section is stored in a <<seclet>>. These
+ are much like the fixups in <<gas>>. The seclet abstraction
+ allows a section to grow and shrink within itself.
- A seglet knows how big it is, and which is the next seglet and
- where the raw data for it is, and also points to a list of
+ A seclet knows how big it is, and which is the next seclet and
+ where the raw data for it is; it also points to a list of
relocations which apply to it.
- The seglet is used by the linker to perform relaxing on final
- code. The application creates code which is as big as
+ The seclet is used by the linker to perform relaxing on final
+ code. The compiler creates code which is as big as
necessary to make it work without relaxing, and the user can
select whether to relax. Sometimes relaxing takes a lot of
time. The linker runs around the relocations to see if any
are attached to data which can be shrunk, if so it does it on
- a seglet by seglet basis.
+ a seclet by seclet basis.
*/
SUBSECTION
typedef asection
- The shape of a section struct:
+ Here is the section structure:
CODE_FRAGMENT
.
.typedef struct sec
.{
-. {* The name of the section, the name isn't a copy, the pointer is
+. {* The name of the section; the name isn't a copy, the pointer is
. the same as that passed to bfd_make_section. *}
.
. CONST char *name;
.
-. {* Which section is it 0.nth *}
+. {* Which section is it; 0..nth. *}
.
. int index;
.
.
. struct sec *next;
.
-. {* The field flags contains attributes of the section. Some of
+. {* The field flags contains attributes of the section. Some
. flags are read in from the object file, and some are
. synthesized from other information. *}
.
.
.#define SEC_NO_FLAGS 0x000
.
-. {* Tells the OS to allocate space for this section when loaded.
-. This would clear for a section containing debug information
+. {* Tells the OS to allocate space for this section when loading.
+. This is clear for a section containing debug information
. only. *}
.#define SEC_ALLOC 0x001
.
. {* Tells the OS to load the section from the file when loading.
-. This would be clear for a .bss section *}
+. This is clear for a .bss section. *}
.#define SEC_LOAD 0x002
.
-. {* The section contains data still to be relocated, so there will
-. be some relocation information too. *}
+. {* The section contains data still to be relocated, so there is
+. some relocation information too. *}
.#define SEC_RELOC 0x004
.
.#if 0 {* Obsolete ? *}
. type is used by the linker to create lists of constructors and
. destructors used by <<g++>>. When a back end sees a symbol
. which should be used in a constructor list, it creates a new
-. section for the type of name (eg <<__CTOR_LIST__>>), attaches
-. the symbol to it and builds a relocation. To build the lists
-. of constructors, all the linker has to to is catenate all the
-. sections called <<__CTOR_LIST__>> and relocte the data
+. section for the type of name (e.g., <<__CTOR_LIST__>>), attaches
+. the symbol to it, and builds a relocation. To build the lists
+. of constructors, all the linker has to do is catenate all the
+. sections called <<__CTOR_LIST__>> and relocate the data
. contained within - exactly the operations it would peform on
. standard data. *}
.#define SEC_CONSTRUCTOR 0x100
.#define SEC_CONSTRUCTOR_BSS 0x3100
.
. {* The section has contents - a data section could be
-. <<SEC_ALLOC>> | <<SEC_HAS_CONTENTS>>, a debug section could be
+. <<SEC_ALLOC>> | <<SEC_HAS_CONTENTS>>; a debug section could be
. <<SEC_HAS_CONTENTS>> *}
.#define SEC_HAS_CONTENTS 0x200
.
-. {* An instruction to the linker not to output sections
-. containing this flag even if they have information which
-. would normally be written. *}
+. {* An instruction to the linker to not output the section
+. even if it has information which would normally be written. *}
.#define SEC_NEVER_LOAD 0x400
.
. {* The section is a shared library section. The linker must leave
. translate to bfd_com_section), but ECOFF has two. *}
.#define SEC_IS_COMMON 0x8000
.
+. {* The section contains only debugging information. For
+. example, this is set for ELF .debug and .stab sections.
+. strip tests this flag to see if a section can be
+. discarded. *}
+.#define SEC_DEBUGGING 0x10000
+.
. {* End of section flags. *}
.
. {* The virtual memory address of the section - where it will be
. boolean user_set_vma;
.
. {* The load address of the section - where it would be in a
-. rom image, really only used for writing section header
+. rom image; really only used for writing section header
. information. *}
.
. bfd_vma lma;
.
. {* The size of the section in bytes, as it will be output.
-. contains a value even if the section has no contents (eg, the
+. contains a value even if the section has no contents (e.g., the
. size of <<.bss>>). This will be filled in after relocation *}
.
. bfd_size_type _cooked_size;
.
-. {* The size on disk of the section in bytes originally. Normally this
+. {* The original size on disk of the section, in bytes. Normally this
. value is the same as the size, but if some relaxing has
. been done, then this value will be bigger. *}
.
.
. {* If this section is going to be output, then this value is the
. offset into the output section of the first byte in the input
-. section. Eg, if this was going to start at the 100th byte in
+. section. E.g., if this was going to start at the 100th byte in
. the output section, this value would be 100. *}
.
. bfd_vma output_offset;
.
. struct sec *output_section;
.
-. {* The alignment requirement of the section, as an exponent - eg
-. 3 aligns to 2^3 (or 8) *}
+. {* The alignment requirement of the section, as an exponent of 2 -
+. e.g., 3 aligns to 2^3 (or 8). *}
.
. unsigned int alignment_power;
.
.
. file_ptr moving_line_filepos;
.
-. {* what the section number is in the target world *}
+. {* What the section number is in the target world *}
.
. int target_index;
.
section prototypes
These are the functions exported by the section handling part of
-<<libbfd>.
+<<libbfd>>.
*/
/*
asection *bfd_get_section_by_name(bfd *abfd, CONST char *name);
DESCRIPTION
- Runs through the provided @var{abfd} and returns the
- <<asection>> who's name matches that provided, otherwise NULL.
+ Run through the provided @var{abfd} and return the one of the
+ <<asection>>s whose name matches @var{name}, otherwise NULL.
@xref{Sections}, for more information.
+ This should only be used in special cases; the normal way to process
+ all sections of a given name is to use bfd_map_over_sections and
+ strcmp on the name (or better yet, base it on the section flags
+ or something else) for each section.
*/
asection *
bfd_make_section_old_way
SYNOPSIS
- asection *bfd_make_section_old_way(bfd *, CONST char *name);
+ asection *bfd_make_section_old_way(bfd *abfd, CONST char *name);
DESCRIPTION
- This function creates a new empty section called @var{name}
- and attaches it to the end of the chain of sections for the
- BFD supplied. An attempt to create a section with a name which
+ Create a new empty section called @var{name}
+ and attach it to the end of the chain of sections for the
+ BFD @var{abfd}. An attempt to create a section with a name which
is already in use, returns its pointer without changing the
section chain.
It has the funny name since this is the way it used to be
- before is was rewritten...
+ before it was rewritten....
Possible errors are:
o invalid_operation -
return sec;
}
-
/*
FUNCTION
- bfd_make_section
+ bfd_make_section_anyway
SYNOPSIS
- asection * bfd_make_section(bfd *, CONST char *name);
+ asection *bfd_make_section_anyway(bfd *abfd, CONST char *name);
DESCRIPTION
- This function creates a new empty section called @var{name}
- and attaches it to the end of the chain of sections for the
- BFD supplied. An attempt to create a section with a name which
- is already in use, returns NULL without changing the section
- chain.
+ Create a new empty section called @var{name} and attach it to the end of
+ the chain of sections for @var{abfd}. Create a new section even if there
+ is already a section with that name.
- Possible errors are:
- o invalid_operation - If output has already started for this BFD.
- o no_memory - If obstack alloc fails.
+ Returns NULL and sets bfd_error on error; possible errors are:
+ o invalid_operation - If output has already started for @var{abfd}.
+ o no_memory - If obstack alloc fails.
*/
-
-
sec_ptr
-DEFUN(bfd_make_section,(abfd, name),
- bfd *abfd AND
- CONST char * name)
+bfd_make_section_anyway (abfd, name)
+ bfd *abfd;
+ CONST char *name;
{
- asection *newsect;
- asection ** prev = &abfd->sections;
+ asection *newsect;
+ asection **prev = &abfd->sections;
asection * sect = abfd->sections;
-
- if (abfd->output_has_begun) {
- bfd_error = invalid_operation;
- return NULL;
- }
- if (strcmp(name, BFD_ABS_SECTION_NAME) == 0)
- {
- return &bfd_abs_section;
- }
- if (strcmp(name, BFD_COM_SECTION_NAME) == 0)
- {
- return &bfd_com_section;
- }
- if (strcmp(name, BFD_UND_SECTION_NAME) == 0)
- {
- return &bfd_und_section;
- }
+ if (abfd->output_has_begun)
+ {
+ bfd_error = invalid_operation;
+ return NULL;
+ }
- if (strcmp(name, BFD_IND_SECTION_NAME) == 0)
- {
- return &bfd_ind_section;
- }
-
while (sect) {
- if (!strcmp(sect->name, name)) return NULL;
prev = §->next;
sect = sect->next;
}
newsect->symbol->value = 0;
newsect->symbol->section = newsect;
newsect->symbol->flags = BSF_SECTION_SYM;
-
newsect->symbol_ptr_ptr = &newsect->symbol;
-
+
if (BFD_SEND (abfd, _new_section_hook, (abfd, newsect)) != true) {
free (newsect);
return NULL;
return newsect;
}
+/*
+FUNCTION
+ bfd_make_section
+
+SYNOPSIS
+ asection *bfd_make_section(bfd *, CONST char *name);
+
+DESCRIPTION
+ Like <<bfd_make_section_anyway>>, but return NULL (without setting
+ bfd_error) without changing the section chain if there is already a
+ section named @var{name}. If there is an error, return NULL and set
+ bfd_error.
+*/
+
+sec_ptr
+DEFUN(bfd_make_section,(abfd, name),
+ bfd *abfd AND
+ CONST char * name)
+{
+ asection * sect = abfd->sections;
+
+ if (strcmp(name, BFD_ABS_SECTION_NAME) == 0)
+ {
+ return &bfd_abs_section;
+ }
+ if (strcmp(name, BFD_COM_SECTION_NAME) == 0)
+ {
+ return &bfd_com_section;
+ }
+ if (strcmp(name, BFD_UND_SECTION_NAME) == 0)
+ {
+ return &bfd_und_section;
+ }
+
+ if (strcmp(name, BFD_IND_SECTION_NAME) == 0)
+ {
+ return &bfd_ind_section;
+ }
+
+ while (sect) {
+ if (!strcmp(sect->name, name)) return NULL;
+ sect = sect->next;
+ }
+
+ /* The name is not already used; go ahead and make a new section. */
+ return bfd_make_section_anyway (abfd, name);
+}
+
/*
FUNCTION
bfd_set_section_flags
SYNOPSIS
- boolean bfd_set_section_flags(bfd *, asection *, flagword);
+ boolean bfd_set_section_flags(bfd *abfd, asection *sec, flagword flags);
DESCRIPTION
- Attempts to set the attributes of the section named in the BFD
- supplied to the value. Returns true on success, false on
- error. Possible error returns are:
+ Set the attributes of the section @var{sec} in the BFD
+ @var{abfd} to the value @var{flags}. Returns <<true>> on success,
+ <<false>> on error. Possible error returns are:
o invalid operation -
The section cannot have one or more of the attributes
PTR obj);
DESCRIPTION
- Calls the provided function @var{func} for each section
+ Call the provided function @var{func} for each section
attached to the BFD @var{abfd}, passing @var{obj} as an
argument. The function will be called as if by
| func(abfd, the_section, obj);
- This is the prefered method for iterating over sections, an
+ This is the prefered method for iterating over sections; an
alternative would be to use a loop:
| section *p;
bfd_set_section_size
SYNOPSIS
- boolean bfd_set_section_size(bfd *, asection *, bfd_size_type val);
+ boolean bfd_set_section_size(bfd *abfd, asection *sec, bfd_size_type val);
DESCRIPTION
- Sets @var{section} to the size @var{val}. If the operation is
+ Set @var{sec} to the size @var{val}. If the operation is
ok, then <<true>> is returned, else <<false>>.
Possible error returns:
file_ptr offset, bfd_size_type count);
DESCRIPTION
- This function reads data from @var{section} in BFD @var{abfd}
+ Read data from @var{section} in BFD @var{abfd}
into memory starting at @var{location}. The data is read at an
offset of @var{offset} from the start of the input section,
and is read for @var{count} bytes.
/* Generic symbol-table support for the BFD library.
- Copyright (C) 1990-1991 Free Software Foundation, Inc.
+ Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
SECTION
Symbols
- BFD trys to maintain as much symbol information as it can when
+ BFD tries to maintain as much symbol information as it can when
it moves information from file to file. BFD passes information
to applications though the <<asymbol>> structure. When the
application requests the symbol table, BFD reads the table in
the native form and translates parts of it into the internal
- format. To maintain more than the infomation passed to
- applications some targets keep some information 'behind the
- sceans', in a structure only the particular back end knows
+ format. To maintain more than the information passed to
+ applications, some targets keep some information ``behind the
+ scenes'' in a structure only the particular back end knows
about. For example, the coff back end keeps the original
symbol table structure as well as the canonical structure when
a BFD is read in. On output, the coff back end can reconstruct
the output symbol table so that no information is lost, even
information unique to coff which BFD doesn't know or
- understand. If a coff symbol table was read, but was written
+ understand. If a coff symbol table were read, but were written
through an a.out back end, all the coff specific information
would be lost. The symbol table of a BFD
is not necessarily read in until a canonicalize request is
application with pointers to the canonical information. To
output symbols, the application provides BFD with a table of
pointers to pointers to <<asymbol>>s. This allows applications
- like the linker to output a symbol as read, since the 'behind
- the sceens' information will be still available.
+ like the linker to output a symbol as it was read, since the ``behind
+ the scenes'' information will be still available.
@menu
@* Reading Symbols::
@* Writing Symbols::
@* symbol handling functions::
@end menu
-@node Reading Symbols, Writing Symbols, Symbols, Symbols
+INODE
+Reading Symbols, Writing Symbols, Symbols, Symbols
SUBSECTION
Reading Symbols
- There are two stages to reading a symbol table from a BFD;
+ There are two stages to reading a symbol table from a BFD:
allocating storage, and the actual reading process. This is an
- excerpt from an appliction which reads the symbol table:
+ excerpt from an application which reads the symbol table:
| unsigned int storage_needed;
| asymbol **symbol_table;
| }
All storage for the symbols themselves is in an obstack
- connected to the BFD, and is freed when the BFD is closed.
+ connected to the BFD; it is freed when the BFD is closed.
-@node Writing Symbols, typedef asymbol, Reading Symbols, Symbols
+INODE
+Writing Symbols, typedef asymbol, Reading Symbols, Symbols
SUBSECTION
Writing Symbols
pointers to pointers to symbols to the BFD being written, and
fills in the symbol count. The close and cleanup code reads
through the table provided and performs all the necessary
- operations. The outputing code must always be provided with an
- 'owned' symbol; one which has come from another BFD, or one
- which has been created using <<bfd_make_empty_symbol>>. An
+ operations. The BFD output code must always be provided with an
+ ``owned'' symbol: one which has come from another BFD, or one
+ which has been created using <<bfd_make_empty_symbol>>. Here is an
example showing the creation of a symbol table with only one element:
| #include "bfd.h"
| 00012345 A dummy_symbol
Many formats cannot represent arbitary symbol information; for
- instance the <<a.out>> object format does not allow an
+ instance, the <<a.out>> object format does not allow an
arbitary number of sections. A symbol pointing to a section
which is not one of <<.text>>, <<.data>> or <<.bss>> cannot
be described.
*/
+
/*
-@node typedef asymbol, symbol handling functions, Writing Symbols, Symbols
+DOCDD
+INODE
+typedef asymbol, symbol handling functions, Writing Symbols, Symbols
*/
/*
/*
CODE_FRAGMENT
+.
.typedef struct symbol_cache_entry
.{
. {* A pointer to the BFD which owns the symbol. This information
. is necessary so that a back end can work out what additional
-. (invisible to the application writer) information is carried
-. with the symbol. *}
+. information (invisible to the application writer) is carried
+. with the symbol.
+.
+. This field is *almost* redundant, since you can use section->owner
+. instead, except that some symbols point to the global sections
+. bfd_{abs,com,und}_section. This could be fixed by making
+. these globals be per-bfd (or per-target-flavor). FIXME. *}
.
-. struct _bfd *the_bfd;
+. struct _bfd *the_bfd; {* Use bfd_asymbol_bfd(sym) to access this field. *}
.
-. {* The text of the symbol. The name is left alone, and not copied - the
+. {* The text of the symbol. The name is left alone, and not copied; the
. application may not alter it. *}
. CONST char *name;
.
-. {* The value of the symbol.*}
+. {* The value of the symbol. This really should be a union of a
+. numeric value with a pointer, since some flags indicate that
+. a pointer to another symbol is stored here. *}
. symvalue value;
.
. {* Attributes of a symbol: *}
. value is the offset into the section of the data. *}
.#define BSF_GLOBAL 0x02
.
-. {* Obsolete *}
-.#define BSF_IMPORT 0x04
-.
-. {* The symbol has global scope, and is exported. The value is
+. {* The symbol has global scope and is exported. The value is
. the offset into the section of the data. *}
-.#define BSF_EXPORT 0x08
-.
-. {* The symbol is undefined. <<extern>> in <<C>>. The value has
-. no meaning. *}
-.#define BSF_UNDEFINED_OBS 0x10
-.
-. {* The symbol is common, initialized to zero; default in
-. <<C>>. The value is the size of the object in bytes. *}
-.#define BSF_FORT_COMM_OBS 0x20
+.#define BSF_EXPORT BSF_GLOBAL {* no real difference *}
.
. {* A normal C symbol would be one of:
. <<BSF_LOCAL>>, <<BSF_FORT_COMM>>, <<BSF_UNDEFINED>> or
-. <<BSF_EXPORT|BSD_GLOBAL>> *}
+. <<BSF_GLOBAL>> *}
.
. {* The symbol is a debugging record. The value has an arbitary
. meaning. *}
-.#define BSF_DEBUGGING 0x40
+.#define BSF_DEBUGGING 0x08
.
-. {* Used by the linker *}
-.#define BSF_KEEP 0x10000
-.#define BSF_KEEP_G 0x80000
+. {* The symbol denotes a function entry point. Used in ELF,
+. perhaps others someday. *}
+.#define BSF_FUNCTION 0x10
.
-. {* Unused *}
-.#define BSF_WEAK 0x100000
-.#define BSF_CTOR 0x200000
+. {* Used by the linker. *}
+.#define BSF_KEEP 0x20
+.#define BSF_KEEP_G 0x40
.
-. {* This symbol was created to point to a section *}
-.#define BSF_SECTION_SYM 0x400000
+. {* A weak global symbol, overridable without warnings by
+. a regular global symbol of the same name. *}
+.#define BSF_WEAK 0x80
+.
+. {* This symbol was created to point to a section, e.g. ELF's
+. STT_SECTION symbols. *}
+.#define BSF_SECTION_SYM 0x100
.
. {* The symbol used to be a common symbol, but now it is
. allocated. *}
-.#define BSF_OLD_COMMON 0x800000
+.#define BSF_OLD_COMMON 0x200
.
. {* The default value for common data. *}
.#define BFD_FORT_COMM_DEFAULT_VALUE 0
. declared and not at the end of a section. This bit is set
. by the target BFD part to convey this information. *}
.
-.#define BSF_NOT_AT_END 0x40000
+.#define BSF_NOT_AT_END 0x400
.
. {* Signal that the symbol is the label of constructor section. *}
-.#define BSF_CONSTRUCTOR 0x1000000
+.#define BSF_CONSTRUCTOR 0x800
.
. {* Signal that the symbol is a warning symbol. If the symbol
. is a warning symbol, then the value field (I know this is
. tacky) will point to the asymbol which when referenced will
. cause the warning. *}
-.#define BSF_WARNING 0x2000000
+.#define BSF_WARNING 0x1000
.
. {* Signal that the symbol is indirect. The value of the symbol
. is a pointer to an undefined asymbol which contains the
. name to use instead. *}
-.#define BSF_INDIRECT 0x4000000
+.#define BSF_INDIRECT 0x2000
+.
+. {* BSF_FILE marks symbols that contain a file name. This is used
+. for ELF STT_FILE symbols. *}
+.#define BSF_FILE 0x4000
.
. flagword flags;
.
.
. {* Back end special data. This is being phased out in favour
. of making this a union. *}
-. PTR udata;
+. PTR udata;
.
.} asymbol;
*/
#include "bfd.h"
#include "sysdep.h"
+
#include "libbfd.h"
#include "aout/stab_gnu.h"
/*
-@node symbol handling functions, , typedef asymbol, Symbols
+DOCDD
+INODE
+symbol handling functions, , typedef asymbol, Symbols
SUBSECTION
Symbol Handling Functions
*/
get_symtab_upper_bound
DESCRIPTION
- Returns the number of bytes required in a vector of pointers
- to <<asymbols>> for all the symbols in the supplied BFD,
+ Return the number of bytes required to store a vector of pointers
+ to <<asymbols>> for all the symbols in the BFD @var{abfd},
including a terminal NULL pointer. If there are no symbols in
- the BFD, then 0 is returned.
+ the BFD, then return 0.
.#define get_symtab_upper_bound(abfd) \
. BFD_SEND (abfd, _get_symtab_upper_bound, (abfd))
bfd_canonicalize_symtab
DESCRIPTION
- Supplied a BFD and a pointer to an uninitialized vector of
- pointers. This reads in the symbols from the BFD, and fills in
- the table with pointers to the symbols, and a trailing NULL.
- The routine returns the actual number of symbol pointers not
+ Read the symbols from the BFD @var{abfd}, and fills in
+ the vector @var{location} with pointers to the symbols and
+ a trailing NULL.
+ Return the actual number of symbol pointers, not
including the NULL.
FUNCTION
bfd_set_symtab
-DESCRIPTION
- Provided a table of pointers to symbols and a count, writes to
- the output BFD the symbols when closed.
-
SYNOPSIS
- boolean bfd_set_symtab (bfd *, asymbol **, unsigned int );
+ boolean bfd_set_symtab (bfd *abfd, asymbol **location, unsigned int count);
+
+DESCRIPTION
+ Arrange that when the output BFD @var{abfd} is closed,
+ the table @var{location} of @var{count} pointers to symbols
+ will be written.
*/
boolean
FUNCTION
bfd_print_symbol_vandf
-DESCRIPTION
- Prints the value and flags of the symbol supplied to the stream file.
-
SYNOPSIS
void bfd_print_symbol_vandf(PTR file, asymbol *symbol);
+
+DESCRIPTION
+ Print the value and flags of the @var{symbol} supplied to the
+ stream @var{file}.
*/
void
DEFUN(bfd_print_symbol_vandf,(file, symbol),
{
fprintf_vma(file, symbol->value);
}
- fprintf(file," %c%c%c%c%c%c%c%c",
+ fprintf(file," %c%c%c%c%c%c%c",
(type & BSF_LOCAL) ? 'l':' ',
(type & BSF_GLOBAL) ? 'g' : ' ',
- (type & BSF_IMPORT) ? 'i' : ' ',
- (type & BSF_EXPORT) ? 'e' : ' ',
+ (type & BSF_WEAK) ? 'w' : ' ',
(type & BSF_CONSTRUCTOR) ? 'C' : ' ',
(type & BSF_WARNING) ? 'W' : ' ',
(type & BSF_INDIRECT) ? 'I' : ' ',
bfd_make_empty_symbol
DESCRIPTION
- This function creates a new <<asymbol>> structure for the BFD,
- and returns a pointer to it.
+ Create a new <<asymbol>> structure for the BFD @var{abfd}
+ and return a pointer to it.
- This routine is necessary, since each back end has private
+ This routine is necessary because each back end has private
information surrounding the <<asymbol>>. Building your own
<<asymbol>> and pointing to it will not create the private
information, and will cause problems later on.
. BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd))
*/
+/*
+FUNCTION
+ bfd_make_debug_symbol
+
+DESCRIPTION
+ Create a new <<asymbol>> structure for the BFD @var{abfd},
+ to be used as a debugging symbol. Further details of its use have
+ yet to be worked out.
+
+.#define bfd_make_debug_symbol(abfd,ptr,size) \
+. BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size))
+*/
+
+struct section_to_type
+{
+ CONST char *section;
+ char type;
+};
+
+/* Map section names to POSIX/BSD single-character symbol types.
+ This table is probably incomplete. It is sorted for convenience of
+ adding entries. Since it is so short, a linear search is used. */
+static CONST struct section_to_type stt[] = {
+ {"*DEBUG*", 'N'},
+ {".bss", 'b'},
+ {".data", 'd'},
+ {".sbss", 's'}, /* Small BSS (uninitialized data) */
+ {".scommon", 'c'}, /* Small common */
+ {".sdata", 'g'}, /* Small initialized data */
+ {".text", 't'},
+ {0, 0}
+};
+
+/* Return the single-character symbol type corresponding to
+ section S, or '?' for an unknown COFF section. */
+
+static char
+coff_section_type (s)
+ char *s;
+{
+ CONST struct section_to_type *t;
+
+ for (t = &stt[0]; t->section; t++)
+ if (!strcmp (s, t->section))
+ return t->type;
+ return '?';
+}
+
+#ifndef islower
+#define islower(c) ((c) >= 'a' && (c) <= 'z')
+#endif
+#ifndef toupper
+#define toupper(c) (islower(c) ? ((c) & ~0x20) : (c))
+#endif
+
/*
FUNCTION
bfd_decode_symclass
DESCRIPTION
- Return a lower-case character corresponding to the symbol
- class of symbol.
+ Return a character corresponding to the symbol
+ class of @var{symbol}, or '?' for an unknown class.
SYNOPSIS
int bfd_decode_symclass(asymbol *symbol);
DEFUN(bfd_decode_symclass,(symbol),
asymbol *symbol)
{
- flagword flags = symbol->flags;
-
- if (symbol->section == &bfd_com_section) return 'C';
- if (symbol->section == &bfd_und_section) return 'U';
-
- if ( flags & (BSF_GLOBAL|BSF_LOCAL) ) {
- if ( symbol->section == &bfd_abs_section)
- return (flags & BSF_GLOBAL) ? 'A' : 'a';
- else if ( !strcmp(symbol->section->name, ".text") )
- return (flags & BSF_GLOBAL) ? 'T' : 't';
- else if ( !strcmp(symbol->section->name, ".data") )
- return (flags & BSF_GLOBAL) ? 'D' : 'd';
- else if ( !strcmp(symbol->section->name, ".bss") )
- return (flags & BSF_GLOBAL) ? 'B' : 'b';
- else
- return (flags & BSF_GLOBAL) ? 'O' : 'o';
- }
+ char c;
+
+ if (bfd_is_com_section (symbol->section))
+ return 'C';
+ if (symbol->section == &bfd_und_section)
+ return 'U';
+ if (symbol->section == &bfd_ind_section)
+ return 'I';
+ if (!(symbol->flags & (BSF_GLOBAL|BSF_LOCAL)))
+ return '?';
+
+ if (symbol->section == &bfd_abs_section)
+ c = 'a';
+ else if (symbol->section)
+ c = coff_section_type (symbol->section->name);
+ else
+ return '?';
+ if (symbol->flags & BSF_GLOBAL)
+ c = toupper (c);
+ return c;
/* We don't have to handle these cases just yet, but we will soon:
N_SETV: 'v';
N_SETB: 's';
N_INDR: 'i';
*/
-
- return '?';
}
+/*
+FUNCTION
+ bfd_symbol_info
+
+DESCRIPTION
+ Fill in the basic info about symbol that nm needs.
+ Additional info may be added by the back-ends after
+ calling this function.
+
+SYNOPSIS
+ void bfd_symbol_info(asymbol *symbol, symbol_info *ret);
+*/
+void
+DEFUN(bfd_symbol_info,(symbol, ret),
+ asymbol *symbol AND
+ symbol_info *ret)
+{
+ ret->type = bfd_decode_symclass (symbol);
+ if (ret->type != 'U')
+ ret->value = symbol->value+symbol->section->vma;
+ else
+ ret->value = 0;
+ ret->name = symbol->name;
+}
+
+void
bfd_symbol_is_absolute()
{
-
abort();
}
target are unknown. BFD uses various mechanisms to determine
how to interpret the file. The operations performed are:
- o First a BFD is created by calling the internal routine
- <<new_bfd>>, then <<bfd_find_target>> is called with the
+ o Create a BFD by calling the internal routine
+ <<new_bfd>>, then call <<bfd_find_target>> with the
target string supplied to <<bfd_openr>> and the new BFD pointer.
o If a null target string was provided to <<bfd_find_target>>,
- it looks up the environment variable <<GNUTARGET>> and uses
+ look up the environment variable <<GNUTARGET>> and use
that as the target string.
o If the target string is still NULL, or the target string is
- <<default>>, then the first item in the target vector is used
- as the target type, and <<target_defaulted>> is set to
+ <<default>>, then use the first item in the target vector
+ as the target type, and set <<target_defaulted>> in the BFD to
cause <<bfd_check_format>> to loop through all the targets.
@xref{bfd_target}. @xref{Formats}.
- o Otherwise, the elements in the target vector are inspected
+ o Otherwise, inspect the elements in the target vector
one by one, until a match on target name is found. When found,
- that is used.
+ use it.
- o Otherwise the error <<invalid_target>> is returned to
+ o Otherwise return the error <<invalid_target>> to
<<bfd_openr>>.
o <<bfd_openr>> attempts to open the file using
format may be determined. This is done by calling
<<bfd_check_format>> on the BFD with a suggested format.
If <<target_defaulted>> has been set, each possible target
- type is tried to see if it recognizes the specified format. The
- routine returns <<true>> when the application guesses right.
+ type is tried to see if it recognizes the specified format.
+ <<bfd_check_format>> returns <<true>> when the caller guesses right.
@menu
@* bfd_target::
@end menu
DESCRIPTION
This structure contains everything that BFD knows about a
- target. It includes things like its byte order, name, what
- routines to call to do various operations, etc.
+ target. It includes things like its byte order, name, and which
+ routines to call to do various operations.
Every BFD points to a target structure with its <<xvec>>
member.
- These macros are used to dispatch to functions through the
- bfd_target vector. They are used in a number of macros further
+ The macros below are used to dispatch to functions through the
+ <<bfd_target>> vector. They are used in a number of macros further
down in @file{bfd.h}, and are also used when calling various
- routines by hand inside the BFD implementation. The "arglist"
+ routines by hand inside the BFD implementation. The @var{arglist}
argument must be parenthesized; it contains all the arguments
to the called function.
.#define BFD_SEND(bfd, message, arglist) \
. ((*((bfd)->xvec->message)) arglist)
- For operations which index on the BFD format
+ For operations which index on the BFD format:
.#define BFD_SEND_FMT(bfd, message, arglist) \
. (((bfd)->xvec->message[(int)((bfd)->format)]) arglist)
- This is the struct which defines the type of BFD this is. The
+ This is the structure which defines the type of BFD this is. The
<<xvec>> member of the struct <<bfd>> itself points here. Each
module that implements access to a different target under BFD,
defines one of these.
the entry points which call them. Too bad we can't have one
macro to define them both!
+.enum bfd_flavour {
+. bfd_target_unknown_flavour,
+. bfd_target_aout_flavour,
+. bfd_target_coff_flavour,
+. bfd_target_ecoff_flavour,
+. bfd_target_elf_flavour,
+. bfd_target_ieee_flavour,
+. bfd_target_nlm_flavour,
+. bfd_target_oasys_flavour,
+. bfd_target_tekhex_flavour,
+. bfd_target_srec_flavour,
+. bfd_target_som_flavour};
+
.typedef struct bfd_target
.{
-Identifies the kind of target, eg SunOS4, Ultrix, etc.
+Identifies the kind of target, e.g., SunOS4, Ultrix, etc.
. char *name;
The "flavour" of a back end is a general indication about the contents
of a file.
-. enum target_flavour {
-. bfd_target_unknown_flavour,
-. bfd_target_aout_flavour,
-. bfd_target_coff_flavour,
-. bfd_target_ecoff_flavour,
-. bfd_target_elf_flavour,
-. bfd_target_ieee_flavour,
-. bfd_target_nlm_flavour,
-. bfd_target_oasys_flavour,
-. bfd_target_tekhex_flavour,
-. bfd_target_srec_flavour,
-. bfd_target_som_flavour} flavour;
+. enum bfd_flavour flavour;
The order of bytes within the data area of a file.
. boolean header_byteorder_big_p;
-This is a mask of all the flags which an executable may have set -
+A mask of all the flags which an executable may have set -
from the set <<NO_FLAGS>>, <<HAS_RELOC>>, ...<<D_PAGED>>.
. flagword object_flags;
-This is a mask of all the flags which a section may have set - from
+A mask of all the flags which a section may have set - from
the set <<SEC_NO_FLAGS>>, <<SEC_ALLOC>>, ...<<SET_NEVER_LOAD>>.
. flagword section_flags;
The character normally found at the front of a symbol
-(if any), perhaps _.
+(if any), perhaps `_'.
. char symbol_leading_char;
-The pad character for filenames within an archive header.
+The pad character for file names within an archive header.
. char ar_pad_char;
. unsigned int align_power_min;
-Entries for byte swapping for data. These are different to the other
-entry points, since they don't take BFD as first arg. Certain other handlers
-could do the same.
+Entries for byte swapping for data. These are different from the other
+entry points, since they don't take a BFD asthe first argument.
+Certain other handlers could do the same.
. bfd_vma (*bfd_getx64) PARAMS ((bfd_byte *));
. bfd_signed_vma (*bfd_getx_signed_64) PARAMS ((bfd_byte *));
Format dependent routines: these are vectors of entry points
within the target vector structure, one for each format to check.
-Check the format of a file being read. Return bfd_target * or zero.
+Check the format of a file being read. Return a <<bfd_target *>> or zero.
. struct bfd_target * (*_bfd_check_format[bfd_type_end]) PARAMS ((bfd *));
. boolean (*_bfd_set_format[bfd_type_end]) PARAMS ((bfd *));
-Write cached information into a file being written, at bfd_close.
+Write cached information into a file being written, at <<bfd_close>>.
. boolean (*_bfd_write_contents[bfd_type_end]) PARAMS ((bfd *));
The following functions are defined in <<JUMP_TABLE>>. The idea is
that the back end writer of <<foo>> names all the routines
-<<foo_>>@var{entry_point}, <<JUMP_TABLE>> will built the entries
+<<foo_>>@var{entry_point}; <<JUMP_TABLE>> will build the entries
in this structure in the right order.
-Core file entry points
+Core file entry points.
. char * (*_core_file_failing_command) PARAMS ((bfd *));
. int (*_core_file_failing_signal) PARAMS ((bfd *));
. boolean (*_core_file_matches_executable_p) PARAMS ((bfd *, bfd *));
-Archive entry points
+Archive entry points.
. boolean (*_bfd_slurp_armap) PARAMS ((bfd *));
. boolean (*_bfd_slurp_extended_name_table) PARAMS ((bfd *));
. file_ptr, bfd_size_type));
. boolean (*_new_section_hook) PARAMS ((bfd *, sec_ptr));
-Symbols and relocations
+Symbols and relocations.
. unsigned int (*_get_symtab_upper_bound) PARAMS ((bfd *));
. unsigned int (*_bfd_canonicalize_symtab) PARAMS ((bfd *,
extern bfd_target oasys_vec;
extern bfd_target rs6000coff_vec;
extern bfd_target shcoff_vec;
+extern bfd_target sparclynx_aout_vec;
+extern bfd_target sparclynx_coff_vec;
extern bfd_target sunos_big_vec;
extern bfd_target tekhex_vec;
extern bfd_target we32kcoff_vec;
#endif
&rs6000coff_vec,
&shcoff_vec,
+ &sparclynx_aout_vec,
+ &sparclynx_coff_vec,
&sunos_big_vec,
#if 0
&tekhex_vec,
FUNCTION
bfd_find_target
+SYNOPSIS
+ bfd_target *bfd_find_target(CONST char *target_name, bfd *abfd);
+
DESCRIPTION
- Returns a pointer to the transfer vector for the object target
- named target_name. If target_name is NULL, chooses the one in
- the environment variable GNUTARGET; if that is null or not
- defined thenthe first entry in the target list is chosen.
+ Return a pointer to the transfer vector for the object target
+ named @var{target_name}. If @var{target_name} is NULL, choose the
+ one in the environment variable GNUTARGET; if that is null or not
+ defined, then choose the first entry in the target list.
Passing in the string "default" or setting the environment
variable to "default" will cause the first entry in the target
list to be returned, and "target_defaulted" will be set in the
BFD. This causes <<bfd_check_format>> to loop over all the
targets to find the one that matches the file being read.
-
-SYNOPSIS
- bfd_target *bfd_find_target(CONST char *, bfd *);
*/
bfd_target *
FUNCTION
bfd_target_list
-DESCRIPTION
- This function returns a freshly malloced NULL-terminated
- vector of the names of all the valid BFD targets. Do not
- modify the names
-
SYNOPSIS
CONST char **bfd_target_list(void);
+DESCRIPTION
+ Return a freshly malloced NULL-terminated
+ vector of the names of all the valid BFD targets. Do not
+ modify the names.
+
*/
CONST char **