X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=bfd%2Fcoff-rs6000.c;h=ba879d2f43e57345ca62890fea2a37d26667efc3;hb=fe55a7e7ca2d7ea427db43f2a97b058db48cb132;hp=31c51d5c80b499d22ca6c559ff3f5e8107663210;hpb=bb2deaf25f57e1a6d77f2321e9091f1e4a5e9c1d;p=binutils-gdb.git diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index 31c51d5c80b..ba879d2f43e 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -1,5 +1,5 @@ /* BFD back-end for IBM RS/6000 "XCOFF" files. - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + Copyright 1990, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. FIXME: Can someone provide a transliteration of this name into ASCII? Using the following chars caused a compiler warning on HIUX (so I replaced them with octal escapes), and isn't useful without an understanding of what @@ -31,11 +31,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfd.h" #include "sysdep.h" #include "libbfd.h" -#include "obstack.h" #include "coff/internal.h" #include "coff/rs6000.h" #include "libcoff.h" +/* The main body of code is in coffcode.h. */ + +static boolean xcoff_mkobject PARAMS ((bfd *)); +static boolean xcoff_copy_private_bfd_data PARAMS ((bfd *, bfd *)); +static boolean xcoff_is_local_label_name PARAMS ((bfd *, const char *)); +static void xcoff_rtype2howto + PARAMS ((arelent *, struct internal_reloc *)); +static reloc_howto_type *xcoff_reloc_type_lookup + PARAMS ((bfd *, bfd_reloc_code_real_type)); static boolean xcoff_slurp_armap PARAMS ((bfd *)); static const bfd_target *xcoff_archive_p PARAMS ((bfd *)); static PTR xcoff_read_ar_hdr PARAMS ((bfd *)); @@ -45,18 +53,104 @@ static const char *normalize_filename PARAMS ((bfd *)); static boolean xcoff_write_armap PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int)); static boolean xcoff_write_archive_contents PARAMS ((bfd *)); + +/* We use our own tdata type. Its first field is the COFF tdata type, + so the COFF routines are compatible. */ -/* The main body of code is in coffcode.h. */ +static boolean +xcoff_mkobject (abfd) + bfd *abfd; +{ + coff_data_type *coff; -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3) + abfd->tdata.xcoff_obj_data = + ((struct xcoff_tdata *) + bfd_zalloc (abfd, sizeof (struct xcoff_tdata))); + if (abfd->tdata.xcoff_obj_data == NULL) + return false; + coff = coff_data (abfd); + coff->symbols = (coff_symbol_type *) NULL; + coff->conversion_table = (unsigned int *) NULL; + coff->raw_syments = (struct coff_ptr_struct *) NULL; + coff->relocbase = 0; + + xcoff_data (abfd)->modtype = ('1' << 8) | 'L'; + + /* We set cputype to -1 to indicate that it has not been + initialized. */ + xcoff_data (abfd)->cputype = -1; + + xcoff_data (abfd)->csects = NULL; + xcoff_data (abfd)->debug_indices = NULL; + + return true; +} + +/* Copy XCOFF data from one BFD to another. */ + +static boolean +xcoff_copy_private_bfd_data (ibfd, obfd) + bfd *ibfd; + bfd *obfd; +{ + struct xcoff_tdata *ix, *ox; + asection *sec; + + if (ibfd->xvec != obfd->xvec) + return true; + ix = xcoff_data (ibfd); + ox = xcoff_data (obfd); + ox->full_aouthdr = ix->full_aouthdr; + ox->toc = ix->toc; + if (ix->sntoc == 0) + ox->sntoc = 0; + else + { + sec = coff_section_from_bfd_index (ibfd, ix->sntoc); + if (sec == NULL) + ox->sntoc = 0; + else + ox->sntoc = sec->output_section->target_index; + } + if (ix->snentry == 0) + ox->snentry = 0; + else + { + sec = coff_section_from_bfd_index (ibfd, ix->snentry); + if (sec == NULL) + ox->snentry = 0; + else + ox->snentry = sec->output_section->target_index; + } + ox->text_align_power = ix->text_align_power; + ox->data_align_power = ix->data_align_power; + ox->modtype = ix->modtype; + ox->cputype = ix->cputype; + ox->maxdata = ix->maxdata; + ox->maxstack = ix->maxstack; + return true; +} + +/* I don't think XCOFF really has a notion of local labels based on + name. This will mean that ld -X doesn't actually strip anything. + The AIX native linker does not have a -X option, and it ignores the + -x option. */ +static boolean +xcoff_is_local_label_name (abfd, name) + bfd *abfd; + const char *name; +{ + return false; +} + /* The XCOFF reloc table. Actually, XCOFF relocations specify the bitsize and whether they are signed or not, along with a conventional type. This table is for the types, which are used for different algorithms for putting in the reloc. Many of these relocs need special_function entries, which I have not written. */ -static reloc_howto_type rs6000coff_howto_table[] = +static reloc_howto_type xcoff_howto_table[] = { /* Standard 32 bit relocation. */ HOWTO (0, /* type */ @@ -110,7 +204,7 @@ static reloc_howto_type rs6000coff_howto_table[] = 16, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ + complain_overflow_bitfield, /* complain_on_overflow */ 0, /* special_function */ "R_TOC", /* name */ true, /* partial_inplace */ @@ -333,7 +427,7 @@ static reloc_howto_type rs6000coff_howto_table[] = 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ 0, /* special_function */ - "R_REL", /* name */ + "R_CREL", /* name */ true, /* partial_inplace */ 0xffff, /* src_mask */ 0xffff, /* dst_mask */ @@ -378,7 +472,7 @@ static reloc_howto_type rs6000coff_howto_table[] = 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ 0, /* special_function */ - "R_REL", /* name */ + "R_RBR", /* name */ true, /* partial_inplace */ 0xffff, /* src_mask */ 0xffff, /* dst_mask */ @@ -393,24 +487,19 @@ static reloc_howto_type rs6000coff_howto_table[] = 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ 0, /* special_function */ - "R_REL", /* name */ + "R_RBRC", /* name */ true, /* partial_inplace */ 0xffff, /* src_mask */ 0xffff, /* dst_mask */ false) /* pcrel_offset */ }; -#define RTYPE2HOWTO(cache_ptr, dst) rs6000coff_rtype2howto (cache_ptr, dst) - -static void rs6000coff_rtype2howto PARAMS ((arelent *, - struct internal_reloc *)); - static void -rs6000coff_rtype2howto (relent, internal) +xcoff_rtype2howto (relent, internal) arelent *relent; struct internal_reloc *internal; { - relent->howto = rs6000coff_howto_table + internal->r_type; + relent->howto = xcoff_howto_table + internal->r_type; /* The r_size field of an XCOFF reloc encodes the bitsize of the relocation, as well as indicating whether it is signed or not. @@ -426,26 +515,22 @@ rs6000coff_rtype2howto (relent, internal) #endif } -#define coff_bfd_reloc_type_lookup rs6000coff_reloc_type_lookup - -static reloc_howto_type *rs6000coff_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); - static reloc_howto_type * -rs6000coff_reloc_type_lookup (abfd, code) +xcoff_reloc_type_lookup (abfd, code) bfd *abfd; bfd_reloc_code_real_type code; { switch (code) { case BFD_RELOC_PPC_B26: - return &rs6000coff_howto_table[0xa]; + return &xcoff_howto_table[0xa]; case BFD_RELOC_PPC_BA26: - return &rs6000coff_howto_table[8]; + return &xcoff_howto_table[8]; case BFD_RELOC_PPC_TOC16: - return &rs6000coff_howto_table[3]; + return &xcoff_howto_table[3]; case BFD_RELOC_32: - return &rs6000coff_howto_table[0]; + case BFD_RELOC_CTOR: + return &xcoff_howto_table[0]; default: return NULL; } @@ -460,9 +545,19 @@ rs6000coff_reloc_type_lookup (abfd, code) : 0) \ | (howto->bitsize - 1)); \ } + +#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3) #define COFF_LONG_FILENAMES +#define RTYPE2HOWTO(cache_ptr, dst) xcoff_rtype2howto (cache_ptr, dst) + +#define coff_mkobject xcoff_mkobject +#define coff_bfd_copy_private_bfd_data xcoff_copy_private_bfd_data +#define coff_bfd_is_local_label_name xcoff_is_local_label_name +#define coff_bfd_reloc_type_lookup xcoff_reloc_type_lookup +#define coff_relocate_section _bfd_ppc_xcoff_relocate_section + #include "coffcode.h" /* XCOFF archive support. The original version of this code was by @@ -590,6 +685,10 @@ struct xcoff_ar_hdr bfd_false) #define xcoff_truncate_arname bfd_dont_truncate_arname +/* We can use the standard get_elt_at_index routine. */ + +#define xcoff_get_elt_at_index _bfd_generic_get_elt_at_index + /* XCOFF archives do not have a timestamp. */ #define xcoff_update_armap_timestamp bfd_true @@ -638,10 +737,7 @@ xcoff_slurp_armap (abfd) sz = strtol (hdr.size, (char **) NULL, 10); contents = (bfd_byte *) bfd_alloc (abfd, sz); if (contents == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } + return false; if (bfd_read ((PTR) contents, 1, sz, abfd) != sz) return false; @@ -657,10 +753,7 @@ xcoff_slurp_armap (abfd) bfd_ardata (abfd)->symdefs = ((carsym *) bfd_alloc (abfd, c * sizeof (carsym))); if (bfd_ardata (abfd)->symdefs == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } + return false; /* After the count comes a list of four byte file offsets. */ for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 4; @@ -717,10 +810,7 @@ xcoff_archive_p (abfd) (struct artdata *) bfd_zalloc (abfd, sizeof (struct artdata)); if (bfd_ardata (abfd) == (struct artdata *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } + return NULL; bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff, (char **) NULL, 10); @@ -731,10 +821,7 @@ xcoff_archive_p (abfd) bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, SIZEOF_AR_FILE_HDR); if (bfd_ardata (abfd)->tdata == NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } + return NULL; memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR); @@ -765,10 +852,7 @@ xcoff_read_ar_hdr (abfd) namlen = strtol (hdr.namlen, (char **) NULL, 10); hdrp = bfd_alloc (abfd, SIZEOF_AR_HDR + namlen + 1); if (hdrp == NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } + return NULL; memcpy (hdrp, &hdr, SIZEOF_AR_HDR); if (bfd_read ((char *) hdrp + SIZEOF_AR_HDR, 1, namlen, abfd) != namlen) return NULL; @@ -776,10 +860,7 @@ xcoff_read_ar_hdr (abfd) ret = (struct areltdata *) bfd_alloc (abfd, sizeof (struct areltdata)); if (ret == NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } + return NULL; ret->arch_header = (char *) hdrp; ret->parsed_size = strtol (hdr.size, (char **) NULL, 10); ret->filename = (char *) hdrp + SIZEOF_AR_HDR; @@ -826,7 +907,7 @@ xcoff_openr_next_archived_file (archive, last_file) /* Stat an element in an XCOFF archive. */ -int +static int xcoff_generic_stat_arch_elt (abfd, s) bfd *abfd; struct stat *s; @@ -881,7 +962,7 @@ xcoff_write_armap (abfd, elength, map, orl_count, stridx) { struct xcoff_ar_hdr hdr; char *p; - char buf[4]; + unsigned char buf[4]; bfd *sub; file_ptr fileoff; unsigned int i; @@ -991,10 +1072,7 @@ xcoff_write_archive_contents (abfd) } offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr)); if (offsets == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } + return false; if (bfd_seek (abfd, SIZEOF_AR_FILE_HDR, SEEK_SET) != 0) return false; @@ -1033,7 +1111,7 @@ xcoff_write_archive_contents (abfd) if (stat (bfd_get_filename (sub), &s) != 0) { bfd_set_error (bfd_error_system_call); - return NULL; + return false; } sprintf (ahdrp->size, "%ld", (long) s.st_size); @@ -1047,10 +1125,7 @@ xcoff_write_archive_contents (abfd) sub->arelt_data = ((struct areltdata *) bfd_alloc (sub, sizeof (struct areltdata))); if (sub->arelt_data == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } + return false; } arch_eltdata (sub)->parsed_size = s.st_size; @@ -1211,6 +1286,26 @@ xcoff_write_archive_contents (abfd) return true; } +/* We can't use the usual coff_sizeof_headers routine, because AIX + always uses an a.out header. */ + +/*ARGSUSED*/ +static int +_bfd_xcoff_sizeof_headers (abfd, reloc) + bfd *abfd; + boolean reloc; +{ + int size; + + size = FILHSZ; + if (xcoff_data (abfd)->full_aouthdr) + size += AOUTSZ; + else + size += SMALL_AOUTSZ; + size += abfd->section_count * SCNHSZ; + return size; +} + #define CORE_FILE_P _bfd_dummy_target #define coff_core_file_failing_command _bfd_nocore_core_file_failing_command @@ -1262,17 +1357,31 @@ extern int lynx_core_file_failing_signal PARAMS ((bfd *abfd)); #endif /* LYNX_CORE */ +#define _bfd_xcoff_bfd_get_relocated_section_contents \ + coff_bfd_get_relocated_section_contents +#define _bfd_xcoff_bfd_relax_section coff_bfd_relax_section +#define _bfd_xcoff_bfd_link_split_section coff_bfd_link_split_section + /* The transfer vector that leads the outside world to all of the above. */ -const bfd_target rs6000coff_vec = +const bfd_target +#ifdef TARGET_SYM + TARGET_SYM = +#else + rs6000coff_vec = +#endif { +#ifdef TARGET_NAME + TARGET_NAME, +#else "aixcoff-rs6000", /* name */ +#endif bfd_target_coff_flavour, - true, /* data byte order is big */ - true, /* header byte order is big */ + BFD_ENDIAN_BIG, /* data byte order is big */ + BFD_ENDIAN_BIG, /* header byte order is big */ (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | + HAS_LINENO | HAS_DEBUG | DYNAMIC | HAS_SYMS | HAS_LOCALS | WP_TEXT), (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ @@ -1301,8 +1410,8 @@ const bfd_target rs6000coff_vec = BFD_JUMP_TABLE_SYMBOLS (coff), BFD_JUMP_TABLE_RELOCS (coff), BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), + BFD_JUMP_TABLE_LINK (_bfd_xcoff), + BFD_JUMP_TABLE_DYNAMIC (_bfd_xcoff), COFF_SWAP_TABLE, };