RS/6000 support, by Metin G. Ozisik, Mimi Phûông-Thåo Võ, and John Gilmore.

This commit is contained in:
John Gilmore 1991-10-25 07:06:02 +00:00
parent c8c0a2bd59
commit cbdc790909
10 changed files with 621 additions and 420 deletions

View File

@ -1,3 +1,31 @@
Thu Oct 24 22:40:07 1991 John Gilmore (gnu at cygnus.com)
RS/6000 support, by Metin G. Ozisik, Mimi Phûông-Thåo Võ, and
John Gilmore.
* Makefile.in: Add cpu-rs6000.c and rs6000coff.c.
* configure.in: Add rs6000 case.
* targets.c: Add rs6000 vector.
* archures.c: Add rs6000, fix comment on romp.
* bfd-in.h (enum bfd_error): Add no_debug_section error.
* libcoff-in.h (struct coff_tdata): Remove unused string_table.
* bfd.c (bfd_errmsgs): Add no_debug_section error message.
* section.c (bfd_make_section): Return NULL on attempt to create
a section twice.
* coffcode.h (bfd_swap_reloc_in): Handle r_type and r_size.
(bfd_swap_aouthdr_in): Handle lots more members.
(make_a_section_from_file): If section has already been seen,
just return false rather than overwriting it.
(coff_real_object_p): Understand incoming magic numbers.
(coff_set_flags): Understand outgoing magic numbers.
(coff_compute_section_file_positions): outgoing aouthdr magic #.
(build_debug_section): Add fn for reading debug string section.
(get_normalized_symtab): Handle symbol names in debug string section.
Remove unused obj_string_table.
(coff_slurp_symbol_table): Handle rs6000-specific storage classes.
* aoutx.h (translate_from_native_sym_flags, N_SET*): Check for
existing section before making one.
Thu Oct 24 02:03:24 1991 Fred Fish (fnf at cygnus.com)
* elf.c: Add partial support for ELF format corefiles. Still needs

View File

@ -43,12 +43,13 @@ CFLAGS = -g $(HDEFINES) $(TDEFINES) $(CSEARCH) $(CSWITCHES) # -DINTEL960VERSION
BFD_LIBS = libbfd.o opncls.o bfd.o archive.o targets.o cache.o \
archures.o core.o section.o format.o syms.o reloc.o init.o
BFD_MACHINES=cpu-h8300.o cpu-i960.o cpu-sparc.o cpu-m68k.o cpu-m88k.o \
cpu-vax.o cpu-mips.o cpu-a29k.o cpu-i386.o
BFD_MACHINES = cpu-h8300.o cpu-i960.o cpu-sparc.o cpu-m68k.o cpu-m88k.o \
cpu-vax.o cpu-mips.o cpu-a29k.o cpu-i386.o cpu-rs6000.o
BFD_BACKENDS = oasys.o ieee.o srec.o \
aout64.o aout32.o demo64.o sunos.o newsos3.o i386aout.o bout.o \
icoff.o amdcoff.o m68kcoff.o i386coff.o m88k-bcs.o ecoff.o elf.o
icoff.o amdcoff.o m68kcoff.o i386coff.o m88k-bcs.o ecoff.o elf.o \
rs6000coff.o
OPTIONAL_BACKENDS = trad-core.o
@ -58,11 +59,11 @@ BFD_H=$(INCDIR)/bfd.h
# C source files that correspond to .o's.
CFILES = libbfd.c opncls.c bfd.c archive.c targets.c cache.c archures.c \
i386coff.c aout64.c aout32.c sunos.c demo64.c icoff.c srec.c \
oasys.c ieee.c m68kcoff.c amdcoff.c \
oasys.c ieee.c m68kcoff.c amdcoff.c rs6000coff.c \
format.c section.c core.c syms.c reloc.c init.c \
m88k-bcs.c ecoff.c trad-core.c newsos3.c i386aout.c bout.c elf.c \
cpu-h8300.c cpu-i960.c cpu-sparc.c cpu-m68k.c cpu-m88k.c \
cpu-vax.c cpu-mips.c cpu-a29k.c cpu-i386.o
cpu-vax.c cpu-mips.c cpu-a29k.c cpu-i386.c cpu-rs6000.c
STAGESTUFF = $(TARGETLIB) $(OFILES)
@ -125,6 +126,9 @@ $(BFD_MACHINES): libbfd.h $(BFD_H) $(RECONFIG)
$(BFD_BACKENDS): libbfd.h $(BFD_H) $(RECONFIG)
$(OPTIONAL_BACKENDS): libbfd.h $(BFD_H) $(RECONFIG)
# Get around a Sun Make bug in SunOS 4.1.1 with VPATH
cpu-i386.o:cpu-i386.c
saber:
#suppress 65 on bfd_map_over_sections
#suppress 66 on bfd_map_over_sections
@ -262,6 +266,8 @@ m68kcoff.o : m68kcoff.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h libbfd.h \
$(INCDIR)/m68kcoff.h $(INCDIR)/internalcoff.h libcoff.h coffcode.h
amdcoff.o : amdcoff.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h libbfd.h \
$(INCDIR)/amdcoff.h $(INCDIR)/internalcoff.h libcoff.h coffcode.h
rs6000coff.o: rs6000coff.c $(INCDIR)/bfd.h $(INCDIR)/obstack.h libbfd.h \
$(INCDIR)/rs6000coff.h $(INCDIR)/internalcoff.h libcoff.h coffcode.h
format.o : format.c $(INCDIR)/bfd.h \
$(INCDIR)/obstack.h libbfd.h
section.o : section.c $(INCDIR)/bfd.h \

View File

@ -700,7 +700,10 @@ bfd *abfd)
asection *section ;
arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, sizeof(arelent_chain));
strcpy(copy, cache_ptr->symbol.name);
section = bfd_get_section_by_name (abfd, copy);
if (!section)
section = bfd_make_section(abfd,copy);
switch ( (cache_ptr->type & N_TYPE) ) {
case N_SETA:
section->flags = SEC_CONSTRUCTOR;
@ -1700,9 +1703,9 @@ DEFUN(NAME(aout,find_nearest_line),(abfd,
}
int
DEFUN(NAME(aout,sizeof_headers),(ignore_abfd, execable),
bfd *ignore_abfd AND
DEFUN(NAME(aout,sizeof_headers),(abfd, execable),
bfd *abfd AND
boolean execable)
{
return EXEC_BYTES_SIZE;
return adata(abfd)->exec_bytes_size;
}

View File

@ -22,11 +22,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/*doc*
@section Architectures
BFD's idea of an architecture is implimented in @code{archures.c}. BFD
keeps one atoms in a BFD describing the architecture of the data
attached to the BFD; a pointer to a @code{bfd_arch_info_struct}.
keeps one atom in a BFD describing the architecture of the data
attached to the BFD; a pointer to a @code{bfd_arch_info_type}.
Pointers to structures can be requested independently of a bfd so that
an archictectures information can be interrogated without access to an
an architecture's information can be interrogated without access to an
open bfd.
The arch information is provided by each architecture package. The
@ -82,12 +82,13 @@ enum bfd_architecture
bfd_arch_ns32k, {* National Semiconductor 32xxx *}
bfd_arch_tahoe, {* CCI/Harris Tahoe *}
bfd_arch_i860, {* Intel 860 *}
bfd_arch_romp, {* IBM ROMP RS/6000 *}
bfd_arch_romp, {* IBM ROMP PC/RT *}
bfd_arch_alliant, {* Alliant *}
bfd_arch_convex, {* Convex *}
bfd_arch_m88k, {* Motorola 88xxx *}
bfd_arch_pyramid, {* Pyramid Technology *}
bfd_arch_h8300, {* Hitachi H8/300 *}
bfd_arch_rs6000, {* IBM RS/6000 *}
bfd_arch_last
};
*-
@ -100,16 +101,16 @@ stuff
/* $Id$ */
#include <sysdep.h>
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
/*proto* bfd_arch_info_struct
/*proto* bfd_arch_info
This structure contains information on architectures.
*+
typedef int bfd_reloc_code_enum_type;
typedef int bfd_reloc_code_type;
typedef struct bfd_arch_info_struct
typedef struct bfd_arch_info
{
int bits_per_word;
int bits_per_address;
@ -120,52 +121,25 @@ typedef struct bfd_arch_info_struct
CONST char *printable_name;
{* true if this is the default machine for the architecture *}
boolean the_default;
CONST struct bfd_arch_info_struct * EXFUN((*compatible),(CONST struct bfd_arch_info_struct *a,
CONST struct bfd_arch_info_struct *b));
CONST struct bfd_arch_info * EXFUN((*compatible),(CONST struct bfd_arch_info *a,
CONST struct bfd_arch_info *b));
boolean EXFUN((*scan),(CONST struct bfd_arch_info_struct *,CONST char *));
boolean EXFUN((*scan),(CONST struct bfd_arch_info *,CONST char *));
unsigned int EXFUN((*disassemble),(bfd_vma addr, CONST char *data,
PTR stream));
CONST struct reloc_howto_struct *EXFUN((*reloc_type_lookup), (bfd_reloc_code_enum_type code));
CONST struct reloc_howto_struct *EXFUN((*reloc_type_lookup), (CONST struct
bfd_arch_info *,
bfd_reloc_code_type code));
struct bfd_arch_info_struct *next;
struct bfd_arch_info *next;
} bfd_arch_info_struct_type;
} bfd_arch_info_type;
*-
*/
bfd_arch_info_struct_type *bfd_arch_info_list;
/*proto* bfd_printable_arch_mach
Return a printable string representing the architecture and machine
type.
NB. The use of this routine is depreciated.
*; PROTO(CONST char *,bfd_printable_arch_mach,
(enum bfd_architecture arch, unsigned long machine));
*/
CONST char *
DEFUN(bfd_printable_arch_mach,(arch, machine),
enum bfd_architecture arch AND
unsigned long machine)
{
bfd_arch_info_struct_type *ap;
bfd_check_init();
for (ap = bfd_arch_info_list;
ap != (bfd_arch_info_struct_type *)NULL;
ap = ap->next) {
if (ap->arch == arch &&
((ap->mach == machine) || (ap->the_default && machine == 0))) {
return ap->printable_name;
}
}
return "UNKNOWN!";
}
bfd_arch_info_type *bfd_arch_info_list;
/*proto* bfd_printable_name
@ -193,26 +167,24 @@ supports any cpu which could be described with the name provided. The
routine returns a pointer to an arch_info structure if a machine is
found, otherwise NULL.
*; bfd_arch_info_struct_type *EXFUN(bfd_scan_arch,(CONST char *));
*; bfd_arch_info_type *EXFUN(bfd_scan_arch,(CONST char *));
*/
bfd_arch_info_struct_type *
bfd_arch_info_type *
DEFUN(bfd_scan_arch,(string),
CONST char *string)
{
struct bfd_arch_info_struct *ap;
struct bfd_arch_info *ap;
/* Look through all the installed architectures */
for (ap = bfd_arch_info_list;
ap != (bfd_arch_info_struct_type *)NULL;
ap != (bfd_arch_info_type *)NULL;
ap = ap->next) {
/* Don't bother with anything if the first chars don't match */
if (ap->arch_name[0] != string[0])
continue;
if (ap->scan(ap, string))
return ap;
}
return (bfd_arch_info_struct_type *)NULL;
return (bfd_arch_info_type *)NULL;
}
@ -224,12 +196,12 @@ denominator between the two architectures and machine types implied by
the BFDs and returns a pointer to an arch_info structure describing
the compatible machine.
*; CONST bfd_arch_info_struct_type *EXFUN(bfd_arch_get_compatible,
*; CONST bfd_arch_info_type *EXFUN(bfd_arch_get_compatible,
(CONST bfd *abfd,
CONST bfd *bbfd));
*/
CONST bfd_arch_info_struct_type *
CONST bfd_arch_info_type *
DEFUN(bfd_arch_get_compatible,(abfd, bbfd),
CONST bfd *abfd AND
CONST bfd *bbfd)
@ -244,11 +216,11 @@ CONST bfd *bbfd)
What bfds are seeded with
*+
extern bfd_arch_info_struct_type bfd_default_arch_struct;
extern bfd_arch_info_type bfd_default_arch_struct;
*-
*/
bfd_arch_info_struct_type bfd_default_arch_struct =
bfd_arch_info_type bfd_default_arch_struct =
{
32,32,8,bfd_arch_unknown,0,"unknown","unknown",true,
bfd_default_compatible, bfd_default_scan,
@ -257,13 +229,13 @@ bfd_arch_info_struct_type bfd_default_arch_struct =
/*proto* bfd_set_arch_info
*; void EXFUN(bfd_set_arch_info,(bfd *, bfd_arch_info_struct_type *));
*; void EXFUN(bfd_set_arch_info,(bfd *, bfd_arch_info_type *));
*/
void DEFUN(bfd_set_arch_info,(abfd, arg),
bfd *abfd AND
bfd_arch_info_struct_type *arg)
bfd_arch_info_type *arg)
{
abfd->arch_info = arg;
}
@ -284,15 +256,15 @@ boolean DEFUN(bfd_default_set_arch_mach,(abfd, arch, mach),
enum bfd_architecture arch AND
unsigned long mach)
{
static struct bfd_arch_info_struct *old_ptr = &bfd_default_arch_struct;
static struct bfd_arch_info *old_ptr = &bfd_default_arch_struct;
boolean found = false;
/* run through the table to find the one we want, we keep a little
cache to speed things up */
if (old_ptr == 0 || arch != old_ptr->arch || mach != old_ptr->mach) {
bfd_arch_info_struct_type *ptr;
old_ptr = (bfd_arch_info_struct_type *)NULL;
bfd_arch_info_type *ptr;
old_ptr = (bfd_arch_info_type *)NULL;
for (ptr = bfd_arch_info_list;
ptr != (bfd_arch_info_struct_type *)NULL;
ptr != (bfd_arch_info_type *)NULL;
ptr= ptr->next) {
if (ptr->arch == arch &&
((ptr->mach == mach) || (ptr->the_default && mach == 0))) {
@ -385,6 +357,7 @@ extern void EXFUN(bfd_vax_arch,(void));
extern void EXFUN(bfd_a29k_arch,(void));
extern void EXFUN(bfd_mips_arch,(void));
extern void EXFUN(bfd_i386_arch,(void));
extern void EXFUN(bfd_rs6000_arch,(void));
@ -402,6 +375,7 @@ static void EXFUN((*archures_init_table[]),()) =
bfd_i960_arch,
bfd_m68k_arch,
bfd_vax_arch,
bfd_rs6000_arch,
#endif
0
};
@ -434,12 +408,12 @@ DEFUN_VOID(bfd_arch_init)
Link the provided arch info structure into the list
*; void EXFUN(bfd_arch_linkin,(bfd_arch_info_struct_type *));
*; void EXFUN(bfd_arch_linkin,(bfd_arch_info_type *));
*/
void DEFUN(bfd_arch_linkin,(ptr),
bfd_arch_info_struct_type *ptr)
bfd_arch_info_type *ptr)
{
ptr->next = bfd_arch_info_list;
bfd_arch_info_list = ptr;
@ -450,17 +424,17 @@ void DEFUN(bfd_arch_linkin,(ptr),
The default function for testing for compatibility
*; CONST bfd_arch_info_struct_type *EXFUN(bfd_default_compatible,
(CONST bfd_arch_info_struct_type *a,
CONST bfd_arch_info_struct_type *b));
*; CONST bfd_arch_info_type *EXFUN(bfd_default_compatible,
(CONST bfd_arch_info_type *a,
CONST bfd_arch_info_type *b));
*/
CONST bfd_arch_info_struct_type *
CONST bfd_arch_info_type *
DEFUN(bfd_default_compatible,(a,b),
CONST bfd_arch_info_struct_type *a AND
CONST bfd_arch_info_struct_type *b)
CONST bfd_arch_info_type *a AND
CONST bfd_arch_info_type *b)
{
if(a->arch != b->arch) return (bfd_arch_info_struct_type *)NULL;
if(a->arch != b->arch) return NULL;
if (a->mach > b->mach) {
return a;
@ -475,13 +449,13 @@ DEFUN(bfd_default_compatible,(a,b),
The default function for working out whether this is an architecture
hit and a machine hit
*; boolean EXFUN(bfd_default_scan,(CONST struct bfd_arch_info_struct *, CONST char *));
*; boolean EXFUN(bfd_default_scan,(CONST struct bfd_arch_info *, CONST char *));
*/
boolean
DEFUN(bfd_default_scan,(info, string),
CONST struct bfd_arch_info_struct *info AND
CONST struct bfd_arch_info *info AND
CONST char *string)
{
CONST char *ptr_src;
@ -554,6 +528,10 @@ CONST char *string)
arch = bfd_arch_i860;
break;
case 6000:
arch = bfd_arch_rs6000;
break;
default:
return false;
}
@ -571,13 +549,65 @@ CONST char *string)
/*proto* bfd_get_arch_info
*; bfd_arch_info_struct_type * EXFUN(bfd_get_arch_info,(bfd *));
*; bfd_arch_info_type * EXFUN(bfd_get_arch_info,(bfd *));
*/
bfd_arch_info_struct_type *
bfd_arch_info_type *
DEFUN(bfd_get_arch_info,(abfd),
bfd *abfd)
{
return abfd->arch_info;
}
/*proto* bfd_lookup_arch
*; bfd_arch_info_type * EXFUN(bfd_lookup_arch,(enum
bfd_architecture arch,long machine));
Look for the architecure info struct which matches the arguments
given. A machine of 0 will match the machine/architecture structure which
marks itself as the default.
*/
bfd_arch_info_type *
DEFUN(bfd_lookup_arch,(arch, machine),
enum bfd_architecture arch AND
long machine)
{
bfd_arch_info_type *ap;
bfd_check_init();
for (ap = bfd_arch_info_list;
ap != (bfd_arch_info_type *)NULL;
ap = ap->next) {
if (ap->arch == arch &&
((ap->mach == machine) || (ap->the_default && machine == 0))) {
return ap;
}
}
return (bfd_arch_info_type *)NULL;
}
/*proto* bfd_printable_arch_mach
Return a printable string representing the architecture and machine
type.
NB. The use of this routine is depreciated.
*; PROTO(CONST char *,bfd_printable_arch_mach,
(enum bfd_architecture arch, unsigned long machine));
*/
CONST char *
DEFUN(bfd_printable_arch_mach,(arch, machine),
enum bfd_architecture arch AND
unsigned long machine)
{
bfd_arch_info_type *ap = bfd_lookup_arch(arch, machine);
if(ap) return ap->printable_name;
return "UNKNOWN!";
}

View File

@ -205,6 +205,7 @@ typedef enum bfd_error {
symbol_not_found, file_not_recognized,
file_ambiguously_recognized, no_contents,
bfd_error_nonrepresentable_section,
no_debug_section,
invalid_error_code} bfd_ec;
extern bfd_ec bfd_error;
@ -220,10 +221,10 @@ PROTO (void, bfd_perror, (CONST char *message));
typedef enum bfd_print_symbol
{
bfd_print_symbol_name_enum,
bfd_print_symbol_type_enum,
bfd_print_symbol_all_enum
} bfd_print_symbol_enum_type;
bfd_print_symbol_name,
bfd_print_symbol_more,
bfd_print_symbol_all
} bfd_print_symbol_type;
@ -269,7 +270,14 @@ CAT(NAME,_bfd_debug_info_start),\
CAT(NAME,_bfd_debug_info_end),\
CAT(NAME,_bfd_debug_info_accumulate)
#define COFF_SWAP_TABLE coff_swap_aux_in, coff_swap_sym_in, coff_swap_lineno_in,
#define COFF_SWAP_TABLE \
coff_swap_aux_in, coff_swap_sym_in, coff_swap_lineno_in, \
coff_swap_aux_out, coff_swap_sym_out, \
coff_swap_lineno_out, coff_swap_reloc_out, \
coff_swap_filehdr_out, coff_swap_aouthdr_out, \
coff_swap_scnhdr_out
/* User program access to BFD facilities */

View File

@ -162,6 +162,7 @@ $};
#include "sysdep.h"
#include "libbfd.h"
#undef strerror
extern char *strerror();
@ -196,6 +197,7 @@ char *bfd_errmsgs[] = { "No error",
"File format is ambiguous",
"Section has no contents",
"Nonrepresentable section on output",
"Symbol needs debug section which does not exist",
"#<Invalid error code>"
};
@ -418,6 +420,27 @@ bfd_get_mtime (abfd)
#define bfd_set_arch_mach(abfd, arch, mach)\
BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach))
#define bfd_coff_swap_reloc_out(abfd, i, o) \
BFD_SEND (abfd, _bfd_coff_swap_reloc_out, (abfd, i, o))
#define bfd_coff_swap_lineno_out(abfd, i, o) \
BFD_SEND (abfd, _bfd_coff_swap_lineno_out, (abfd, i, o))
#define bfd_coff_swap_aux_out(abfd, i, t,c,o) \
BFD_SEND (abfd, _bfd_coff_swap_aux_out, (abfd, i,t,c, o))
#define bfd_coff_swap_sym_out(abfd, i,o) \
BFD_SEND (abfd, _bfd_coff_swap_sym_out, (abfd, i, o))
#define bfd_coff_swap_scnhdr_out(abfd, i,o) \
BFD_SEND (abfd, _bfd_coff_swap_scnhdr_out, (abfd, i, o))
#define bfd_coff_swap_filehdr_out(abfd, i,o) \
BFD_SEND (abfd, _bfd_coff_swap_filehdr_out, (abfd, i, o))
#define bfd_coff_swap_aouthdr_out(abfd, i,o) \
BFD_SEND (abfd, _bfd_coff_swap_aouthdr_out, (abfd, i, o))
*-
*/

View File

@ -105,7 +105,7 @@ avenue to disaster disappear.
The simple canonical form for symbols used by BFD is not rich enough
to keep all the information available in a coff symbol table. The back
end gets around this by keeping the original symbol table around,
"behind the sceens".
"behind the scenes".
When a symbol table is requested (through a call to
@code{bfd_canonicalize_symtab}, a request gets through to
@ -381,7 +381,14 @@ DEFUN(bfd_swap_reloc_in,(abfd, reloc_src, reloc_dst),
{
reloc_dst->r_vaddr = bfd_h_get_32(abfd, (bfd_byte *)reloc_src->r_vaddr);
reloc_dst->r_symndx = bfd_h_get_32(abfd, (bfd_byte *) reloc_src->r_symndx);
#ifdef RS6000COFF_C
reloc_dst->r_type = bfd_h_get_8(abfd, reloc_src->r_type);
reloc_dst->r_size = bfd_h_get_8(abfd, reloc_src->r_size);
#else
reloc_dst->r_type = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_type);
#endif
#if M88
reloc_dst->r_offset = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_offset);
#endif
@ -584,7 +591,7 @@ DEFUN(coff_swap_aux_out,(abfd, inp, type, class, extp),
switch (class) {
case C_FILE:
if (in->x_file.x_fname[0] == 0) {
PUTWORD(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes );
PUTWORD(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes);
PUTWORD(abfd,
in->x_file.x_n.x_offset,
(bfd_byte *) ext->x_file.x_n.x_offset);
@ -705,6 +712,20 @@ DEFUN(bfd_swap_aouthdr_in,(abfd, aouthdr_ext1, aouthdr_int1),
#ifdef I960
aouthdr_int->tagentries = bfd_h_get_32(abfd, (bfd_byte *) aouthdr_ext->tagentries);
#endif
#ifdef RS6000COFF_C
aouthdr_int->o_toc = bfd_h_get_32(abfd, aouthdr_ext->o_toc);
aouthdr_int->o_snentry = bfd_h_get_16(abfd, aouthdr_ext->o_snentry);
aouthdr_int->o_sntext = bfd_h_get_16(abfd, aouthdr_ext->o_sntext);
aouthdr_int->o_sndata = bfd_h_get_16(abfd, aouthdr_ext->o_sndata);
aouthdr_int->o_sntoc = bfd_h_get_16(abfd, aouthdr_ext->o_sntoc);
aouthdr_int->o_snloader = bfd_h_get_16(abfd, aouthdr_ext->o_snloader);
aouthdr_int->o_snbss = bfd_h_get_16(abfd, aouthdr_ext->o_snbss);
aouthdr_int->o_algntext = bfd_h_get_16(abfd, aouthdr_ext->o_algntext);
aouthdr_int->o_algndata = bfd_h_get_16(abfd, aouthdr_ext->o_algndata);
aouthdr_int->o_modtype = bfd_h_get_16(abfd, aouthdr_ext->o_modtype);
aouthdr_int->o_maxstack = bfd_h_get_32(abfd, aouthdr_ext->o_maxstack);
#endif
}
static unsigned int
@ -821,6 +842,8 @@ DEFUN(make_a_section_from_file,(abfd, hdr),
name[sizeof (hdr->s_name)] = 0;
return_section = bfd_make_section(abfd, name);
if (return_section == NULL)
return false;
}
/* s_paddr is presumed to be = to s_vaddr */
@ -988,12 +1011,21 @@ machine = 0;
case F_I960KA:
machine = bfd_mach_i960_ka_sa;
break;
}
break;
#endif
#endif
#ifdef U802ROMAGIC
case U802ROMAGIC:
case U802WRMAGIC:
case U802TOCMAGIC:
arch = bfd_arch_rs6000;
machine = 6000;
break;
#endif
default: /* Unreadable input file type */
arch = bfd_arch_obscure;
break;
@ -1255,25 +1287,22 @@ DEFUN(coff_mangle_symbols,(bfd_ptr),
{
unsigned int symbol_count = bfd_get_symcount(bfd_ptr);
asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
unsigned int symbol_index;
for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
{
coff_symbol_type *coff_symbol_ptr = coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
if (coff_symbol_ptr && coff_symbol_ptr->native ) {
coff_symbol_type *coff_symbol_ptr =
coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
if (coff_symbol_ptr && coff_symbol_ptr->native) {
int i;
combined_entry_type *s = coff_symbol_ptr->native;
for (i = 0; i < s->u.syment.n_numaux ; i++) {
combined_entry_type *a = s + i + 1;
if (a->fix_tag) {
a->u.auxent.x_sym.x_tagndx.l = a->u.auxent.x_sym.x_tagndx.p->offset;
a->u.auxent.x_sym.x_tagndx.l =
a->u.auxent.x_sym.x_tagndx.p->offset;
}
if (a->fix_end) {
a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l =
@ -1340,14 +1369,13 @@ DEFUN(coff_mangle_symbols,(bfd_ptr),
coff_symbol_ptr->symbol.section->output_section->vma;
}
/* If this symbol ties up something then do it */
if (syment->n_sclass == C_FILE && last_file != (struct internal_syment *)NULL)
{
last_file->n_value = native_index;
}
else if ((syment->n_sclass == C_EXT
else if ((syment->n_sclass == C_EXT /* FIXME - may need C_HIDEXT */
|| syment->n_sclass == C_STAT
#ifdef C_LEAFEXT
|| syment->n_sclass == C_LEAFEXT
@ -1359,7 +1387,6 @@ DEFUN(coff_mangle_symbols,(bfd_ptr),
union internal_auxent *auxent = (union internal_auxent *)(last_fcn+1);
auxent->x_sym.x_fcnary.x_fcn.x_endndx.l = native_index;
last_fcn = (struct internal_syment *)NULL;
}
else if (syment->n_sclass == C_EOS && last_tagndx != (struct internal_syment*)NULL)
{
@ -1432,8 +1459,6 @@ DEFUN(coff_mangle_symbols,(bfd_ptr),
bfd *bfd_ptr = coff_symbol_ptr->symbol.the_bfd;
struct internal_syment *base = obj_raw_syments(bfd_ptr);
/* auxent->x_sym.x_tagndx = base[auxent->x_sym.x_tagndx]._n._n_n._n_offset;*/
}
}
if (ISFCN(syment->n_type)) {
@ -1640,7 +1665,6 @@ unsigned int written)
}
symbol->symbol.section->output_section->moving_line_filepos +=
count * LINESZ;
}
return coff_write_symbol(abfd, &( symbol->symbol), native,written);
}
@ -1669,8 +1693,6 @@ DEFUN(coff_write_symbols,(abfd),
asymbol *symbol = *p;
coff_symbol_type *c_symbol = coff_symbol_from(abfd, symbol);
if (c_symbol == (coff_symbol_type *) NULL ||
c_symbol->native == (combined_entry_type *)NULL)
{
@ -1694,7 +1716,9 @@ DEFUN(coff_write_symbols,(abfd),
bfd_h_put_32(abfd, size, buffer);
bfd_write((PTR) buffer, 1, sizeof(buffer), abfd);
for (p = abfd->outsymbols, i = 0; i < limit; i++, p++)
for (p = abfd->outsymbols, i = 0;
i < limit;
i++, p++)
{
asymbol *q = *p;
size_t name_length = strlen(q->name);
@ -1952,6 +1976,12 @@ DEFUN(coff_set_flags,(abfd, magicp, flagsp),
break;
#endif
#ifdef U802TOCMAGIC
case bfd_arch_rs6000:
*magicp = U802TOCMAGIC;
break;
#endif
default: /* Unknown architecture */
/* return false; -- fall through to "return false" below, to avoid
"statement never reached" errors on the one below. */
@ -2142,7 +2172,6 @@ DEFUN(coff_write_object_contents,(abfd),
if (current->size - pad == 0 ||
(current->flags & SEC_LOAD) == 0) {
section.s_scnptr = 0;
}
else {
section.s_scnptr = current->filepos;
@ -2268,6 +2297,13 @@ DEFUN(coff_write_object_contents,(abfd),
/* Never was anything here for the 68k */
#endif /* M88 */
#if RS6000COFF_C
#define __A_MAGIC_SET__
internal_a.magic = (abfd->flags & D_PAGED)? RS6K_AOUTHDR_ZMAGIC:
(abfd->flags & WP_TEXT)? RS6K_AOUTHDR_NMAGIC:
RS6K_AOUTHDR_OMAGIC;
#endif
#ifndef __A_MAGIC_SET__
# include "Your aouthdr magic number is not being set!"
#else
@ -2425,11 +2461,9 @@ bfd *abfd)
char string_table_size_buffer[4];
unsigned int string_table_size;
char *string_table;
/*
At this point we should be "seek"'d to the end of the
symbols === the symbol table size.
*/
/* At this point we should be "seek"'d to the end of the
symbols === the symbol table size. */
if (bfd_read((char *) string_table_size_buffer,
sizeof(string_table_size_buffer),
1, abfd) != sizeof(string_table_size)) {
@ -2450,6 +2484,46 @@ bfd *abfd)
return string_table;
}
/* Allocate space for the ".debug" section, and read it.
We did not read the debug section until now, because
we didn't want to go to the trouble until someone needed it. */
static char *
DEFUN(build_debug_section,(abfd),
bfd *abfd)
{
char *debug_section;
long position;
asection *sect = bfd_get_section_by_name (abfd, ".debug");
if (!sect) {
bfd_error = no_debug_section;
return NULL;
}
debug_section = (PTR) bfd_alloc (abfd, bfd_section_size (abfd, sect));
if (debug_section == NULL) {
bfd_error = no_memory;
return NULL;
}
/* Seek to the beginning of the `.debug' section and read it.
Save the current position first; it is needed by our caller.
Then read debug section and reset the file pointer. */
position = bfd_tell (abfd);
bfd_seek (abfd, sect->filepos, SEEK_SET);
if (bfd_read (debug_section, bfd_section_size (abfd, sect), 1, abfd)
!= bfd_section_size (abfd, sect)) {
bfd_error = system_call_error;
return NULL;
}
bfd_seek (abfd, position, SEEK_SET);
return debug_section;
}
/* Return a pointer to a malloc'd copy of 'name'. 'name' may not be
\0-terminated, but will not exceed 'maxlen' characters. The copy *will*
be \0-terminated. */
@ -2478,19 +2552,19 @@ DEFUN(copy_name,(abfd, name, maxlen),
}
/*
read a symbol table into freshly mallocated memory, swap it, and knit the
symbol names into a normalized form. By normalized here I mean that all
symbols have an n_offset pointer that points to a NULL terminated string.
Oh, and the first symbol MUST be a C_FILE. If there wasn't one there
before, put one there.
*/
/* Read a symbol table into freshly bfd_allocated memory, swap it, and
knit the symbol names into a normalized form. By normalized here I
mean that all symbols have an n_offset pointer that points to a null-
terminated string. */
#ifndef SYMNAME_IN_DEBUG
#define SYMNAME_IN_DEBUG(x) 0
#endif
static combined_entry_type *
DEFUN(get_normalized_symtab,(abfd),
bfd *abfd)
{
combined_entry_type *internal;
combined_entry_type *internal_ptr;
combined_entry_type *internal_end;
@ -2498,9 +2572,9 @@ bfd *abfd)
SYMENT *raw_src;
SYMENT *raw_end;
char *string_table = NULL;
char *debug_section = NULL;
unsigned long size;
unsigned int raw_size;
if (obj_raw_syments(abfd) != (combined_entry_type *)NULL) {
return obj_raw_syments(abfd);
@ -2529,18 +2603,26 @@ bfd *abfd)
*/
/* Swap all the raw entries */
for (raw_src = raw, internal_ptr = internal; raw_src < raw_end; raw_src++, internal_ptr++) {
for (raw_src = raw, internal_ptr = internal;
raw_src < raw_end;
raw_src++, internal_ptr++) {
unsigned int i;
coff_swap_sym_in(abfd, (char *)raw_src, (char *)&internal_ptr->u.syment);
internal_ptr->fix_tag = 0;
internal_ptr->fix_end = 0;
for (i = internal_ptr->u.syment.n_numaux; i; --i, raw_src++, internal_ptr++) {
for (i = internal_ptr->u.syment.n_numaux;
i;
--i, raw_src++, internal_ptr++) {
(internal_ptr+1)->fix_tag = 0;
(internal_ptr+1)->fix_end = 0;
coff_swap_aux_in(abfd, (char *)(raw_src +1), internal_ptr->u.syment.n_type,
internal_ptr->u.syment.n_sclass, & (internal_ptr+1)->u.auxent);
coff_swap_aux_in(abfd, (char *)(raw_src +1),
internal_ptr->u.syment.n_type,
internal_ptr->u.syment.n_sclass,
&(internal_ptr+1)->u.auxent);
coff_pointerize_aux(abfd,
internal,
@ -2560,8 +2642,7 @@ bfd *abfd)
/* make a file symbol point to the name in the auxent, since
the text ".file" is redundant */
if ((internal_ptr+1)->u.auxent.x_file.x_n.x_zeroes == 0) {
/* the filename is a long one, point into the string table
*/
/* the filename is a long one, point into the string table */
if (string_table == NULL) {
string_table = build_string_table(abfd);
}
@ -2573,22 +2654,18 @@ bfd *abfd)
else {
/* ordinary short filename, put into memory anyway */
internal_ptr->u.syment._n._n_n._n_offset = (int)
copy_name(abfd, (internal_ptr+1)->u.auxent.x_file.x_fname, FILNMLEN);
copy_name(abfd, (internal_ptr+1)->u.auxent.x_file.x_fname,
FILNMLEN);
}
}
else {
if (internal_ptr->u.syment._n._n_n._n_zeroes != 0) {
/*
This is a "short" name. Make it long.
*/
/* This is a "short" name. Make it long. */
unsigned long i = 0;
char *newstring = NULL;
/*
find the length of this string without walking into memory
that isn't ours.
*/
/* find the length of this string without walking into memory
that isn't ours. */
for (i = 0; i < 8; ++i) {
if (internal_ptr->u.syment._n._n_name[i] == '\0') {
break;
@ -2603,22 +2680,28 @@ bfd *abfd)
strncpy(newstring, internal_ptr->u.syment._n._n_name, i-1);
internal_ptr->u.syment._n._n_n._n_offset = (int) newstring;
internal_ptr->u.syment._n._n_n._n_zeroes = 0;
}
else {
/* This is a long name already. Just point it at the string in memory. */
else if (!SYMNAME_IN_DEBUG(&internal_ptr->u.syment)) {
/* Long name already. Point symbol at the string in the table. */
if (string_table == NULL) {
string_table = build_string_table(abfd);
}
internal_ptr->u.syment._n._n_n._n_offset =
(int) (string_table - 4 + internal_ptr->u.syment._n._n_n._n_offset);
internal_ptr->u.syment._n._n_n._n_offset = (int)
(string_table - 4 + internal_ptr->u.syment._n._n_n._n_offset);
}
else {
/* Long name in debug section. Very similar. */
if (debug_section == NULL) {
debug_section = build_debug_section(abfd);
}
internal_ptr->u.syment._n._n_n._n_offset = (int)
(debug_section + internal_ptr->u.syment._n._n_n._n_offset);
}
}
internal_ptr += internal_ptr->u.syment.n_numaux;
}
obj_raw_syments(abfd) = internal;
obj_string_table(abfd) = string_table;
return (internal);
} /* get_normalized_symtab() */
@ -2738,7 +2821,6 @@ DEFUN(coff_slurp_symbol_table,(abfd),
return (false);
} /* on error */
/* Allocate enough room for all the symbols in cached form */
cached_area =
(coff_symbol_type *)
@ -2784,6 +2866,9 @@ DEFUN(coff_slurp_symbol_table,(abfd),
#endif
case C_EXT:
#ifdef RS6000COFF_C
case C_HIDEXT:
#endif
if ((src->u.syment.n_scnum) == 0) {
if ((src->u.syment.n_value) == 0) {
dst->symbol.flags = BSF_UNDEFINED;
@ -2814,8 +2899,8 @@ DEFUN(coff_slurp_symbol_table,(abfd),
dst->symbol.flags |= BSF_NOT_AT_END;
}
}
break;
case C_STAT: /* static */
#ifdef I960
case C_LEAFSTAT: /* static leaf procedure */
@ -2849,7 +2934,6 @@ DEFUN(coff_slurp_symbol_table,(abfd),
case C_AUTOARG: /* 960-specific storage class */
#endif
case C_TPDEF: /* type definition */
case C_ARG:
case C_AUTO: /* automatic variable */
case C_FIELD: /* bit field */
@ -2857,17 +2941,31 @@ DEFUN(coff_slurp_symbol_table,(abfd),
case C_MOE: /* member of enumeration */
case C_MOU: /* member of union */
case C_UNTAG: /* union tag */
dst->symbol.flags = BSF_DEBUGGING;
dst->symbol.value = (src->u.syment.n_value);
break;
case C_FILE: /* file name */
case C_STRTAG: /* structure tag */
#ifdef RS6000COFF_C
case C_BINCL: /* beginning of include file */
case C_EINCL: /* ending of include file */
case C_GSYM:
case C_LSYM:
case C_PSYM:
case C_RSYM:
case C_RPSYM:
case C_STSYM:
case C_DECL:
case C_ENTRY:
case C_FUN:
case C_BSTAT:
case C_ESTAT:
#endif
dst->symbol.flags = BSF_DEBUGGING;
dst->symbol.value = (src->u.syment.n_value);
break;
case C_BLOCK: /* ".bb" or ".eb" */
case C_FCN: /* ".bf" or ".ef" */
case C_EFCN: /* physical end of function */
@ -2876,8 +2974,8 @@ DEFUN(coff_slurp_symbol_table,(abfd),
Base the value as an index from the base of the section
*/
dst->symbol.value = (src->u.syment.n_value) - dst->symbol.section->vma;
break;
case C_NULL:
case C_EXTDEF: /* external definition */
case C_ULABEL: /* undefined label */
@ -2885,7 +2983,6 @@ DEFUN(coff_slurp_symbol_table,(abfd),
case C_LINE: /* line # reformatted as symbol table entry */
case C_ALIAS: /* duplicate tag */
case C_HIDDEN: /* ext symbol in dmert public lib */
default:
fprintf(stderr,"Unrecognized storage class %d\n",
@ -2893,7 +2990,6 @@ DEFUN(coff_slurp_symbol_table,(abfd),
abort();
dst->symbol.flags = BSF_DEBUGGING;
dst->symbol.value = (src->u.syment.n_value);
break;
}
@ -3056,8 +3152,7 @@ DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols),
refering to the symbols in the raw data have not been
modified, so we have to have a negative addend to compensate.
Note that symbols which used to be common must be left alone
*/
Note that symbols which used to be common must be left alone */
if (ptr && ptr->the_bfd == abfd
&& ptr->section != (asection *) NULL
@ -3106,9 +3201,7 @@ DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols),
BFD_ASSERT(0);
}
#endif
}
}
asect->relocation = reloc_cache;
@ -3298,4 +3391,3 @@ DEFUN(coff_sizeof_headers,(abfd, reloc),
#define coff_bfd_debug_info_start bfd_void
#define coff_bfd_debug_info_end bfd_void
#define coff_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void

View File

@ -111,6 +111,12 @@ sony) bfd_target=news ;;
intel) bfd_target=${target_cpu}-coff ;;
cbm) bfd_target=${target_cpu}-elf ;;
ibm) my_host=rs6000
case "${target_cpu}" in
rs6000) bfd_target=rs6000 ;;
esac
;;
amd)
case "${target_os}" in
ebmon) bfd_target=a29k-coff ;;

View File

@ -34,20 +34,19 @@ the list.
* section prototypes::
@end menu
@node Section Input, Section Output,,Sections
@comment node-name, next, previous, up
@node Section Input, Section Output, Sections, Sections
@subsection Section Input
When a BFD is opened for reading, the section structures are created
and attatched to the BFD.
and attached to the BFD.
Each section has a name which describes the section in the outside
world - for example, @code{a.out} would contain at least three
sections, called @code{.text}, @code{.data} and @code{.bss}.
Sometimes a BFD will contain more than the 'natural' number of
sections. A back end may attatch other sections containing constructor
sections. A back end may attach other sections containing constructor
data, or an application may add a section (using bfd_make_section) to
the sections attatched to an already open BFD. For example, the linker
the sections attached to an already open BFD. For example, the linker
creates a supernumary section @code{COMMON} for each input file's BFD
to hold information about common storage.
@ -60,17 +59,17 @@ file doesn't contain raw data in sections, but data and relocation
expressions intermixed, so the data area has to be parsed to get out
the data and relocations.
@node Section Output,typedef asection,Section Input,Sections
@node Section Output, typedef asection, Section Input, Sections
@subsection Section Output
To write a new object style BFD, the various sections to be written
have to be created. They are attatched to the BFD in the same way as
have to be created. They are attached to the BFD in the same way as
input sections, data is written to the sections using
@code{bfd_set_section_contents}.
The linker uses the fields @code{output_section} and
@code{output_offset} to create an output file.
The data to be written comes from input sections attatched to the
The data to be written comes from input sections attached to the
output sections. The output section structure can be considered a
filter for the input section, the output section determines the vma of
the output data and the name, but the input section determines the
@ -97,13 +96,13 @@ subsections, "A" at offset 0x0 (ie at vma 0x100) and "B" at offset
*/
#include "sysdep.h"
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
/*doc*
@node typedef asection,section prototypes,Section Output,Sections
@node typedef asection, section prototypes, Section Output, Sections
@subsection typedef asection
*/
@ -171,7 +170,7 @@ The section contains constructor information. This section type is
used by the linker to create lists of constructors and destructors
used by @code{g++}. When a back end sees a symbol which should be used
in a constructor list, it creates a new section for the type of name
(eg @code{__CTOR_LIST__}), attatches the symbol to it and builds a
(eg @code{__CTOR_LIST__}), attaches the symbol to it and builds a
relocation. To build the lists of constructors, all the linker has to
to is catenate all the sections called @code{__CTOR_LIST__} and
relocte the data contained within - exactly the operations it would
@ -297,7 +296,7 @@ $} asection ;
*/
/*doc*
@node section prototypes,Section,typedef section,Sections
@node section prototypes, , typedef asection, Sections
@subsection section prototypes
*/
@ -322,10 +321,10 @@ DEFUN(bfd_get_section_by_name,(abfd, name),
/*proto* bfd_make_section
This function creates a new empty section called @var{name} and attatches it
This function creates a new empty section called @var{name} and attaches it
to the end of the chain of sections for the BFD supplied. An attempt to
create a section with a name which is already in use, returns the old
section by that name instead.
create a section with a name which is already in use, returns NULL without
changing the section chain.
Possible errors are:
@table @code
@ -355,7 +354,7 @@ DEFUN(bfd_make_section,(abfd, name),
}
while (sect) {
if (!strcmp(sect->name, name)) return sect;
if (!strcmp(sect->name, name)) return NULL;
prev = &sect->next;
sect = sect->next;
}
@ -418,7 +417,7 @@ DEFUN(bfd_set_section_flags,(abfd, section, flags),
/*proto* bfd_map_over_sections
Calls the provided function @var{func} for each section attatched to
Calls the provided function @var{func} for each section attached to
the BFD @var{abfd}, passing @var{obj} as an argument. The function
will be called as if by

View File

@ -341,6 +341,7 @@ extern bfd_target i386coff_vec;
extern bfd_target i386aout_vec;
extern bfd_target a29kcoff_big_vec;
extern bfd_target trad_core_vec;
extern bfd_target rs6000coff_vec;
#ifdef SELECT_VECS
@ -387,6 +388,7 @@ extern bfd_target DEFAULT_VECTOR;
#define I386COFF_VEC i386coff_vec
#define I386AOUT_VEC i386aout_vec
#define A29KCOFF_BIG_VEC a29kcoff_big_vec
#define RS6000COFF_VEC rs6000coff_vec
#endif
bfd_target *target_vector[] = {
@ -473,6 +475,10 @@ bfd_target *target_vector[] = {
&trad_core_vec,
#endif
#ifdef RS6000COFF_VEC
&RS6000COFF_VEC,
#endif
NULL, /* end of list marker */
};