@@ -1,22 +1,38 @@
/* MIPS Extended-Coff handler for Binary File Diddling.
Written by Per Bothner.
FIXME, Needs Copyleft here. */
/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
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. */
/* This does not compile on anything but a MIPS yet (and I haven't been
able to test it there either since the latest merge!). So it stays
out by default. */
# ifdef ECOFF_BFD
# define MIPS 1
# include <stdio.h>
# include <string.h>
# include "bfd.h"
# include "libbfd.h"
# include "sysdep.h"
# include "libcoff.h" /* to allow easier abstraction-breaking */
# include "intel-coff.h"
# include "libcoff.h" /* to allow easier abstraction-breaking */
static reloc_howto_type howto_table [ ] =
{
@@ -47,7 +63,7 @@ static reloc_howto_type howto_table[] =
{ 24 } ,
{ R_IPRMED , 2 , 2 , 22 , 1 , 0 , true , true } ,
{ 26 } ,
/* What do we do with this - ? */
/* FIXME: What do we do with this - ? */
# if 1
{ R_OPTCALL , 0 , 2 , 32 , 0 , 0 , true , true } ,
# else
@@ -63,9 +79,6 @@ static reloc_howto_type howto_table[] =
/* Support for Motorola 88k bcs coff as well as Intel 960 coff */
# include <stdio.h>
# include <string.h>
/* Align an address by rounding it up to a power of two. It leaves the
address unchanged if align == 0 (2^0 = alignment of 1 byte) */
@@ -83,55 +96,18 @@ void fatal();
* peculiar to this particular implementation of coff
*/
static void
static boolean
ecoff_new_section_hook ( abfd , section )
bfd * abfd ;
asection * section ;
{
section - > output_file_alignment = DEFAULT_SECTION_ALIGNMENT ;
section - > subsection_alignment = section - > output_file_alignment ;
if ( abfd - > flags & D_PAGED )
{
/**
If the output object file is demand paged then the
text section starts at the filehdr, with the first
usefull bit of data at the end of the filehdr+opthdr+
scnhdrs. Since we don't know how many sections will
be put into the output file, we have to recalculate
the section pads after each additional section has
been created
**/
asection * ptr = abfd - > sections ;
unsigned int padding = FILHSZ + AOUTSZ + SCNHSZ * abfd - > section_count ;
padding = ALIGN ( padding , ptr - > output_file_alignment ) ;
while ( ptr )
{
ptr - > start_pad = padding ;
/* Only the first section is padded */
padding = 0 ;
ptr = ptr - > next ;
}
}
else
{
/* If the object is not demand paged, then all the sections
have no padding
*/
section - > start_pad = 0 ;
}
return true ;
}
/* actually it makes itself and its children from the file headers */
static boolean
make_a_section_from_file ( abfd , hdr )
bfd * abfd ;
bfd * abfd ;
struct scnhdr * hdr ;
{
asection * return_section ;
@@ -147,7 +123,7 @@ bfd *abfd;
/* FIXME -- needs to call swapping routines */
# define assign(to, from) return_section->to = hdr->from
assign ( vma , s_vaddr ) ;
assign ( original_vma , s_vaddr) ;
/* assign (vma, s_vaddr);*/
assign ( size , s_size ) ;
assign ( filepos , s_scnptr ) ;
assign ( rel_filepos , s_relptr ) ;
@@ -186,7 +162,7 @@ ecoff_real_object_p (abfd, nscns, opthdr)
/* OK, now we know the format, read in the filehdr, soi-disant
"optional header", and all the sections.*/
readsize = sizeof ( struct filehdr ) + opthdr + ( nscns * sizeof ( struct scnhdr ) ) ;
file_info = xmalloc ( readsize ) ;
file_info = ( char * ) bfd_alloc ( abfd , readsize ) ;
if ( file_info = = NULL ) {
bfd_error = no_memory ;
return 0 ;
@@ -197,9 +173,10 @@ ecoff_real_object_p (abfd, nscns, opthdr)
sections = ( struct scnhdr * ) ( file_info + sizeof ( struct filehdr ) + opthdr ) ;
/* Now copy data as required; construct all asections etc */
tdata = ( struct icofdata * ) xm alloc ( sizeof ( struct icofdata ) +
sizeof ( AOUTHDR ) ) ;
tdata = ( struct icofdata * ) bfd_z alloc ( abfd , sizeof ( struct icofdata ) +
sizeof ( AOUTHDR ) ) ;
if ( tdata = = NULL ) {
bfd_release ( abfd , file_info ) ;
bfd_error = no_memory ;
return 0 ;
}
@@ -213,44 +190,22 @@ ecoff_real_object_p (abfd, nscns, opthdr)
}
}
# ifdef I960
/* OK, now make a section for the tagbits if there were any */
#if 0
{
AOUTHDR *aouthdr; /* points into tdata! */
aouthdr = (AOUTHDR *) (((char *) tdata) + sizeof (struct icofdata));
if (aouthdr->tagentries != 0) {
asection *tag_section = (asection *) xmalloc (sizeof (asection));
if (tag_section == NULL) {
free (tdata);
return 0;
}
tag_section->size = aouthdr->tagentries * sizeof (TAGBITS);
tag_section->name = TAG_SECTION_NAME;
tag_section->filepos = readsize; /* not surprisingly */
/* Put this one first */
tag_section->next = abfd->sections;
abfd->sections = tag_section;
}
}
#endif
# endif
abfd - > flags | = HAS_RELOC | HAS_LINENO | HAS_LOCALS ;
abfd - > flags | = HAS_RELOC | HAS_LINENO | HAS_LOCALS ;
/* FIXME, the guess should be set by OR-ing info from the sections */
if ( ( filehdr - > f_flags & F_RELFLG ) ! = F_RELFLG ) abfd - > flags & = ~ HAS_RELOC ;
if ( ( filehdr - > f_flags & F_EXEC ) = = F_EXEC ) abfd - > flags | = EXEC_P ;
if ( ( filehdr - > f_flags & F_LNNO ) ! = F_LNNO ) abfd - > flags & = ~ HAS_LINENO ;
if ( ( filehdr - > f_flags & F_LSYMS ) ! = F_LSYMS ) abfd - > flags & = ~ HAS_LOCALS ;
abfd - > tdata = tdata ;
set_tdata ( abfd , tdata ) ;
bfd_get_symcount ( abfd ) = filehdr - > f_nsyms ;
if ( filehdr - > f_nsyms ) abfd - > flags | = HAS_SYMS ;
tdata - > sym_filepos = filehdr - > f_symptr ;
tdata - > hdr = ( struct aouthdr * ) ( file_info + sizeof ( struct filehdr ) ) ;
tdata - > symbols = ( esymbol * ) NULL ;
bfd_get_start_address ( abfd ) = exec_hdr ( abfd ) - > entry ;
/* FIXME, needs byte swapping */
tdata - > hdr = * ( struct aouthdr * ) ( file_info + sizeof ( struct filehdr ) ) ;
tdata - > symbols = ( coff_symbol_type * ) NULL ;
bfd_get_start_address ( abfd ) = exec_hdr ( abfd ) . entry ;
return abfd - > xvec ;
}
@@ -275,7 +230,8 @@ ecoff_object_p (abfd)
return 0 ;
nscns = bfd_h_getshort ( abfd , ( unsigned char * ) & nscns ) ;
if ( bfd_seek ( abfd , ( ( sizeof ( long ) ) * 3 ) , true ) < 0 ) return false ;
if ( bfd_seek ( abfd , ( file_ptr ) ( ( sizeof ( long ) ) * 3 ) , true ) < 0 )
return 0 ;
if ( bfd_read ( & opthdr , 1 , sizeof ( opthdr ) , abfd ) ! = sizeof ( opthdr ) )
return 0 ;
opthdr = bfd_h_getshort ( abfd , ( unsigned char * ) & opthdr ) ;
@@ -293,15 +249,12 @@ ecoff_mkobject (abfd)
bfd_error = no_error ;
/* Use an intermediate variable for clarity */
rawptr = xmalloc ( sizeof ( struct icofdata ) + sizeof ( AOUTHDR ) ) ;
rawptr = ( char * ) bfd_zalloc ( abfd , sizeof ( struct icofdata ) ) ;
if ( rawptr = = NULL ) {
bfd_error = no_memory ;
return false ;
}
abfd - > tdata = ( struct icofdata * ) rawptr ;
exec_hdr ( abfd ) = ( AOUTHDR * ) ( rawptr + sizeof ( struct icofdata ) ) ;
set_tdata ( abfd , rawptr ) ;
return true ;
}
@@ -310,143 +263,38 @@ ecoff_count_linenumbers(abfd)
bfd * abfd ;
{
unsigned int limit = bfd_get_symcount ( abfd ) ;
unsigned int i = 0 ;
e symbol * * p = ( esymbol * * ) ( abfd - > outsymbols ) ;
unsigned int i ;
a symbol * * p ;
{
asection * s = abfd - > sections ;
asection * s = abfd - > sections - > output_section ;
while ( s ) {
if ( s - > lineno_count ! = 0 ) {
fatal ( " Bad initial state " ) ;
}
BFD_ASSERT ( s - > lineno_count = = 0 ) ;
s = s - > next ;
}
}
while ( i < limit )
for ( p = abfd - > outsymbols , i = 0 ; i < limit ; i + + , p + + )
{
e symbol * q = * p ;
if ( q - > c . lineno )
{
/* This symbol has a linenumber, increment the
* owning section's linenumber count */
alent * l = q - > c . lineno ;
q - > c . section - > lineno_count + + ;
l + + ;
while ( l - > line_number ) {
q - > c . section - > lineno_count + + ;
a symbol * q_maybe = * p ;
if ( q_maybe - > the_bfd - > xvec - > flavour = = bfd_target_coff_flavour_enum ) {
coff_symbol_type * q = coffsymbol ( q_maybe ) ;
if ( q - > lineno )
{
/* This symbol has a linenumber, increment the
* owning section's linenumber count */
alent * l = q - > lineno ;
q - > symbol . section - > output_section - > lineno_count + + ;
l + + ;
while ( l - > line_number ) {
q - > symbol . section - > output_section - > lineno_count + + ;
l + + ;
}
}
}
p + + ;
i + + ;
}
}
}
/*
run through the internal symbol table and make all the
pointers and things within the table point to the right places
*/
static void
ecoff_mangle_symbols ( abfd )
bfd * abfd ;
{
esymbol * * p = ( esymbol * * ) ( abfd - > outsymbols ) ;
unsigned int native_index = 0 ;
unsigned int last_file_index = 0 ;
unsigned int limit = bfd_get_symcount ( abfd ) ;
struct syment * last_file_symbol = ( struct syment * ) NULL ;
while ( limit - - ) {
esymbol * q = * p ;
struct syment * native = q - > native ;
if ( native ) {
/* Alter the native representation */
native - > n_value = q - > c . value ;
if ( q - > c . flags & BSF_FORT_COMM ) {
native - > n_scnum = 0 ;
}
else if ( q - > c . flags & BSF_DEBUGGING ) {
native - > n_scnum = - 2 ;
}
else if ( q - > c . flags & BSF_UNDEFINED ) {
native - > n_scnum = 0 ;
}
else if ( q - > c . flags & BSF_ABSOLUTE ) {
native - > n_scnum = - 1 ;
}
else {
native - > n_scnum = q - > c . section - > index + 1 ;
}
if ( native - > n_numaux )
{
union auxent * a = ( union auxent * ) ( native + 1 ) ;
/* Relocate symbol indexes */
if ( ISFCN ( native - > n_type ) )
{
a - > x_sym . x_fcnary . x_fcn . x_endndx + = last_file_index ;
}
else if ( native - > n_sclass = = C_BLOCK & & q - > c . name [ 1 ] = = ' b ' )
{
a - > x_sym . x_fcnary . x_fcn . x_endndx + = last_file_index ;
}
else if ( native - > n_sclass = = C_STRTAG )
{
a - > x_sym . x_fcnary . x_fcn . x_endndx + = last_file_index ;
}
else if ( native - > n_sclass = = C_MOS | | native - > n_sclass = = C_EOS | | native - > n_sclass = = C_MOE )
{
a - > x_sym . x_tagndx + = last_file_index ;
}
}
switch ( native - > n_sclass ) {
case C_MOS :
case C_EOS :
case C_REGPARM :
case C_REG :
case 19 : /*C_REGARG:FIXME */
/* Fix so that they have an absolute section */
native - > n_scnum = - 1 ;
break ;
case C_FILE :
/* Chain all the .file symbols together */
if ( last_file_symbol ) {
last_file_symbol - > n_value = native_index ;
}
last_file_symbol = native ;
last_file_index = native_index ;
break ;
case C_NULL :
case C_AUTO :
case C_EXT :
case C_EXTDEF :
case C_LABEL :
case C_ULABEL :
case C_USTATIC :
case C_STRTAG :
case C_FCN :
case C_BLOCK :
case C_STAT :
case C_LEAFPROC :
break ;
default :
/* Bogus: This should be returning an error code, not printing
something out! */
/* warning("Unrecognised sclass %d", native->n_sclass); */
break ;
}
native_index + = 1 + native - > n_numaux ;
}
else {
native_index + + ;
}
p + + ;
}
}
static void
ecoff_write_symbols ( abfd )
bfd * abfd ;
@@ -466,13 +314,11 @@ ecoff_make_empty_symbol(abfd, n)
bfd * abfd ;
unsigned int n ;
{
unsigned int j ;
esymbol * new = ( esymbol * ) xmalloc ( sizeof ( esymbol ) * n ) ;
for ( j = 0 ; j < n ; j + + ) {
new [ j ] . native = 0 ;
new [ j ] . c . lineno = ( alent * ) NULL ;
}
return ( asymbol * ) new ;
coff_symbol_type * new = ( coff_symbol_type * ) xmalloc ( sizeof ( coff_symbol_type ) ) ;
new - > native = 0 ;
new - > lineno = ( alent * ) NULL ;
new - > symbol . the_bfd = abfd ;
return & new - > symbol ;
}
/*SUPPRESS 558*/
@@ -490,23 +336,7 @@ static void
ecoff_compute_section_file_positions ( abfd )
bfd * abfd ;
{
file_ptr sofar = sizeof ( struct filehdr ) + sizeof ( AOUTHDR ) ;
asection * current ;
sofar + = abfd - > section_count * sizeof ( struct scnhdr ) ;
for ( current = abfd - > sections ; current ! = NULL ; current = current - > next ) {
sofar = ALIGN ( sofar , current - > output_file_alignment ) ;
current - > filepos = sofar ;
/* Only add sections which are loadable */
if ( current - > flags & SEC_LOAD ) sofar + = current - > size ;
#if 0
if(current->filepos & (current->alignment-1)) {
sofar += current->alignment - (current->filepos &(current->alignment-1));
current->filepos = (current->filepos + current->alignment) & -current->alignment;
}
#endif
}
obj_relocbase ( abfd ) = sofar ;
abort ( ) ;
}
boolean
@@ -539,31 +369,6 @@ ecoff_close_and_cleanup (abfd)
return false ;
}
static void *
buy_and_read ( abfd , where , relative , size )
bfd * abfd ;
int where ;
boolean relative ;
unsigned int size ;
{
void * area = ( void * ) xmalloc ( size ) ;
if ( ! area ) {
bfd_error = no_memory ;
return 0 ;
}
bfd_seek ( abfd , where , relative ) ;
if ( bfd_read ( area , 1 , size , abfd ) ! = size ) {
bfd_error = system_call_error ;
free ( area ) ;
return 0 ;
}
return area ;
}
static
struct sec * section_from_bfd_index ( abfd , index )
bfd * abfd ;
@@ -609,7 +414,7 @@ ecoff_symbol_name (abfd, idx)
bfd * abfd ;
symindex idx ;
{
return ( obj_symbols ( abfd ) + idx ) - > c . name ;
return ( obj_symbols ( abfd ) + idx ) - > symbol . name ;
}
static long
@@ -617,7 +422,7 @@ ecoff_symbol_value (abfd, idx)
bfd * abfd ;
symindex idx ;
{
return ( obj_symbols ( abfd ) + idx ) - > c . value ;
return ( obj_symbols ( abfd ) + idx ) - > symbol . value ;
}
static symclass
@@ -625,14 +430,7 @@ ecoff_classify_symbol (abfd, idx)
bfd * abfd ;
symindex idx ;
{
esymbol * sym = obj_symbols ( abfd ) + idx ;
if ( ( sym - > c . flags & BSF_FORT_COMM ) ! = 0 ) return bfd_symclass_fcommon ;
if ( ( sym - > c . flags & BSF_GLOBAL ) ! = 0 ) return bfd_symclass_global ;
if ( ( sym - > c . flags & BSF_DEBUGGING ) ! = 0 ) return bfd_symclass_debugger ;
if ( ( sym - > c . flags & BSF_UNDEFINED ) ! = 0 ) return bfd_symclass_undefined ;
return bfd_symclass_unknown ;
abort ( ) ;
}
static boolean
@@ -641,18 +439,7 @@ ecoff_symbol_hasclass (abfd, idx, class)
symindex idx ;
symclass class ;
{
esymbol * sym = obj_symbols ( abfd ) + idx ;
switch ( class ) {
case bfd_symclass_fcommon : return ( sym - > c . flags & BSF_FORT_COMM ) ! = 0 ;
case bfd_symclass_global : return ( sym - > c . flags & BSF_GLOBAL ) ! = 0 ;
case bfd_symclass_debugger : return ( sym - > c . flags & BSF_DEBUGGING ) ! = 0 ;
case bfd_symclass_undefined : return ( sym - > c . flags & BSF_UNDEFINED ) ! = 0 ;
default : return false ;
}
abort ( ) ;
}
@@ -671,198 +458,7 @@ static boolean
ecoff_slurp_symbol_table ( abfd )
bfd * abfd ;
{
struct syment * native_symbols ;
esymbol * cached_area ;
char * string_table = ( char * ) NULL ;
unsigned int string_table_size ;
unsigned int number_of_symbols = 0 ;
if ( obj_symbols ( abfd ) ) return true ;
bfd_seek ( abfd , obj_sym_filepos ( abfd ) , false ) ;
/* Read in the symbol table */
native_symbols =
( struct syment * ) buy_and_read ( abfd ,
obj_sym_filepos ( abfd ) ,
false ,
bfd_get_symcount ( abfd ) * sizeof ( struct syment ) ) ;
if ( ! native_symbols ) {
return false ;
}
/* Allocate enough room for all the symbols in cached form */
cached_area = ( esymbol * ) xmalloc ( bfd_get_symcount ( abfd ) * sizeof ( esymbol ) ) ;
{
esymbol * dst = cached_area ;
unsigned int last_native_index = bfd_get_symcount ( abfd ) ;
unsigned int this_index = 0 ;
while ( this_index < last_native_index )
{
struct syment * src = native_symbols + this_index ;
if ( src - > n_zeroes = = 0 ) {
/* This symbol has a name in the string table */
/* Which means that we'll have to read it in */
/* Fetch the size of the string table which is straight after the
* symbol table
*/
if ( string_table = = ( char * ) NULL ) {
if ( bfd_read ( & string_table_size , sizeof ( string_table_size ) , 1 , abfd ) ! =
sizeof ( string_table_size ) ) {
fatal ( " Corrupt coff format " ) ;
}
else {
/* Read the string table */
string_table =
( char * ) buy_and_read ( abfd , 0 , true ,
string_table_size - sizeof ( string_table_size ) ) ;
}
}
dst - > c . name = string_table + src - > n_offset - 4 ;
}
else {
/* Otherwise we have to buy somewhere for this name */
dst - > c . name = xmalloc ( SYMNMLEN + 1 ) ;
strncpy ( dst - > c . name , src - > n_name , SYMNMLEN ) ;
dst - > c . name [ SYMNMLEN + 1 ] = ' \0 ' ; /* Be sure to terminate it */
}
/* We use the native name field to point to the cached field */
src - > n_zeroes = ( long ) dst ;
dst - > c . section = section_from_bfd_index ( abfd , src - > n_scnum ) ;
switch ( src - > n_sclass )
{
# ifdef I960
case C_LEAFPROC :
dst - > c . value = src - > n_value - dst - > c . section - > vma ;
dst - > c . flags = BSF_EXPORT | BSF_GLOBAL ;
dst - > c . flags | = BSF_NOT_AT_END ;
break ;
# endif
case C_EXT :
if ( src - > n_scnum = = 0 ) {
if ( src - > n_value = = 0 )
{
dst - > c . flags = BSF_UNDEFINED ;
}
else {
dst - > c . flags = BSF_FORT_COMM ;
dst - > c . value = src - > n_value ;
}
}
else {
/* Base the value as an index from the base of the section */
if ( dst - > c . section = = ( asection * ) NULL )
{
dst - > c . flags = BSF_EXPORT | BSF_GLOBAL | BSF_ABSOLUTE ;
dst - > c . value = src - > n_value ;
}
else
{
dst - > c . flags = BSF_EXPORT | BSF_GLOBAL ;
dst - > c . value = src - > n_value - dst - > c . section - > vma ;
}
if ( ISFCN ( src - > n_type ) ) {
/* A function ext does not go at the end of a file*/
dst - > c . flags | = BSF_NOT_AT_END ;
}
}
break ;
case C_STAT : /* static */
case C_LABEL : /* label */
dst - > c . flags = BSF_LOCAL ;
/* Base the value as an index from the base of the section */
dst - > c . value = src - > n_value - dst - > c . section - > vma ;
break ;
case C_MOS : /* member of structure */
case C_EOS : /* end of structure */
case C_REGPARM : /* register parameter */
case C_REG : /* register variable */
case 19 : /* Intel specific REGARG FIXME */
case C_TPDEF : /* type definition */
case C_ARG :
case C_AUTO : /* automatic variable */
case C_FIELD : /* bit field */
case C_ENTAG : /* enumeration tag */
case C_MOE : /* member of enumeration */
case C_MOU : /* member of union */
case C_UNTAG : /* union tag */
dst - > c . flags = BSF_DEBUGGING ;
dst - > c . value = src - > n_value ;
break ;
case C_FILE : /* file name */
case C_STRTAG : /* structure tag */
dst - > c . flags = BSF_DEBUGGING ;
dst - > c . value = src - > n_value ;
break ;
case C_BLOCK : /* ".bb" or ".eb" */
case C_FCN : /* ".bf" or ".ef" */
dst - > c . flags = BSF_LOCAL ;
/* Base the value as an index from the base of the section */
dst - > c . value = src - > n_value - dst - > c . section - > vma ;
break ;
case C_EFCN : /* physical end of function */
case C_NULL :
case C_EXTDEF : /* external definition */
case C_ULABEL : /* undefined label */
case C_USTATIC : /* undefined static */
case C_LINE : /* line # reformatted as symbol table entry */
case C_ALIAS : /* duplicate tag */
case C_HIDDEN : /* ext symbol in dmert public lib */
default :
printf ( " SICK%d \n " , src - > n_sclass ) ;
dst - > c . flags = BSF_DEBUGGING ;
dst - > c . value = src - > n_value ;
break ;
}
if ( dst - > c . flags = = 0 ) fatal ( " OOOO dear " ) ;
dst - > native = src ;
dst - > c . udata = 0 ;
dst - > c . lineno = ( alent * ) NULL ;
this_index + = src - > n_numaux + 1 ;
dst + + ;
number_of_symbols + + ;
}
}
obj_symbols ( abfd ) = cached_area ;
obj_raw_syments ( abfd ) = native_symbols ;
bfd_get_symcount ( abfd ) = number_of_symbols ;
/* Slurp the line tables for each section too */
{
asection * p ;
p = abfd - > sections ;
while ( p ) {
ecoff_slurp_line_table ( abfd , p ) ;
p = p - > next ;
}
}
return true ;
abort ( ) ;
}
unsigned int
@@ -871,7 +467,7 @@ ecoff_get_symtab_upper_bound (abfd)
{
if ( ! ecoff_slurp_symbol_table ( abfd ) ) return 0 ;
return ( bfd_get_symcount ( abfd ) + 1 ) * ( sizeof ( e symbol * ) ) ;
return ( bfd_get_symcount ( abfd ) + 1 ) * ( sizeof ( coff_ symbol_type * ) ) ;
}
@@ -881,8 +477,8 @@ bfd *abfd;
asymbol * * alocation ;
{
unsigned int counter = 0 ;
e symbol * symbase ;
e symbol * * location = ( e symbol * * ) ( alocation ) ;
coff_ symbol_type * symbase ;
coff_ symbol_type * * location = ( coff_ symbol_type * * ) ( alocation ) ;
if ( ! ecoff_slurp_symbol_table ( abfd ) ) return 0 ;
@@ -913,68 +509,7 @@ ecoff_slurp_reloc_table (abfd, asect)
bfd * abfd ;
sec_ptr asect ;
{
struct reloc * native_relocs ;
arelent * reloc_cache ;
if ( asect - > relocation ) return true ;
if ( asect - > reloc_count = = 0 ) return true ;
if ( ! ecoff_slurp_symbol_table ( abfd ) ) return false ;
native_relocs = ( struct reloc * ) buy_and_read ( abfd ,
asect - > rel_filepos ,
false ,
sizeof ( struct reloc ) * asect - > reloc_count ) ;
reloc_cache = ( arelent * ) xmalloc ( asect - > reloc_count * sizeof ( arelent ) ) ;
{
unsigned int counter = 0 ;
arelent * cache_ptr = reloc_cache ;
struct reloc * src = native_relocs ;
while ( counter < asect - > reloc_count )
{
cache_ptr - > address = src - > r_vaddr - asect - > original_vma ;
cache_ptr - > sym = ( asymbol * ) ( src - > r_symndx +
obj_raw_syments ( abfd ) ) - > n_zeroes ;
/* The symbols that we have read in have been relocated as if their
* sections started at 0. But the offsets refering to the symbols
* in the raw data have not been modified, so we have to have
* a negative addend to compensate
*/
if ( cache_ptr - > sym - > section ) {
cache_ptr - > addend = - cache_ptr - > sym - > section - > original_vma ;
}
else {
/* If the symbol doesn't have a section then it hasn't been relocated,
* so we don't have to fix it
*/
cache_ptr - > addend = 0 ;
}
cache_ptr - > section = 0 ;
# if I960
cache_ptr - > howto = howto_table + src - > r_type ;
# endif
# if M88
if ( src - > r_type > = R_PCR16L & & src - > r_type < = R_VRT32 )
{
cache_ptr - > howto = howto_table + src - > r_type - R_PCR16L ;
}
else
{
fatal ( " unrecognised reloc type %d \n " , src - > r_type ) ;
}
# endif
cache_ptr + + ;
src + + ;
counter + + ;
}
}
free ( native_relocs ) ;
asect - > relocation = reloc_cache ;
return true ;
abort ( ) ;
}
@@ -988,8 +523,49 @@ ecoff_canonicalize_reloc (abfd, section, relptr)
return 0 ;
}
boolean
ecoff_get_section_contents ( abfd , section , location , offset , count )
bfd * abfd ;
sec_ptr section ;
PTR location ;
file_ptr offset ;
int count ;
{
if ( count ) {
if ( offset > = section - > size ) return false ;
bfd_seek ( abfd , section - > filepos + offset , SEEK_SET ) ;
return ( bfd_read ( location , 1 , count , abfd ) = = count ) ? true : false ;
}
else return true ;
}
alent *
ecoff_get_lineno ( ignore_abfd , ignore_symbol )
bfd * ignore_abfd ;
PTR ignore_symbol ;
{
return ( alent * ) NULL ;
}
# define ecoff_core_file_failing_command _bfd_dummy_core_file_failing_command
# define ecoff_core_file_failing_signal _bfd_dummy_core_file_failing_signal
# define ecoff_core_file_matches_executable_p _bfd_dummy_core_file_matches_executable_p
# define ecoff_slurp_armap bfd_false
# define ecoff_slurp_extended_name_table bfd_false
# define ecoff_truncate_arname bfd_void
# define ecoff_write_armap bfd_false
# define ecoff_print_symbol bfd_void
# define ecoff_set_arch_mach bfd_false
# define ecoff_openr_next_archived_file bfd_generic_openr_next_archived_file
# define ecoff_find_nearest_line bfd_false
# define ecoff_generic_stat_arch_elt bfd_generic_stat_arch_elt
# define ecoff_sizeof_headers bfd_0
bfd_target ecoff_little_vec =
{ " ecoff-littlemips " , /* name */
bfd_target_coff_flavour_enum ,
false , /* data byte order is little */
false , /* header byte order is little */
@@ -997,36 +573,9 @@ bfd_target ecoff_little_vec =
HAS_LINENO | HAS_DEBUG |
HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ) ,
( SEC_ALLOC | SEC_LOAD | SEC_RELOC ) , /* section flags */
0 , /* valid reloc types */
( SEC_HAS_CONTENTS | SEC_ ALLOC | SEC_LOAD | SEC_RELOC ) , /* section flags */
' / ' , /* ar_pad_char */
15 , /* ar_max_namelen */
ecoff_close_and_cleanup , /* _close_and_cleanup */
ecoff_set_section_contents , /* bfd_set_section_contents */
ecoff_new_section_hook , /* new_section_hook */
_bfd_dummy_core_file_failing_command , /* _core_file_failing_command */
_bfd_dummy_core_file_failing_signal , /* _core_file_failing_signal */
_bfd_dummy_core_file_matches_executable_p , /* _core_file_matches_ex...p */
bfd_slurp_coff_armap , /* bfd_slurp_armap */
_bfd_slurp_extended_name_table , /* bfd_slurp_extended_name_table*/
bfd_dont_truncate_arname , /* bfd_truncate_arname */
ecoff_get_symtab_upper_bound , /* get_symtab_upper_bound */
ecoff_get_symtab , /* canonicalize_symtab */
( void ( * ) ( ) ) bfd_false , /* bfd_reclaim_symbol_table */
ecoff_get_reloc_upper_bound , /* get_reloc_upper_bound */
ecoff_canonicalize_reloc , /* bfd_canonicalize_reloc */
( void ( * ) ( ) ) bfd_false , /* bfd_reclaim_reloc */
ecoff_get_symcount_upper_bound , /* bfd_get_symcount_upper_bound */
ecoff_get_first_symbol , /* bfd_get_first_symbol */
ecoff_get_next_symbol , /* bfd_get_next_symbol */
ecoff_classify_symbol , /* bfd_classify_symbol */
ecoff_symbol_hasclass , /* bfd_symbol_hasclass */
ecoff_symbol_name , /* bfd_symbol_name */
ecoff_symbol_value , /* bfd_symbol_value */
_do_getllong , _do_putllong , _do_getlshort , _do_putlshort , /* data */
_do_getllong , _do_putllong , _do_getlshort , _do_putlshort , /* hdrs */
@@ -1034,13 +583,12 @@ bfd_target ecoff_little_vec =
bfd_generic_archive_p , _bfd_dummy_target } ,
{ bfd_false , ecoff_mkobject , bfd_false , /* bfd_set_format */
bfd_false } ,
ecoff_make_empty_symbol ,
} ;
JUMP_TABLE ( ecoff )
} ;
bfd_target ecoff_big_vec =
{ " ecoff-bigmips " , /* name */
bfd_target_coff_flavour_enum ,
true , /* data byte order is big */
true , /* header byte order is big */
@@ -1048,36 +596,9 @@ bfd_target ecoff_big_vec =
HAS_LINENO | HAS_DEBUG |
HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ) ,
( SEC_ALLOC | SEC_LOAD | SEC_RELOC ) , /* section flags */
0 , /* valid reloc types */
' / ' , /* ar_pad_char */
15 , /* ar_max_namelen */
ecoff_close_and_cleanup , /* _close_and_cleanup */
ecoff_set_section_contents , /* bfd_set_section_contents */
ecoff_new_section_hook , /* new_section_hook */
_bfd_dummy_core_file_failing_command , /* _core_file_failing_command */
_bfd_dummy_core_file_failing_signal , /* _core_file_failing_signal */
_bfd_dummy_core_file_matches_executable_p , /* _core_file_matches_ex...p */
bfd_slurp_coff_armap , /* bfd_slurp_armap */
_bfd_slurp_extended_name_table , /* bfd_slurp_extended_name_table*/
bfd_dont_truncate_arname , /* bfd_truncate_arname */
ecoff_get_symtab_upper_bound , /* get_symtab_upper_bound */
ecoff_get_symtab , /* canonicalize_symtab */
( void ( * ) ( ) ) bfd_false , /* bfd_reclaim_symbol_table */
ecoff_get_reloc_upper_bound , /* get_reloc_upper_bound */
ecoff_canonicalize_reloc , /* bfd_canonicalize_reloc */
( void ( * ) ( ) ) bfd_false , /* bfd_reclaim_reloc */
ecoff_get_symcount_upper_bound , /* bfd_get_symcount_upper_bound */
ecoff_get_first_symbol , /* bfd_get_first_symbol */
ecoff_get_next_symbol , /* bfd_get_next_symbol */
ecoff_classify_symbol , /* bfd_classify_symbol */
ecoff_symbol_hasclass , /* bfd_symbol_hasclass */
ecoff_symbol_name , /* bfd_symbol_name */
ecoff_symbol_value , /* bfd_symbol_value */
( SEC_HAS_CONTENTS | SEC_ ALLOC | SEC_LOAD | SEC_RELOC ) , /* section flags */
' ' , /* ar_pad_char */
16 , /* ar_max_namelen */
_do_getblong , _do_putblong , _do_getbshort , _do_putbshort , /* data */
_do_getblong , _do_putblong , _do_getbshort , _do_putbshort , /* hdrs */
@@ -1085,9 +606,5 @@ bfd_target ecoff_big_vec =
bfd_generic_archive_p , _bfd_dummy_target } ,
{ bfd_false , ecoff_mkobject , bfd_false , /* bfd_set_format */
bfd_false } ,
ecoff_make_empty_symbol ,
} ;
# endif /* ECOFF_BFD */
JUMP_TABLE ( ecoff )
} ;