Initial revision
This commit is contained in:
parent
a737c70bde
commit
2013f9b4e1
10 changed files with 1576 additions and 0 deletions
430
bfd/bfd.texinfo
Executable file
430
bfd/bfd.texinfo
Executable 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
244
bfd/coff-a29k.c
Normal 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
348
binutils/am29k-pinsn.c
Normal 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
303
include/coff-a29k.h
Executable 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
4
ld/config/hmake-rtbsd
Executable 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
1
ld/config/tmake-coff-a29k
Executable file
|
@ -0,0 +1 @@
|
|||
TDEFINES = -DDEFAULT_EMULATION=GLD29K_EMULATION_NAME
|
144
ld/ldglda29k.c
Executable file
144
ld/ldglda29k.c
Executable 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
38
ld/ldglda29k.script
Executable 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
32
ld/ldglda29kUr.script
Executable 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
32
ld/ldglda29kr.script
Executable 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]
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in a new issue