/* coff-msym.c: Byte-swap a symbol table in MIPS' format (Third-Eye, `ecoff'). Copyright 1992 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. 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 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 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; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* These routines are not yet called from BFD. They are called from the MIPS symbol reading code in GDB. However, they are in the BFD library because they will eventually be useful if and when BFD supports reading or writing of MIPS symbol tables. FLASH! FIXME! Unfortunately MIPS has these *%&%&$#^# copyrighted include files defining the symbol format (which I've been politely asking them to release for public use for about a year now). Since this function can only compile if these include files are available, the config files for MIPS-based hosts configure the Makefile so that this file will be compiled only if on a MIPS-based host. FIXME! The routines in this file convert the external representation of ECOFF symbol tables to the internal (usual struct) representation. On a machine with the same byte-order and the same basic type sizes and alignments as a MIPS machine, this is a no-op. If the symbol TEST is defined when this file is compiled, a comparison is made to ensure that, in fact, the output is bit-for-bit the same as the input. Of course, this symbol should only be defined when deliberately testing the code on a machine with the proper byte sex and such. */ #include "bfd.h" #undef LANGUAGE_C #define LANGUAGE_C /* Wierd MIPS crap */ #include "sym.h" /* MIPS symbols */ #include "symconst.h" /* MIPS symbols */ #include "coff/ecoff-ext.h" /* ECOFF external struct defns */ void ecoff_swap_hdr_in (abfd, ext_copy, intern) bfd *abfd; struct hdr_ext *ext_copy; HDRR *intern; { struct hdr_ext ext[1]; *ext = *ext_copy; intern->magic = bfd_h_get_16 (abfd, (bfd_byte *)ext->h_magic); intern->vstamp = bfd_h_get_16 (abfd, (bfd_byte *)ext->h_vstamp); intern->ilineMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ilineMax); intern->cbLine = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_cbLine); intern->cbLineOffset = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_cbLineOffset); intern->idnMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_idnMax); intern->cbDnOffset = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_cbDnOffset); intern->ipdMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ipdMax); intern->cbPdOffset = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_cbPdOffset); intern->isymMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_isymMax); intern->cbSymOffset = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_cbSymOffset); intern->ioptMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ioptMax); intern->cbOptOffset = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_cbOptOffset); intern->iauxMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_iauxMax); intern->cbAuxOffset = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_cbAuxOffset); intern->issMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_issMax); intern->cbSsOffset = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_cbSsOffset); intern->issExtMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_issExtMax); intern->cbSsExtOffset = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_cbSsExtOffset); intern->ifdMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ifdMax); intern->cbFdOffset = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_cbFdOffset); intern->crfd = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_crfd); intern->cbRfdOffset = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_cbRfdOffset); intern->iextMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_iextMax); intern->cbExtOffset = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_cbExtOffset); #ifdef TEST if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) abort(); #endif } /* Swap in the file descriptor record. */ void ecoff_swap_fdr_in (abfd, ext_copy, intern) bfd *abfd; struct fdr_ext *ext_copy; FDR *intern; { struct fdr_ext ext[1]; *ext = *ext_copy; /* Make it reasonable to do in-place. */ intern->adr = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_adr); intern->rss = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_rss); intern->issBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_issBase); intern->cbSs = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_cbSs); intern->isymBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_isymBase); intern->csym = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_csym); intern->ilineBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_ilineBase); intern->cline = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_cline); intern->ioptBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_ioptBase); intern->copt = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_copt); intern->ipdFirst = bfd_h_get_16 (abfd, (bfd_byte *)ext->f_ipdFirst); intern->cpd = bfd_h_get_16 (abfd, (bfd_byte *)ext->f_cpd); intern->iauxBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_iauxBase); intern->caux = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_caux); intern->rfdBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_rfdBase); intern->crfd = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_crfd); /* now the fun stuff... */ if (abfd->xvec->header_byteorder_big_p != false) { intern->lang = (ext->f_bits1[0] & FDR_BITS1_LANG_BIG) >> FDR_BITS1_LANG_SH_BIG; intern->fMerge = 0 != (ext->f_bits1[0] & FDR_BITS1_FMERGE_BIG); intern->fReadin = 0 != (ext->f_bits1[0] & FDR_BITS1_FREADIN_BIG); intern->fBigendian = 0 != (ext->f_bits1[0] & FDR_BITS1_FBIGENDIAN_BIG); intern->glevel = (ext->f_bits2[0] & FDR_BITS2_GLEVEL_BIG) >> FDR_BITS2_GLEVEL_SH_BIG; /* intern->reserved we ignore. */ } else { intern->lang = (ext->f_bits1[0] & FDR_BITS1_LANG_LITTLE) >> FDR_BITS1_LANG_SH_LITTLE; intern->fMerge = 0 != (ext->f_bits1[0] & FDR_BITS1_FMERGE_LITTLE); intern->fReadin = 0 != (ext->f_bits1[0] & FDR_BITS1_FREADIN_LITTLE); intern->fBigendian = 0 != (ext->f_bits1[0] & FDR_BITS1_FBIGENDIAN_LITTLE); intern->glevel = (ext->f_bits2[0] & FDR_BITS2_GLEVEL_LITTLE) >> FDR_BITS2_GLEVEL_SH_LITTLE; /* intern->reserved we ignore. */ } intern->cbLineOffset = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_cbLineOffset); intern->cbLine = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_cbLine); #ifdef TEST if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) abort(); #endif } /* Swap in the procedure descriptor record. */ void ecoff_swap_pdr_in (abfd, ext_copy, intern) bfd *abfd; struct pdr_ext *ext_copy; PDR *intern; { struct pdr_ext ext[1]; *ext = *ext_copy; /* Make it reasonable to do in-place. */ intern->adr = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_adr); intern->isym = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_isym); intern->iline = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_iline); intern->regmask = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_regmask); intern->regoffset = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_regoffset); intern->iopt = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_iopt); intern->fregmask = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_fregmask); intern->fregoffset = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_fregoffset); intern->frameoffset = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_frameoffset); intern->framereg = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_framereg); intern->pcreg = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_pcreg); intern->lnLow = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnLow); intern->lnHigh = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnHigh); intern->cbLineOffset = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_cbLineOffset); #ifdef TEST if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) abort(); #endif } /* Swap in a symbol record. */ void ecoff_swap_sym_in (abfd, ext_copy, intern) bfd *abfd; struct sym_ext *ext_copy; SYMR *intern; { struct sym_ext ext[1]; *ext = *ext_copy; /* Make it reasonable to do in-place. */ intern->iss = bfd_h_get_32 (abfd, (bfd_byte *)ext->s_iss); intern->value = bfd_h_get_32 (abfd, (bfd_byte *)ext->s_value); /* now the fun stuff... */ if (abfd->xvec->header_byteorder_big_p != false) { intern->st = (ext->s_bits1[0] & SYM_BITS1_ST_BIG) >> SYM_BITS1_ST_SH_BIG; intern->sc = ((ext->s_bits1[0] & SYM_BITS1_SC_BIG) << SYM_BITS1_SC_SH_LEFT_BIG) | ((ext->s_bits2[0] & SYM_BITS2_SC_BIG) >> SYM_BITS2_SC_SH_BIG); intern->reserved = 0 != (ext->s_bits2[0] & SYM_BITS2_RESERVED_BIG); intern->index = ((ext->s_bits2[0] & SYM_BITS2_INDEX_BIG) << SYM_BITS2_INDEX_SH_LEFT_BIG) | (ext->s_bits3[0] << SYM_BITS3_INDEX_SH_LEFT_BIG) | (ext->s_bits4[0] << SYM_BITS4_INDEX_SH_LEFT_BIG); } else { intern->st = (ext->s_bits1[0] & SYM_BITS1_ST_LITTLE) >> SYM_BITS1_ST_SH_LITTLE; intern->sc = ((ext->s_bits1[0] & SYM_BITS1_SC_LITTLE) >> SYM_BITS1_SC_SH_LITTLE) | ((ext->s_bits2[0] & SYM_BITS2_SC_LITTLE) << SYM_BITS2_SC_SH_LEFT_LITTLE); intern->reserved = 0 != (ext->s_bits2[0] & SYM_BITS2_RESERVED_LITTLE); intern->index = ((ext->s_bits2[0] & SYM_BITS2_INDEX_LITTLE) >> SYM_BITS2_INDEX_SH_LITTLE) | (ext->s_bits3[0] << SYM_BITS3_INDEX_SH_LEFT_LITTLE) | (ext->s_bits4[0] << SYM_BITS4_INDEX_SH_LEFT_LITTLE); } #ifdef TEST if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) abort(); #endif } /* Swap in an external symbol record. */ void ecoff_swap_ext_in (abfd, ext_copy, intern) bfd *abfd; struct ext_ext *ext_copy; EXTR *intern; { struct ext_ext ext[1]; *ext = *ext_copy; /* Make it reasonable to do in-place. */ /* now the fun stuff... */ if (abfd->xvec->header_byteorder_big_p != false) { intern->jmptbl = 0 != (ext->es_bits1[0] & EXT_BITS1_JMPTBL_BIG); intern->cobol_main = 0 != (ext->es_bits1[0] & EXT_BITS1_COBOL_MAIN_BIG); } else { intern->jmptbl = 0 != (ext->es_bits1[0] & EXT_BITS1_JMPTBL_LITTLE); intern->cobol_main = 0 != (ext->es_bits1[0] & EXT_BITS1_COBOL_MAIN_LITTLE); } intern->ifd = bfd_h_get_16 (abfd, (bfd_byte *)ext->es_ifd); ecoff_swap_sym_in (abfd, &ext->es_asym, &intern->asym); #ifdef TEST if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) abort(); #endif } /* Swap in a type information record. BIGEND says whether AUX symbols are big-endian or little-endian; this info comes from the file header record (fh-fBigendian). */ void ecoff_swap_tir_in (bigend, ext_copy, intern) int bigend; struct tir_ext *ext_copy; TIR *intern; { struct tir_ext ext[1]; *ext = *ext_copy; /* Make it reasonable to do in-place. */ /* now the fun stuff... */ if (bigend) { intern->fBitfield = 0 != (ext->t_bits1[0] & TIR_BITS1_FBITFIELD_BIG); intern->continued = 0 != (ext->t_bits1[0] & TIR_BITS1_CONTINUED_BIG); intern->bt = (ext->t_bits1[0] & TIR_BITS1_BT_BIG) >> TIR_BITS1_BT_SH_BIG; intern->tq4 = (ext->t_tq45[0] & TIR_BITS_TQ4_BIG) >> TIR_BITS_TQ4_SH_BIG; intern->tq5 = (ext->t_tq45[0] & TIR_BITS_TQ5_BIG) >> TIR_BITS_TQ5_SH_BIG; intern->tq0 = (ext->t_tq01[0] & TIR_BITS_TQ0_BIG) >> TIR_BITS_TQ0_SH_BIG; intern->tq1 = (ext->t_tq01[0] & TIR_BITS_TQ1_BIG) >> TIR_BITS_TQ1_SH_BIG; intern->tq2 = (ext->t_tq23[0] & TIR_BITS_TQ2_BIG) >> TIR_BITS_TQ2_SH_BIG; intern->tq3 = (ext->t_tq23[0] & TIR_BITS_TQ3_BIG) >> TIR_BITS_TQ3_SH_BIG; } else { intern->fBitfield = 0 != (ext->t_bits1[0] & TIR_BITS1_FBITFIELD_LITTLE); intern->continued = 0 != (ext->t_bits1[0] & TIR_BITS1_CONTINUED_LITTLE); intern->bt = (ext->t_bits1[0] & TIR_BITS1_BT_LITTLE) >> TIR_BITS1_BT_SH_LITTLE; intern->tq4 = (ext->t_tq45[0] & TIR_BITS_TQ4_LITTLE) >> TIR_BITS_TQ4_SH_LITTLE; intern->tq5 = (ext->t_tq45[0] & TIR_BITS_TQ5_LITTLE) >> TIR_BITS_TQ5_SH_LITTLE; intern->tq0 = (ext->t_tq01[0] & TIR_BITS_TQ0_LITTLE) >> TIR_BITS_TQ0_SH_LITTLE; intern->tq1 = (ext->t_tq01[0] & TIR_BITS_TQ1_LITTLE) >> TIR_BITS_TQ1_SH_LITTLE; intern->tq2 = (ext->t_tq23[0] & TIR_BITS_TQ2_LITTLE) >> TIR_BITS_TQ2_SH_LITTLE; intern->tq3 = (ext->t_tq23[0] & TIR_BITS_TQ3_LITTLE) >> TIR_BITS_TQ3_SH_LITTLE; } #ifdef TEST if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) abort(); #endif } /* Swap in a relative symbol record. BIGEND says whether it is in big-endian or little-endian format.*/ void ecoff_swap_rndx_in (bigend, ext_copy, intern) int bigend; struct rndx_ext *ext_copy; RNDXR *intern; { struct rndx_ext ext[1]; *ext = *ext_copy; /* Make it reasonable to do in-place. */ /* now the fun stuff... */ if (bigend) { intern->rfd = (ext->r_bits[0] << RNDX_BITS0_RFD_SH_LEFT_BIG) | ((ext->r_bits[1] & RNDX_BITS1_RFD_BIG) >> RNDX_BITS1_RFD_SH_BIG); intern->index = ((ext->r_bits[1] & RNDX_BITS1_INDEX_BIG) << RNDX_BITS1_INDEX_SH_LEFT_BIG) | (ext->r_bits[2] << RNDX_BITS2_INDEX_SH_LEFT_BIG) | (ext->r_bits[3] << RNDX_BITS3_INDEX_SH_LEFT_BIG); } else { intern->rfd = (ext->r_bits[0] << RNDX_BITS0_RFD_SH_LEFT_LITTLE) | ((ext->r_bits[1] & RNDX_BITS1_RFD_LITTLE) << RNDX_BITS1_RFD_SH_LEFT_LITTLE); intern->index = ((ext->r_bits[1] & RNDX_BITS1_INDEX_LITTLE) >> RNDX_BITS1_INDEX_SH_LITTLE) | (ext->r_bits[2] << RNDX_BITS2_INDEX_SH_LEFT_LITTLE) | (ext->r_bits[3] << RNDX_BITS3_INDEX_SH_LEFT_LITTLE); } #ifdef TEST if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) abort(); #endif } /* Swap in a relative file descriptor. */ void ecoff_swap_rfd_in (abfd, ext, intern) bfd *abfd; struct rfd_ext *ext; RFDT *intern; { *intern = bfd_h_get_32 (abfd, (bfd_byte *)&ext->rfd); #ifdef TEST if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) abort(); #endif }