Initial revision

This commit is contained in:
Steve Chamberlain 1991-07-15 23:43:15 +00:00
parent a737c70bde
commit 2013f9b4e1
10 changed files with 1576 additions and 0 deletions

430
bfd/bfd.texinfo Executable file
View file

@ -0,0 +1,430 @@
\input cyginfo
@c\input texinfo
@setfilename bfdinfo
@c $Id$
@synindex ky cp
@ifinfo
This file documents the BFD library.
Copyright (C) 1991 Cygnus Support.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.
@ignore
Permission is granted to process this file through Tex and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).
@end ignore
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
section entitled ``GNU General Public License'' is included exactly as
in the original, and provided that the entire resulting derived work is
distributed under the terms of a permission notice identical to this
one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that the section entitled ``GNU General Public License'' may be
included in a translation approved by the author instead of in the
original English.
@end ifinfo
@iftex
@c this removes the gaps around @examples
@c@finalout
@c@setchapternewpage odd
@settitle LIB BFD, the Binary File Desciptor Library
@titlepage
@title{libbfd}
@subtitle{The Big File Descriptor Library}
@sp 1
@subtitle First Edition---@code{bfd} version < 2.0
@subtitle April 1991
@author {Steve Chamberlain}
@author {Cygnus Support}
@page
@tex
\def\$#1${{#1}} % Kluge: collect RCS revision info without $...$
\xdef\manvers{\$Revision$} % For use in headers, footers too
{\parskip=0pt
\hfill Cygnus Support\par
\hfill steve\@cygnus.com\par
\hfill {\it BFD}, \manvers\par
\hfill \TeX{}info \texinfoversion\par
}
\global\parindent=0pt % Steve likes it this way
@end tex
@vskip 0pt plus 1filll
Copyright @copyright{} 1991 Cygnus Support.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end titlepage
@end iftex
@c FIXME: Talk about importance of *order* of args, cmds to linker!
@node Top, Overview, (dir), (dir)
@ifinfo
This file documents the binary file descriptor library libbfd.
@end ifinfo
@menu
* Overview:: Overview of bfd
* History:: History of bfd
* Backends:: Backends
* Porting:: Porting
* Future:: Future
* Index:: Index
BFD body:
* Sections::
* Symbols::
* Archives::
* Formats::
* Relocations::
* Core Files::
* Targets::
* Architecturs::
* Opening and Closing::
* Internal::
* File Caching::
Bfd backends:
* a.out backends::
* coff backends::
@end menu
@node Overview, History, Top, Top
@chapter Introduction
@cindex BFD
@cindex what is it?
Simply put, @code{bfd} is a package which allow applications to use the
same routines to operate on object files whatever the object file
format. A different object file format can be supported simply by
creating a new BFD back end and adding it to the library.
BFD is split into two parts; the front end and the many back ends.
@itemize @bullet
@item The front end of bfd provides the interface to the user. It manages
memory, and various canonical data structures. The front end also
decides which back end to use, and when to call back end routines.
@item The back ends provide bfd its view of the real world. Each back
end provides a set of calls which the bfd front end can use to maintain
its canonical form. The back ends also may keep around information for
their own use, for greater efficiency.
@end itemize
@node History, How It Works, Overview,Top
@section History
Gumby really knows this, so his bit goes here.
One spur behind @code{bfd} was the Intel Oregon's GNU 960 team desire for
interoperability of applications on their COFF and b.out file formats.
Cygnus was providing GNU support for the team, and Cygnus were
contracted to provid the required functionality.
The name came from a conversation Gumby Wallace was
having with Richard Stallman about the library, RMS said that it
would be quite hard, Gumby said BFD. (Stallman was right, but the name
stuck).
At the same time, Ready Systems wanted much the same thing, but for
different object file formats, IEEE-695, Oasys, Srecords, a.out and 68k coff.
BFD was first implemented by Steve Chamberlain (steve@@cygnus.com),
John Gilmore (gnu@@cygnus.com), K. Richard Pixley (rich@@cygnus.com) and
Gumby Wallace (gumby@@cygnus.com).
@node How It Works, History, Porting, Top
@section How It Works
@code{bfd} provides a common interface to the parts of an object file
to a calling application.
When an application sucessfully opens a
target file (object, archive or whatever) a pointer to an internal
structure is returned. This pointer points to structure described in
@code{include/bfd.h}, called @code{bfd}. Conventionally this pointer is
called a @code{bfd}, and instances of it within code are called
@code{abfd}. All operations on the target object file are applied as
methods to the @code{bfd}, the mapping is defined within @code{bfd.h} in
a set of macros, all beginning @code{bfd}_something.
For example, this sequence would do what you expect:
@tex
\globaldefs=1
\def\example{\begingroup\inENV %This group ends at the end of the @lisp body
\hfuzz=12truept % Don't be fussy
% Make spaces be word-separators rather than space tokens.
\sepspaces %
% Single space lines
\singlespace %
% The following causes blank lines not to be ignored
% by adding a space to the end of each line.
\let\par=\lisppar
\def\Eexample{\endgroup}%
\parskip=0pt
\advance \leftskip by \lispnarrowing
\parindent=0pt
\let\exdent=\internalexdent
\obeyspaces \obeylines \tt \rawbackslash
\def\next##1{}\next}
\globaldefs=0
@end tex
@lisp
@w{
#include "bfd.h"
unsigned int number_of_sections(abfd)
bfd *abfd;
@{
return bfd_count_sections(abfd);
@}
}
@end lisp
The metaphor used within @code{bfd} is that an object file has a header,
a numbber of sections containing raw data, a set of relocations and some
symbol information. Also, @code{bfd}s opened upon archives have the
additional attribute of an index and contained sub bfds. This approach is
find for a.out and coff, but looses efficiency when applied to formats
such as S-records and IEEE-695.
@section What BFD Version 1 Can't Do
As different information from the the object files is required,
BFD reads from different sections of the file and processes them.
For example a very common operation for the linker is processing symbol
tables. Each BFD back end provides a routine for converting
between the object file's representation of symbols and an internal
canonical format. When the linker asks for the symbol table of an object
file, it calls through the memory pointer to the relevant BFD
back end routine which reads and converts the table into a canonical
form. The linker then operates upon the common form. When the link is
finished and the linker writes the symbol table of the output file,
another BFD back end routine is called which takes the newly
created symbol table and converts it into the chosen output format.
@node BFD information loss, Mechanism, BFD outline, BFD
@subsection Information Loss
@emph{Some information is lost due to the nature of the file format.} The output targets
supported by BFD do not provide identical facilities, and
information which may be described in one form has nowhere to go in
another format. One example of this is alignment information in
@code{b.out}. There is nowhere in an @code{a.out} format file to store
alignment information on the contained data, so when a file is linked
from @code{b.out} and an @code{a.out} image is produced, alignment
information will not propagate to the output file. (The linker will
still use the alignment information internally, so the link is performed
correctly).
Another example is COFF section names. COFF files may contain an
unlimited number of sections, each one with a textual section name. If
the target of the link is a format which does not have many sections (eg
@code{a.out}) or has sections without names (eg the Oasys format) the
link cannot be done simply. You can circumvent this problem by
describing the desired input-to-output section mapping with the linker command
language.
@emph{Information can be lost during canonicalization.} The BFD
internal canonical form of the external formats is not exhaustive; there
are structures in input formats for which there is no direct
representation internally. This means that the BFD back ends
cannot maintain all possible data richness through the transformation
between external to internal and back to external formats.
This limitation is only a problem when using the linker to read one
format and write another. Each BFD back end is responsible for
maintaining as much data as possible, and the internal BFD
canonical form has structures which are opaque to the BFD core,
and exported only to the back ends. When a file is read in one format,
the canonical form is generated for BFD and the linker. At the
same time, the back end saves away any information which may otherwise
be lost. If the data is then written back in the same format, the back
end routine will be able to use the canonical form provided by the
BFD core as well as the information it prepared earlier. Since
there is a great deal of commonality between back ends, this mechanism
is very useful. There is no information lost for this reason when
linking big endian COFF to little endian COFF, or from @code{a.out} to
@code{b.out}. When a mixture of formats is linked, the information is
only lost from the files whose format differs from the destination.
@node Mechanism, , BFD information loss, BFD
@subsection Mechanism
The greatest potential for loss of information is when there is least
overlap between the information provided by the source format, that
stored by the canonical format, and the information needed by the
destination format. A brief description of the canonical form may help
you appreciate what kinds of data you can count on preserving across
conversions.
@cindex BFD canonical format
@cindex internal object-file format
@table @emph
@item files
Information on target machine architecture, particular implementation
and format type are stored on a per-file basis. Other information
includes a demand pageable bit and a write protected bit. Note that
information like Unix magic numbers is not stored here---only the magic
numbers' meaning, so a @code{ZMAGIC} file would have both the demand pageable
bit and the write protected text bit set.
The byte order of the target is stored on a per-file basis, so that big-
and little-endian object files may be linked with one another.
@item sections
Each section in the input file contains the name of the section, the
original address in the object file, various flags, size and alignment
information and pointers into other BFD data structures.
@item symbols
Each symbol contains a pointer to the object file which originally
defined it, its name, its value, and various flag bits. When a
BFD back end reads in a symbol table, the back end relocates all
symbols to make them relative to the base of the section where they were
defined. This ensures that each symbol points to its containing
section. Each symbol also has a varying amount of hidden data to contain
private data for the BFD back end. Since the symbol points to the
original file, the private data format for that symbol is accessible.
@code{gld} can operate on a collection of symbols of wildly different
formats without problems.
Normal global and simple local symbols are maintained on output, so an
output file (no matter its format) will retain symbols pointing to
functions and to global, static, and common variables. Some symbol
information is not worth retaining; in @code{a.out} type information is
stored in the symbol table as long symbol names. This information would
be useless to most COFF debuggers and may be thrown away with
appropriate command line switches. (The GNU debugger @code{gdb} does
support @code{a.out} style debugging information in COFF).
There is one word of type information within the symbol, so if the
format supports symbol type information within symbols (for example COFF,
IEEE, Oasys) and the type is simple enough to fit within one word
(nearly everything but aggregates) the information will be preserved.
@item relocation level
Each canonical BFD relocation record contains a pointer to the symbol to
relocate to, the offset of the data to relocate, the section the data
is in and a pointer to a relocation type descriptor. Relocation is
performed effectively by message passing through the relocation type
descriptor and symbol pointer. It allows relocations to be performed
on output data using a relocation method only available in one of the
input formats. For instance, Oasys provides a byte relocation format.
A relocation record requesting this relocation type would point
indirectly to a routine to perform this, so the relocation may be
performed on a byte being written to a COFF file, even though 68k COFF
has no such relocation type.
@item line numbers
Object formats can contain, for debugging purposes, some form of mapping
between symbols, source line numbers, and addresses in the output file.
These addresses have to be relocated along with the symbol information.
Each symbol with an associated list of line number records points to the
first record of the list. The head of a line number list consists of a
pointer to the symbol, which allows divination of the address of the
function whose line number is being described. The rest of the list is
made up of pairs: offsets into the section and line numbers. Any format
which can simply derive this information can pass it successfully
between formats (COFF, IEEE and Oasys).
@end table
What is a backend
@node BFD front end, BFD back end, Mechanism, Top
@page
@chapter BFD front end
@include doc/bfd.doc
@page
@node Sections, Symbols , bfd, Top
@include doc/section.doc
@page
@node Symbols, Archives ,Sections, To
@include doc/syms.doc
@page
@node Archives, Formats, Symbols, Top
@include doc/archive.doc
@page
@node Formats, Relocations, Archives, Top
@include doc/format.doc
@page
@node Relocations, Core Files,Formats, Top
@include doc/reloc.doc
@page
@node Core Files, Targets, Relocations, Top
@include doc/core.doc
@page
@node Targets, Architectures, Core Files, Top
@include doc/targets.doc
@page
@node Architectures, Opening and Closing, Targets, Top
@include doc/archures.doc
@page
@node Opening and Closing, Internal, Architectures, Top
@include doc/opncls.doc
@page
@node Internal, File Caching, Opening and Closing, Top
@include doc/libbfd.doc
@page
@node File Caching, Top, Internal, Top
@include doc/cache.doc
@page
@chapter BFD back end
@node BFD back end, ,BFD front end, Top
@menu
* What to put where
* a.out backends::
* coff backends::
* oasys backend::
* ieee backend::
* srecord backend::
@end menu
@node What to Put Where, aout backends, BFD back end, BFD back end
All of bfd lives in one directory.
@page
@node aout backends, coff backends, What to Put Where, BFD back end
@include doc/aoutx.doc
@page
@node coff backends, oasys backends, aout backends, BFD back end
@include doc/coffcode.doc
@page
@node Index, , BFD, Top
@unnumbered Function Index
@printindex fn
@setchapternewpage on
@unnumbered Index
@printindex cp
@tex
% I think something like @colophon should be in texinfo. In the
% meantime:
\long\def\colophon{\hbox to0pt{}\vfill
\centerline{The body of this manual is set in}
\centerline{\fontname\tenrm,}
\centerline{with headings in {\bf\fontname\tenbf}}
\centerline{and examples in {\tt\fontname\tentt}.}
\centerline{{\it\fontname\tenit\/} and}
\centerline{{\sl\fontname\tensl\/}}
\centerline{are used for emphasis.}\vfill}
\page\colophon
% Blame: pesch@cygnus.com, 28mar91.
@end tex
@contents
@bye

244
bfd/coff-a29k.c Normal file
View file

@ -0,0 +1,244 @@
/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
Contributed by David Wood at New York University 7/8/91
This file is part of BFD, the Binary File Diddler.
BFD is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
BFD is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with BFD; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* $Id$ */
#define A29K 1
#include <ansidecl.h>
#include <sysdep.h>
#include "bfd.h"
#include "libbfd.h"
#include "obstack.h"
#include "amdcoff.h"
#include "internalcoff.h"
#include "libcoff.h"
#define INSERT_HWORD(WORD,HWORD) \
(((WORD) & 0xff00ff00) | (((HWORD) & 0xff00) << 8) | ((HWORD)& 0xff))
#define EXTRACT_HWORD(WORD) (((WORD) & 0x00ff0000) >> 8) | ((WORD) & 0xff)
/* Provided the symbol, returns the value reffed */
static long
get_symbol_value(symbol)
asymbol *symbol;
{
long relocation = 0;
if (symbol != (asymbol *)NULL) {
if (symbol->flags & BSF_FORT_COMM) {
relocation = 0;
} else {
relocation = symbol->value;
}
if (symbol->section != (asection *)NULL) {
relocation += symbol->section->output_section->vma +
symbol->section->output_offset;
}
}
return(relocation);
}
static bfd_reloc_status_enum_type
a29k_reloc(abfd, reloc_entry, symbol_in, data, input_section)
bfd *abfd;
arelent *reloc_entry;
asymbol *symbol_in;
unsigned char *data;
asection *input_section;
{
static unsigned long part1_consth_active=0;
static unsigned long part1_consth_value;
unsigned long insn, value, sym_value;
unsigned short r_type;
/* bfd_reloc_status_enum_type result;*/
/* coff_symbol_type *cs = coffsymbol(symbol_in);*/
r_type = reloc_entry->howto->type;
/* FIXME: Do we need to check for partial linking here */
if (symbol_in && (symbol_in->flags & BSF_UNDEFINED)) {
/* Keep the state machine happy in case we're called again */
if (r_type == R_IHIHALF) {
part1_consth_active = 1;
part1_consth_value = 0;
}
return(bfd_reloc_undefined);
}
if ((part1_consth_active) && (r_type != R_IHCONST)) {
fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"Missing IHCONST in module %s\n",abfd->filename);
part1_consth_active = 0;
return(bfd_reloc_dangerous);
}
insn = bfd_get_32(abfd, data + reloc_entry->address);
sym_value = get_symbol_value(symbol_in);
switch (r_type) {
case R_IREL:
value = EXTRACT_HWORD(insn) << 2;
value += sym_value + reloc_entry->addend;
if (value <= 0x3ffff) { /* Absolute jmp/call */
insn |= 0x01000000; /* Make it absolute */
/* FIXME: Should we change r_type to R_IABS */
} else { /* Relative jmp/call */
value -= reloc_entry->address;
if (value > 0x3ffff) {
fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"Jmp/call too far; to %d from %s\n",
symbol_in->name,abfd->filename);
return(bfd_reloc_outofrange);
}
}
value >>= 2;
insn = INSERT_HWORD(insn,value);
break;
case R_ILOHALF:
value = EXTRACT_HWORD(insn);
value += sym_value + reloc_entry->addend;
insn = INSERT_HWORD(insn,value);
break;
case R_IHIHALF: /* consth, part 1 */
/* Just get the symbol value that is referenced */
part1_consth_active = 1;
part1_consth_value = sym_value + reloc_entry->addend;
return(bfd_reloc_ok); /* Don't modify insn until R_IHCONST */
break;
case R_IHCONST: /* consth, part 2 */
/* Now relocate the reference */
if (!part1_consth_active) {
fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"IHIHALF missing in module %s\n",
abfd->filename);
part1_consth_active = 0;
return(bfd_reloc_dangerous);
}
/* sym_ptr_ptr = r_symndx, in coff_slurp_reloc_table() */
value = (unsigned int)reloc_entry->addend; /* r_symndx */
value += part1_consth_value;
value >>= 16;
insn = INSERT_HWORD(insn,value);
part1_consth_active = 0;
break;
case R_BYTE:
value = (insn >> 24) + sym_value + reloc_entry->addend;
if (value & 0xffffff00) {
fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"byte value too large in module %s\n",
abfd->filename);
return(bfd_reloc_overflow);
}
insn = (insn & 0x00ffffff) | (value << 24);
break;
case R_HWORD:
value = (insn >> 16) + sym_value + reloc_entry->addend;
if (value & 0xffff0000) {
fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"hword value too large in module %s\n",
abfd->filename);
return(bfd_reloc_overflow);
}
insn = (insn & 0x0000ffff) | (value<<16);
break;
case R_WORD:
insn += sym_value + reloc_entry->addend;
break;
default:
fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"Unrecognized reloc type %d, in module %s\n",
r_type,abfd->filename);
return (bfd_reloc_dangerous);
}
bfd_put_32(abfd, insn, data+reloc_entry->address);
return(bfd_reloc_ok);
}
/* type rightshift
size
bitsize
pc-relative
bitpos
absolute
complain_on_overflow
special_function
relocation name
partial_inplace
src_mask
*/
/*FIXME: I'm not real sure about this table */
#define NA 0 /* Obsolete fields, via the documentation */
static reloc_howto_type howto_table[] =
{
{R_ABS, 0, 3, NA, false, NA, NA, true,a29k_reloc,"ABS", true, 0xffffffff,0xffffffff, false},
{1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10},
{11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20},
{21}, {22}, {23},
{R_IREL, 0, 3, NA, true, NA, NA, true,a29k_reloc,"IREL", true, 0xffffffff,0xffffffff, false},
{R_IABS, 0, 3, NA, false, NA, NA, true,a29k_reloc,"IABS", true, 0xffffffff,0xffffffff, false},
{R_ILOHALF, 0, 3, NA, true, NA, NA, true,a29k_reloc,"ILOHALF", true, 0x0000ffff,0x0000ffff, false},
{R_IHIHALF, 0, 3, NA, true, NA, NA, true,a29k_reloc,"IHIHALF", true, 0xffff0000,0xffff0000, false},
{R_IHCONST, 0, 3, NA, true, NA, NA, true,a29k_reloc,"IHCONST", true, 0xffff0000,0xffff0000, false},
{R_BYTE, 0, 0, NA, false, NA, NA, true,a29k_reloc,"BYTE", true, 0x000000ff,0x000000ff, false},
{R_HWORD, 0, 1, NA, false, NA, NA, true,a29k_reloc,"HWORD", true, 0x0000ffff,0x0000ffff, false},
{R_WORD, 0, 2, NA, false, NA, NA, true,a29k_reloc,"WORD", true, 0xffffffff,0xffffffff, false},
};
#undef NA
#define BADMAG(x) A29KBADMAG(x)
#include "coffcode.h"
bfd_target a29kcoff_big_vec =
{
"coff-a29k-big", /* name */
bfd_target_coff_flavour_enum,
true, /* data byte order is big */
true, /* header byte order is big */
(HAS_RELOC | EXEC_P | /* object flags */
HAS_LINENO | HAS_DEBUG |
HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
(SEC_HAS_CONTENTS | SEC_ALLOC /* section flags */
| SEC_LOAD | SEC_RELOC
| SEC_READONLY ),
'/', /* ar_pad_char */
15, /* ar_max_namelen */
3, /* minimum section alignment */
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
{_bfd_dummy_target, coff_object_p, /* bfd_check_format */
bfd_generic_archive_p, _bfd_dummy_target},
{bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
bfd_false},
{bfd_false, coff_write_object_contents, /* bfd_write_contents */
_bfd_write_archive_contents, bfd_false},
JUMP_TABLE(coff),
COFF_SWAP_TABLE
};

348
binutils/am29k-pinsn.c Normal file
View file

@ -0,0 +1,348 @@
/* Instruction printing code for the AMD 29000
Copyright (C) 1990 Free Software Foundation, Inc.
Contributed by Cygnus Support. Written by Jim Kingdon.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#ifdef GDB
# include "defs.h"
# include "target.h"
# include "am29k-opcode.h"
#else
# include "sysdep.h"
# include "bfd.h"
# include "a29k-opcode.h"
# define am29k_opcodes a29k_opcodes
# define am29k_opcode a29k_opcode
# define NUM_OPCODES num_opcodes
# define fprintf_filtered fprintf
#endif
/* Print a symbolic representation of a general-purpose
register number NUM on STREAM.
NUM is a number as found in the instruction, not as found in
debugging symbols; it must be in the range 0-255. */
static void
print_general (num, stream)
int num;
FILE *stream;
{
if (num < 128)
fprintf_filtered (stream, "gr%d", num);
else
fprintf_filtered (stream, "lr%d", num - 128);
}
/* Like print_general but a special-purpose register.
The mnemonics used by the AMD assembler are not quite the same
as the ones in the User's Manual. We use the ones that the
assembler uses. */
static void
print_special (num, stream)
int num;
FILE *stream;
{
/* Register names of registers 0-SPEC0_NUM-1. */
static char *spec0_names[] = {
"vab", "ops", "cps", "cfg", "cha", "chd", "chc", "rbp", "tmc", "tmr",
"pc0", "pc1", "pc2", "mmu", "lru"
};
#define SPEC0_NUM ((sizeof spec0_names) / (sizeof spec0_names[0]))
/* Register names of registers 128-128+SPEC128_NUM-1. */
static char *spec128_names[] = {
"ipc", "ipa", "ipb", "q", "alu", "bp", "fc", "cr"
};
#define SPEC128_NUM ((sizeof spec128_names) / (sizeof spec128_names[0]))
/* Register names of registers 160-160+SPEC160_NUM-1. */
static char *spec160_names[] = {
"fpe", "inte", "fps", "sr163", "exop"
};
#define SPEC160_NUM ((sizeof spec160_names) / (sizeof spec160_names[0]))
if (num < SPEC0_NUM)
fprintf_filtered (stream, spec0_names[num]);
else if (num >= 128 && num < 128 + SPEC128_NUM)
fprintf_filtered (stream, spec128_names[num-128]);
else if (num >= 160 && num < 160 + SPEC160_NUM)
fprintf_filtered (stream, spec160_names[num-160]);
else
fprintf_filtered (stream, "sr%d", num);
}
/* Is an instruction with OPCODE a delayed branch? */
static int
is_delayed_branch (opcode)
int opcode;
{
return (opcode == 0xa8 || opcode == 0xa9 || opcode == 0xa0 || opcode == 0xa1
|| opcode == 0xa4 || opcode == 0xa5
|| opcode == 0xb4 || opcode == 0xb5
|| opcode == 0xc4 || opcode == 0xc0
|| opcode == 0xac || opcode == 0xad
|| opcode == 0xcc);
}
/* Now find the four bytes of INSN and put them in *INSN{0,8,16,24}.
Note that the amd can be set up as either
big or little-endian (the tm file says which) and we can't assume
the host machine is the same. */
static void
find_bytes (insn, insn0, insn8, insn16, insn24)
char *insn;
unsigned char *insn0;
unsigned char *insn8;
unsigned char *insn16;
unsigned char *insn24;
{
#if TARGET_BYTE_ORDER == BIG_ENDIAN
*insn24 = insn[0];
*insn16 = insn[1];
*insn8 = insn[2];
*insn0 = insn[3];
#else /* Little-endian. */
*insn24 = insn[3];
*insn16 = insn[2];
*insn8 = insn[1];
*insn0 = insn[0];
#endif /* Little-endian. */
}
/* Print one instruction from MEMADDR on STREAM.
Return the size of the instruction (always 4 on am29k). */
#ifdef GDB
print_insn (memaddr, stream)
CORE_ADDR memaddr;
FILE *stream;
#else
int
print_insn_a29k (memaddr, buffer, stream)
bfd_vma memaddr;
uint8e_type *buffer;
FILE *stream;
#endif
{
/* The raw instruction. */
char insn[4];
/* The four bytes of the instruction. */
unsigned char insn24, insn16, insn8, insn0;
struct am29k_opcode *opcode;
#ifdef GDB
read_memory (memaddr, &insn[0], 4);
#else
insn[0] = ((char*)buffer)[0];
insn[1] = ((char*)buffer)[1];
insn[2] = ((char*)buffer)[2];
insn[3] = ((char*)buffer)[3];
#endif
find_bytes (insn, &insn0, &insn8, &insn16, &insn24);
/* Handle the nop (aseq 0x40,gr1,gr1) specially */
if ((insn24==0x70) && (insn16==0x40) && (insn8==0x01) && (insn0==0x01)) {
fprintf_filtered (stream,"nop");
return 4;
}
/* The opcode is always in insn24. */
for (opcode = &am29k_opcodes[0];
opcode < &am29k_opcodes[NUM_OPCODES];
++opcode)
{
#ifdef GDB
if (insn24 == opcode->opcode)
#else
if (insn24 == (opcode->opcode >> 24))
#endif
{
char *s;
fprintf_filtered (stream, "%s ", opcode->name);
for (s = opcode->args; *s != '\0'; ++s)
{
switch (*s)
{
case 'a':
print_general (insn8, stream);
break;
case 'b':
print_general (insn0, stream);
break;
case 'c':
print_general (insn16, stream);
break;
case 'i':
fprintf_filtered (stream, "%d", insn0);
break;
case 'x':
fprintf_filtered (stream, "%d", (insn16 << 8) + insn0);
break;
case 'h':
fprintf_filtered (stream, "0x%x",
(insn16 << 24) + (insn0 << 16));
break;
case 'X':
fprintf_filtered (stream, "%d",
((insn16 << 8) + insn0) | 0xffff0000);
break;
case 'P':
/* This output looks just like absolute addressing, but
maybe that's OK (it's what the GDB 68k and EBMON
29k disassemblers do). */
/* All the shifting is to sign-extend it. p*/
print_address
(memaddr +
(((int)((insn16 << 10) + (insn0 << 2)) << 14) >> 14),
stream);
break;
case 'A':
print_address ((insn16 << 10) + (insn0 << 2), stream);
break;
case 'e':
fprintf_filtered (stream, "%d", insn16 >> 7);
break;
case 'n':
fprintf_filtered (stream, "0x%x", insn16 & 0x7f);
break;
case 'v':
fprintf_filtered (stream, "%x", insn16);
break;
case 's':
print_special (insn8, stream);
break;
case 'u':
fprintf_filtered (stream, "%d", insn0 >> 7);
break;
case 'r':
fprintf_filtered (stream, "%d", (insn0 >> 4) & 7);
break;
case 'd':
fprintf_filtered (stream, "%d", (insn0 >> 2) & 3);
break;
case 'f':
fprintf_filtered (stream, "%d", insn0 & 3);
break;
case 'F':
fprintf_filtered (stream, "%d", (insn0 >> 18) & 15);
break;
case 'C':
fprintf_filtered (stream, "%d", (insn0 >> 16) & 3);
break;
default:
fprintf_filtered (stream, "%c", *s);
}
}
/* Now we look for a const,consth pair of instructions,
in which case we try to print the symbolic address. */
if (insn24 == 2) /* consth */
{
int errcode;
char prev_insn[4];
unsigned char prev_insn0, prev_insn8, prev_insn16, prev_insn24;
#ifdef GDB
errcode = target_read_memory (memaddr - 4,
&prev_insn[0],
4);
#else
prev_insn[0] = ((char*)buffer)[0-4];
prev_insn[1] = ((char*)buffer)[1-4];
prev_insn[2] = ((char*)buffer)[2-4];
prev_insn[3] = ((char*)buffer)[3-4];
errcode = 0;
#endif
if (errcode == 0)
{
/* If it is a delayed branch, we need to look at the
instruction before the delayed brach to handle
things like
const _foo
call _printf
consth _foo
*/
find_bytes (prev_insn, &prev_insn0, &prev_insn8,
&prev_insn16, &prev_insn24);
if (is_delayed_branch (prev_insn24))
{
#ifdef GDB
errcode = target_read_memory
(memaddr - 8, &prev_insn[0], 4);
#else
prev_insn[0] = ((char*)buffer)[0-8];
prev_insn[1] = ((char*)buffer)[1-8];
prev_insn[2] = ((char*)buffer)[2-8];
prev_insn[3] = ((char*)buffer)[3-8];
errcode = 0;
#endif
find_bytes (prev_insn, &prev_insn0, &prev_insn8,
&prev_insn16, &prev_insn24);
}
}
/* If there was a problem reading memory, then assume
the previous instruction was not const. */
if (errcode == 0)
{
/* Is it const to the same register? */
if (prev_insn24 == 3
&& prev_insn8 == insn8)
{
fprintf_filtered (stream, "\t; ");
print_address (((insn16 << 24) + (insn0 << 16)
+ (prev_insn16 << 8) + (prev_insn0)),
stream);
}
}
}
return 4;
}
}
fprintf_filtered (stream, ".word %8x",
(insn24 << 24) + (insn16 << 16) + (insn8 << 8) + insn0);
return 4;
}

303
include/coff-a29k.h Executable file
View file

@ -0,0 +1,303 @@
/* COFF spec for AMD 290*0
Contributed by David Wood @ New York University.
*/
#ifndef AMD
# define AMD
#endif
/****************************************************************/
/*
** File Header and related definitions
*/
struct external_filehdr
{
char f_magic[2]; /* magic number */
char f_nscns[2]; /* number of sections */
char f_timdat[4]; /* time & date stamp */
char f_symptr[4]; /* file pointer to symtab */
char f_nsyms[4]; /* number of symtab entries */
char f_opthdr[2]; /* sizeof(optional hdr) */
char f_flags[2]; /* flags */
};
#define FILHDR struct external_filehdr
#define FILHSZ sizeof (FILHDR)
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/*
** Magic numbers for Am29000
** (AT&T will assign the "real" magic number)
*/
#define SIPFBOMAGIC 0572 /* Am29000 (Byte 0 is MSB) */
#define SIPRBOMAGIC 0573 /* Am29000 (Byte 0 is LSB) */
#define A29K_MAGIC_BIG SIPFBOMAGIC
#define A29K_MAGIC_LITTLE SIPRBOMAGIC
#define A29KBADMAG(x) (((x).f_magic!=A29K_MAGIC_BIG) && \
((x).f_magic!=A29K_MAGIC_LITTLE))
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/*
** File header flags currently known to us.
**
** Am29000 will use the F_AR32WR and F_AR32W flags to indicate
** the byte ordering in the file.
*/
/*--------------------------------------------------------------*/
/*
** Optional (a.out) header
*/
typedef struct external_aouthdr
{
char magic[2]; /* type of file */
char vstamp[2]; /* version stamp */
char tsize[4]; /* text size in bytes, padded to FW bdry*/
char dsize[4]; /* initialized data " " */
char bsize[4]; /* uninitialized data " " */
char entry[4]; /* entry pt. */
char text_start[4]; /* base of text used for this file */
char data_start[4]; /* base of data used for this file */
} AOUTHDR;
#define AOUTSZ (sizeof(AOUTHDR))
/* aouthdr magic numbers */
#define NMAGIC 0410 /* separate i/d executable */
#define SHMAGIC 0406 /* NYU/Ultra3 shared data executable
(writable text) */
#define _ETEXT "_etext"
/*--------------------------------------------------------------*/
/*
** Section header and related definitions
*/
struct external_scnhdr
{
char s_name[8]; /* section name */
char s_paddr[4]; /* physical address, aliased s_nlib */
char s_vaddr[4]; /* virtual address */
char s_size[4]; /* section size */
char s_scnptr[4]; /* file ptr to raw data for section */
char s_relptr[4]; /* file ptr to relocation */
char s_lnnoptr[4]; /* file ptr to line numbers */
char s_nreloc[2]; /* number of relocation entries */
char s_nlnno[2]; /* number of line number entries*/
char s_flags[4]; /* flags */
};
#define SCNHDR struct external_scnhdr
#define SCNHSZ sizeof (SCNHDR)
/*
* names of "special" sections
*/
#define _TEXT ".text"
#define _DATA ".data"
#define _BSS ".bss"
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/*
** Section types - with additional section type for global
** registers which will be relocatable for the Am29000.
**
** In instances where it is necessary for a linker to produce an
** output file which contains text or data not based at virtual
** address 0, e.g. for a ROM, then the linker should accept
** address base information as command input and use PAD sections
** to skip over unused addresses.
*/
#define STYP_BSSREG 0x1200 /* Global register area (like STYP_INFO) */
#define STYP_ENVIR 0x2200 /* Environment (like STYP_INFO) */
#define STYP_ABS 0x4000 /* Absolute (allocated, not reloc, loaded) */
#define STYP_LIT 0x8020 /* Literal data (like STYP_TEXT) */
/*--------------------------------------------------------------*/
/*
** Relocation information declaration and related definitions
*/
struct external_reloc {
char r_vaddr[4]; /* (virtual) address of reference */
char r_symndx[4]; /* index into symbol table */
char r_type[2]; /* relocation type */
};
#define RELOC struct external_reloc
#define RELSZ 10 /* sizeof (RELOC) */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/*
** Relocation types for the Am29000
*/
#define R_ABS 0 /* reference is absolute */
#define R_IREL 030 /* instruction relative (jmp/call) */
#define R_IABS 031 /* instruction absolute (jmp/call) */
#define R_ILOHALF 032 /* instruction low half (const) */
#define R_IHIHALF 033 /* instruction high half (consth) part 1 */
#define R_IHCONST 034 /* instruction high half (consth) part 2 */
/* constant offset of R_IHIHALF relocation */
#define R_BYTE 035 /* relocatable byte value */
#define R_HWORD 036 /* relocatable halfword value */
#define R_WORD 037 /* relocatable word value */
#define R_IGLBLRC 040 /* instruction global register RC */
#define R_IGLBLRA 041 /* instruction global register RA */
#define R_IGLBLRB 042 /* instruction global register RB */
/*
NOTE:
All the "I" forms refer to 29000 instruction formats. The linker is
expected to know how the numeric information is split and/or aligned
within the instruction word(s). R_BYTE works for instructions, too.
If the parameter to a CONSTH instruction is a relocatable type, two
relocation records are written. The first has an r_type of R_IHIHALF
(33 octal) and a normal r_vaddr and r_symndx. The second relocation
record has an r_type of R_IHCONST (34 octal), a normal r_vaddr (which
is redundant), and an r_symndx containing the 32-bit constant offset
to the relocation instead of the actual symbol table index. This
second record is always written, even if the constant offset is zero.
The constant fields of the instruction are set to zero.
*/
/*--------------------------------------------------------------*/
/*
** Line number entry declaration and related definitions
*/
struct external_lineno
{
union {
char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
char l_paddr[4]; /* (physical) address of line number */
} l_addr;
char l_lnno[2]; /* line number */
};
#define LINENO struct external_lineno
#define LINESZ 6 /* sizeof (LINENO) */
/*--------------------------------------------------------------*/
/*
** Symbol entry declaration and related definitions
*/
#define SYMNMLEN 8 /* Number of characters in a symbol name */
struct external_syment
{
union {
char e_name[SYMNMLEN];
struct {
char e_zeroes[4];
char e_offset[4];
} e;
} e;
char e_value[4];
char e_scnum[2];
char e_type[2];
char e_sclass[1];
char e_numaux[1];
};
#define SYMENT struct external_syment
#define SYMESZ sizeof(SYMENT)
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/*
** Storage class definitions - new classes for global registers.
*/
#define C_GLBLREG 19 /* global register */
#define C_EXTREG 20 /* external global register */
#define C_DEFREG 21 /* ext. def. of global register */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/*
** Derived symbol mask/shifts.
*/
#define N_BTMASK (0xf)
#define N_BTSHFT (4)
#define N_TMASK (0x30)
#define N_TSHIFT (2)
/*--------------------------------------------------------------*/
/*
** Auxiliary symbol table entry declaration and related
** definitions.
*/
#define FILNMLEN 14 /* # characters in a file name */
#define DIMNUM 4 /* # array dimensions in auxiliary entry */
union external_auxent {
struct {
char x_tagndx[4]; /* str, un, or enum tag indx */
union {
struct {
char x_lnno[2]; /* declaration line number */
char x_size[2]; /* str/union/array size */
} x_lnsz;
char x_fsize[4]; /* size of function */
} x_misc;
union {
struct { /* if ISFCN, tag, or .bb */
char x_lnnoptr[4]; /* ptr to fcn line # */
char x_endndx[4]; /* entry ndx past block end */
} x_fcn;
struct { /* if ISARY, up to 4 dimen. */
char x_dimen[DIMNUM][2];
} x_ary;
} x_fcnary;
char x_tvndx[2]; /* tv index */
} x_sym;
union {
char x_fname[FILNMLEN];
struct {
char x_zeroes[4];
char x_offset[4];
} x_n;
} x_file;
struct {
char x_scnlen[4]; /* section length */
char x_nreloc[2]; /* # relocation entries */
char x_nlinno[2]; /* # line numbers */
} x_scn;
struct {
char x_tvfill[4]; /* tv fill value */
char x_tvlen[2]; /* length of .tv */
char x_tvran[2][2]; /* tv range */
} x_tv; /* info about .tv section (in auxent of symbol .tv)) */
};
#define AUXENT union external_auxent
#define AUXESZ 18

4
ld/config/hmake-rtbsd Executable file
View file

@ -0,0 +1,4 @@
YACC = yacc -d
HDEFINES = -DHOST_SYS=RTBSD_SYS -DNO_VARARGS
LDFLAGS =
CC=gcc

1
ld/config/tmake-coff-a29k Executable file
View file

@ -0,0 +1 @@
TDEFINES = -DDEFAULT_EMULATION=GLD29K_EMULATION_NAME

144
ld/ldglda29k.c Executable file
View file

@ -0,0 +1,144 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
GLD is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GLD is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GLD; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
* $Id:#
*/
/*
* emulate the original gld running on an a29k system
*
* Written by David Wood @ New York University
*/
#include "sysdep.h"
#include "bfd.h"
#include "ld.h"
#include "config.h"
#include "ldemul.h"
#include "ldfile.h"
#include "ldmisc.h"
extern boolean lang_float_flag;
extern enum bfd_architecture ldfile_output_architecture;
extern unsigned long ldfile_output_machine;
extern char *ldfile_output_machine_name;
extern bfd *output_bfd;
static void gld29k_before_parse()
{
#ifndef NOTDEF /* Cross developing for now */
ldfile_add_library_path("/lib");
ldfile_add_library_path("/usr/lib");
ldfile_add_library_path("/usr/local/lib");
#endif
ldfile_output_architecture = bfd_arch_a29k;
}
static void
gld29k_after_parse()
{
}
static void
gld29k_after_allocation()
{
}
static void
gld29k_before_allocation()
{
}
static void
gld29k_set_output_arch()
{
/* Set the output architecture and machine if possible */
unsigned long machine = 0;
bfd_set_arch_mach(output_bfd, ldfile_output_architecture, machine);
}
static char *
gld29k_choose_target()
{
char *from_outside = getenv(TARGET_ENVIRON);
if (from_outside != (char *)NULL)
return from_outside;
return GLD29K_TARGET;
}
static void
gld29k_syslib()
{
info("%S SYSLIB ignored\n");
}
static void
gld29k_hll(ignore)
char *ignore;
{
info("%S HLL ignored\n");
}
static char *gld29k_script =
#include "ldglda29k.x"
;
static char *gld29k_script_option_Ur =
#include "ldglda29kUr.x"
;
static char *gld29k_script_option_r =
#include "ldglda29kr.x"
;
static char *gld29k_get_script()
{
extern ld_config_type config;
if (config.relocateable_output == true &&
config.build_constructors == true) {
return gld29k_script_option_Ur;
}
if (config.relocateable_output) {
return gld29k_script_option_r;
}
return gld29k_script;
}
struct ld_emulation_xfer_struct ld_gld29k_emulation =
{
gld29k_before_parse,
gld29k_syslib,
gld29k_hll,
gld29k_after_parse,
gld29k_after_allocation,
gld29k_set_output_arch,
gld29k_choose_target,
gld29k_before_allocation,
gld29k_get_script,
};

38
ld/ldglda29k.script Executable file
View file

@ -0,0 +1,38 @@
OUTPUT_FORMAT("coff-a29k-big")
INPUT(/lab3/u3/sym1/tools/usr/lib/segments.o) /* Has .rstack/.mstack */
SEARCH_DIR(/lab3/u3/sym1/tools/lib)
SEARCH_DIR(/lab3/u3/sym1/tools/usr/lib)
SEARCH_DIR(/lab3/u3/sym1/tools/usr/local/lib)
MEMORY {
text : ORIGIN = 0x1000000, LENGTH = 0x1000000
talias : ORIGIN = 0x2000000, LENGTH = 0x1000000
data : ORIGIN = 0x3000000, LENGTH = 0x1000000
mstack : ORIGIN = 0x4000000, LENGTH = 0x1000000
rstack : ORIGIN = 0x5000000, LENGTH = 0x1000000
}
SECTIONS
{
.text : {
*(.text)
__etext = .;
*(.lit)
*(.shdata)
} > text
.shbss SIZEOF(.text) + ADDR(.text) : {
*(.shbss)
}
.talias : { } > talias
.data : {
*(.data)
__edata = .;
} > data
.bss SIZEOF(.data) + ADDR(.data) :
{
*(.bss)
[COMMON]
__end = ALIGN(0x8);
}
.mstack : { } > mstack
.rstack : { } > rstack
}

32
ld/ldglda29kUr.script Executable file
View file

@ -0,0 +1,32 @@
OUTPUT_FORMAT("coff-a29k-big")
SEARCH_DIR(/lab3/u3/sym1/tools/lib)
SEARCH_DIR(/lab3/u3/sym1/tools/usr/lib)
SEARCH_DIR(/lab3/u3/sym1/tools/usr/local/lib)
MEMORY {
text : ORIGIN = 0x1000000, LENGTH = 0x1000000
talias : ORIGIN = 0x2000000, LENGTH = 0x1000000
data : ORIGIN = 0x3000000, LENGTH = 0x1000000
mstack : ORIGIN = 0x4000000, LENGTH = 0x1000000
rstack : ORIGIN = 0x5000000, LENGTH = 0x1000000
}
SECTIONS
{
.text 0 : {
*(.text)
__etext = .;
*(.lit)
*(.shdata)
} > text
.shbss SIZEOF(.text) + ADDR(.text) : {
*(.shbss)
}
.data SIZEOF(.shbss) + ADDR(.shbss): {
*(.data)
}
.bss SIZEOF(.data) + ADDR(.data) :
{
*(.bss)
[COMMON]
}
}

32
ld/ldglda29kr.script Executable file
View file

@ -0,0 +1,32 @@
OUTPUT_FORMAT("coff-a29k-big")
SEARCH_DIR(/lab3/u3/sym1/tools/lib)
SEARCH_DIR(/lab3/u3/sym1/tools/usr/lib)
SEARCH_DIR(/lab3/u3/sym1/tools/usr/local/lib)
MEMORY {
text : ORIGIN = 0x1000000, LENGTH = 0x1000000
talias : ORIGIN = 0x2000000, LENGTH = 0x1000000
data : ORIGIN = 0x3000000, LENGTH = 0x1000000
mstack : ORIGIN = 0x4000000, LENGTH = 0x1000000
rstack : ORIGIN = 0x5000000, LENGTH = 0x1000000
}
SECTIONS
{
.text 0 : {
*(.text)
__etext = .;
*(.lit)
*(.shdata)
} > text
.shbss SIZEOF(.text) + ADDR(.text) : {
*(.shbss)
}
.data SIZEOF(.shbss) + ADDR(.shbss): {
*(.data)
}
.bss SIZEOF(.data) + ADDR(.data) :
{
*(.bss)
[COMMON]
}
}