coff-rs6000.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,164 行 · 第 1/5 页
C
2,164 行
/* BFD back-end for IBM RS/6000 "XCOFF" files. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 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 character set it is. Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365, and John Gilmore. Archive support from Damon A. Permezel. Contributed by IBM Corporation and Cygnus Support.This file is part of BFD, the Binary File Descriptor library.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "bfd.h"#include "sysdep.h"#include "libbfd.h"#include "coff/internal.h"#include "coff/rs6000.h"#include "libcoff.h"#define TARGET_NAME "aixcoff-rs6000"#define TARGET_SYM rs6000coff_vec#include "xcoff-target.h"/* The main body of code is in coffcode.h. */static const char *normalize_filename PARAMS ((bfd *));/* We use our own tdata type. Its first field is the COFF tdata type, so the COFF routines are compatible. */boolean_bfd_xcoff_mkobject (abfd) bfd *abfd;{ coff_data_type *coff; 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. */boolean_bfd_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. */boolean_bfd_xcoff_is_local_label_name (abfd, name) bfd *abfd ATTRIBUTE_UNUSED; const char *name ATTRIBUTE_UNUSED;{ return false;}void_bfd_xcoff_swap_sym_in (abfd, ext1, in1) bfd *abfd; PTR ext1; PTR in1;{ SYMENT *ext = (SYMENT *)ext1; struct internal_syment *in = (struct internal_syment *)in1; if (ext->e.e_name[0] != 0) { memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN); } else { in->_n._n_n._n_zeroes = 0; in->_n._n_n._n_offset = bfd_h_get_32(abfd, (bfd_byte *) ext->e.e.e_offset); } in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value); in->n_scnum = bfd_h_get_16(abfd, (bfd_byte *) ext->e_scnum); in->n_type = bfd_h_get_16(abfd, (bfd_byte *) ext->e_type); in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass); in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux);}unsigned int_bfd_xcoff_swap_sym_out (abfd, inp, extp) bfd *abfd; PTR inp; PTR extp;{ struct internal_syment *in = (struct internal_syment *)inp; SYMENT *ext =(SYMENT *)extp; if (in->_n._n_name[0] != 0) { memcpy(ext->e.e_name, in->_n._n_name, SYMNMLEN); } else { bfd_h_put_32(abfd, 0, (bfd_byte *) ext->e.e.e_zeroes); bfd_h_put_32(abfd, in->_n._n_n._n_offset, (bfd_byte *) ext->e.e.e_offset); } bfd_h_put_32(abfd, in->n_value , (bfd_byte *) ext->e_value); bfd_h_put_16(abfd, in->n_scnum , (bfd_byte *) ext->e_scnum); bfd_h_put_16(abfd, in->n_type , (bfd_byte *) ext->e_type); bfd_h_put_8(abfd, in->n_sclass , ext->e_sclass); bfd_h_put_8(abfd, in->n_numaux , ext->e_numaux); return bfd_coff_symesz (abfd);}#define PUTWORD bfd_h_put_32#define PUTHALF bfd_h_put_16#define PUTBYTE bfd_h_put_8#define GETWORD bfd_h_get_32#define GETHALF bfd_h_get_16#define GETBYTE bfd_h_get_8void_bfd_xcoff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1) bfd *abfd; PTR ext1; int type; int class; int indx; int numaux; PTR in1;{ AUXENT *ext = (AUXENT *)ext1; union internal_auxent *in = (union internal_auxent *)in1; switch (class) { case C_FILE: if (ext->x_file.x_fname[0] == 0) { in->x_file.x_n.x_zeroes = 0; in->x_file.x_n.x_offset = bfd_h_get_32(abfd, (bfd_byte *) ext->x_file.x_n.x_offset); } else { if (numaux > 1) { if (indx == 0) memcpy (in->x_file.x_fname, ext->x_file.x_fname, numaux * sizeof (AUXENT)); } else { memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN); } } goto end; /* RS/6000 "csect" auxents */ case C_EXT: case C_HIDEXT: if (indx + 1 == numaux) { in->x_csect.x_scnlen.l = bfd_h_get_32 (abfd, ext->x_csect.x_scnlen); in->x_csect.x_parmhash = bfd_h_get_32 (abfd, ext->x_csect.x_parmhash); in->x_csect.x_snhash = bfd_h_get_16 (abfd, ext->x_csect.x_snhash); /* We don't have to hack bitfields in x_smtyp because it's defined by shifts-and-ands, which are equivalent on all byte orders. */ in->x_csect.x_smtyp = bfd_h_get_8 (abfd, ext->x_csect.x_smtyp); in->x_csect.x_smclas = bfd_h_get_8 (abfd, ext->x_csect.x_smclas); in->x_csect.x_stab = bfd_h_get_32 (abfd, ext->x_csect.x_stab); in->x_csect.x_snstab = bfd_h_get_16 (abfd, ext->x_csect.x_snstab); goto end; } break; case C_STAT: case C_LEAFSTAT: case C_HIDDEN: if (type == T_NULL) { in->x_scn.x_scnlen = bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_scnlen); in->x_scn.x_nreloc = bfd_h_get_16(abfd, (bfd_byte *) ext->x_scn.x_nreloc); in->x_scn.x_nlinno = bfd_h_get_16(abfd, (bfd_byte *) ext->x_scn.x_nlinno); /* PE defines some extra fields; we zero them out for safety. */ in->x_scn.x_checksum = 0; in->x_scn.x_associated = 0; in->x_scn.x_comdat = 0; goto end; } break; } in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_tagndx); in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx); if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class)) { in->x_sym.x_fcnary.x_fcn.x_lnnoptr = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr); in->x_sym.x_fcnary.x_fcn.x_endndx.l = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx); } else { in->x_sym.x_fcnary.x_ary.x_dimen[0] = bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]); in->x_sym.x_fcnary.x_ary.x_dimen[1] = bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]); in->x_sym.x_fcnary.x_ary.x_dimen[2] = bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]); in->x_sym.x_fcnary.x_ary.x_dimen[3] = bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]); } if (ISFCN(type)) { in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize); } else { in->x_sym.x_misc.x_lnsz.x_lnno = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_lnno); in->x_sym.x_misc.x_lnsz.x_size = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_size); }end: ; /* the semicolon is because MSVC doesn't like labels at end of block. */}unsigned int_bfd_xcoff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp) bfd *abfd; PTR inp; int type; int class; int indx ATTRIBUTE_UNUSED; int numaux ATTRIBUTE_UNUSED; PTR extp;{ union internal_auxent *in = (union internal_auxent *)inp; AUXENT *ext = (AUXENT *)extp; memset((PTR)ext, 0, bfd_coff_auxesz (abfd)); 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, in->x_file.x_n.x_offset, (bfd_byte *) ext->x_file.x_n.x_offset); } else { memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN); } goto end; /* RS/6000 "csect" auxents */ case C_EXT: case C_HIDEXT: if (indx + 1 == numaux) { PUTWORD (abfd, in->x_csect.x_scnlen.l,ext->x_csect.x_scnlen); PUTWORD (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash); PUTHALF (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash); /* We don't have to hack bitfields in x_smtyp because it's defined by shifts-and-ands, which are equivalent on all byte orders. */ PUTBYTE (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp); PUTBYTE (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas); PUTWORD (abfd, in->x_csect.x_stab, ext->x_csect.x_stab); PUTHALF (abfd, in->x_csect.x_snstab, ext->x_csect.x_snstab); goto end; } break; case C_STAT: case C_LEAFSTAT: case C_HIDDEN: if (type == T_NULL) { bfd_h_put_32(abfd, in->x_scn.x_scnlen, (bfd_byte *) ext->x_scn.x_scnlen); bfd_h_put_16(abfd, in->x_scn.x_nreloc, (bfd_byte *) ext->x_scn.x_nreloc); bfd_h_put_16(abfd, in->x_scn.x_nlinno, (bfd_byte *) ext->x_scn.x_nlinno); goto end; } break; } PUTWORD(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx); bfd_h_put_16 (abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx); if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class)) { bfd_h_put_32(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr); PUTWORD(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx); } else { bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0], (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]); bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1], (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]); bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2], (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]); bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3], (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]); } if (ISFCN (type)) PUTWORD (abfd, in->x_sym.x_misc.x_fsize, (bfd_byte *) ext->x_sym.x_misc.x_fsize); else { bfd_h_put_16(abfd, in->x_sym.x_misc.x_lnsz.x_lnno, (bfd_byte *)ext->x_sym.x_misc.x_lnsz.x_lnno); bfd_h_put_16(abfd, in->x_sym.x_misc.x_lnsz.x_size, (bfd_byte *)ext->x_sym.x_misc.x_lnsz.x_size); }end: return bfd_coff_auxesz (abfd);}/* 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. *//* In case we're on a 32-bit machine, construct a 64-bit "-1" value from smaller values. Start with zero, widen, *then* decrement. */#define MINUS_ONE (((bfd_vma)0) - 1)reloc_howto_type xcoff_howto_table[] ={ /* Standard 32 bit relocation. */ HOWTO (0, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ 0, /* special_function */ "R_POS", /* name */ true, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ false), /* pcrel_offset */ /* 32 bit relocation, but store negative value. */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?