(linenum→info "unix/slp.c:2238")

binutils/2.18/bfd/coffswap.h

    1: /* Generic COFF swapping routines, for BFD.
    2:    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000,
    3:    2001, 2002, 2005, 2007
    4:    Free Software Foundation, Inc.
    5:    Written by Cygnus Support.
    6: 
    7:    This file is part of BFD, the Binary File Descriptor library.
    8: 
    9:    This program is free software; you can redistribute it and/or modify
   10:    it under the terms of the GNU General Public License as published by
   11:    the Free Software Foundation; either version 3 of the License, or
   12:    (at your option) any later version.
   13: 
   14:    This program is distributed in the hope that it will be useful,
   15:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   16:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17:    GNU General Public License for more details.
   18: 
   19:    You should have received a copy of the GNU General Public License
   20:    along with this program; if not, write to the Free Software
   21:    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   22:    MA 02110-1301, USA.  */
   23: 
   24: /* This file contains routines used to swap COFF data.  It is a header
   25:    file because the details of swapping depend on the details of the
   26:    structures used by each COFF implementation.  This is included by
   27:    coffcode.h, as well as by the ECOFF backend.
   28: 
   29:    Any file which uses this must first include "coff/internal.h" and
   30:    "coff/CPU.h".  The functions will then be correct for that CPU.  */
   31: 
   32: #ifndef GET_FCN_LNNOPTR
   33: #define GET_FCN_LNNOPTR(abfd, ext) \
   34:   H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
   35: #endif
   36: 
   37: #ifndef GET_FCN_ENDNDX
   38: #define GET_FCN_ENDNDX(abfd, ext) \
   39:   H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx)
   40: #endif
   41: 
   42: #ifndef PUT_FCN_LNNOPTR
   43: #define PUT_FCN_LNNOPTR(abfd, in, ext) \
   44:   H_PUT_32 (abfd,  in, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
   45: #endif
   46: #ifndef PUT_FCN_ENDNDX
   47: #define PUT_FCN_ENDNDX(abfd, in, ext) \
   48:   H_PUT_32 (abfd, in, ext->x_sym.x_fcnary.x_fcn.x_endndx)
   49: #endif
   50: #ifndef GET_LNSZ_LNNO
   51: #define GET_LNSZ_LNNO(abfd, ext) \
   52:   H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_lnno)
   53: #endif
   54: #ifndef GET_LNSZ_SIZE
   55: #define GET_LNSZ_SIZE(abfd, ext) \
   56:   H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_size)
   57: #endif
   58: #ifndef PUT_LNSZ_LNNO
   59: #define PUT_LNSZ_LNNO(abfd, in, ext) \
   60:   H_PUT_16 (abfd, in, ext->x_sym.x_misc.x_lnsz.x_lnno)
   61: #endif
   62: #ifndef PUT_LNSZ_SIZE
   63: #define PUT_LNSZ_SIZE(abfd, in, ext) \
   64:   H_PUT_16 (abfd, in, ext->x_sym.x_misc.x_lnsz.x_size)
   65: #endif
   66: #ifndef GET_SCN_SCNLEN
   67: #define GET_SCN_SCNLEN(abfd, ext) \
   68:   H_GET_32 (abfd, ext->x_scn.x_scnlen)
   69: #endif
   70: #ifndef GET_SCN_NRELOC
   71: #define GET_SCN_NRELOC(abfd, ext) \
   72:   H_GET_16 (abfd, ext->x_scn.x_nreloc)
   73: #endif
   74: #ifndef GET_SCN_NLINNO
   75: #define GET_SCN_NLINNO(abfd, ext) \
   76:   H_GET_16 (abfd, ext->x_scn.x_nlinno)
   77: #endif
   78: #ifndef PUT_SCN_SCNLEN
   79: #define PUT_SCN_SCNLEN(abfd, in, ext) \
   80:   H_PUT_32 (abfd, in, ext->x_scn.x_scnlen)
   81: #endif
   82: #ifndef PUT_SCN_NRELOC
   83: #define PUT_SCN_NRELOC(abfd, in, ext) \
   84:   H_PUT_16 (abfd, in, ext->x_scn.x_nreloc)
   85: #endif
   86: #ifndef PUT_SCN_NLINNO
   87: #define PUT_SCN_NLINNO(abfd, in, ext) \
   88:   H_PUT_16 (abfd, in, ext->x_scn.x_nlinno)
   89: #endif
   90: #ifndef GET_LINENO_LNNO
   91: #define GET_LINENO_LNNO(abfd, ext) \
   92:   H_GET_16 (abfd, ext->l_lnno);
   93: #endif
   94: #ifndef PUT_LINENO_LNNO
   95: #define PUT_LINENO_LNNO(abfd, val, ext) \
   96:   H_PUT_16 (abfd, val, ext->l_lnno);
   97: #endif
   98: 
   99: /* The f_symptr field in the filehdr is sometimes 64 bits.  */
  100: #ifndef GET_FILEHDR_SYMPTR
  101: #define GET_FILEHDR_SYMPTR H_GET_32
  102: #endif
  103: #ifndef PUT_FILEHDR_SYMPTR
  104: #define PUT_FILEHDR_SYMPTR H_PUT_32
  105: #endif
  106: 
  107: /* Some fields in the aouthdr are sometimes 64 bits.  */
  108: #ifndef GET_AOUTHDR_TSIZE
  109: #define GET_AOUTHDR_TSIZE H_GET_32
  110: #endif
  111: #ifndef PUT_AOUTHDR_TSIZE
  112: #define PUT_AOUTHDR_TSIZE H_PUT_32
  113: #endif
  114: #ifndef GET_AOUTHDR_DSIZE
  115: #define GET_AOUTHDR_DSIZE H_GET_32
  116: #endif
  117: #ifndef PUT_AOUTHDR_DSIZE
  118: #define PUT_AOUTHDR_DSIZE H_PUT_32
  119: #endif
  120: #ifndef GET_AOUTHDR_BSIZE
  121: #define GET_AOUTHDR_BSIZE H_GET_32
  122: #endif
  123: #ifndef PUT_AOUTHDR_BSIZE
  124: #define PUT_AOUTHDR_BSIZE H_PUT_32
  125: #endif
  126: #ifndef GET_AOUTHDR_ENTRY
  127: #define GET_AOUTHDR_ENTRY H_GET_32
  128: #endif
  129: #ifndef PUT_AOUTHDR_ENTRY
  130: #define PUT_AOUTHDR_ENTRY H_PUT_32
  131: #endif
  132: #ifndef GET_AOUTHDR_TEXT_START
  133: #define GET_AOUTHDR_TEXT_START H_GET_32
  134: #endif
  135: #ifndef PUT_AOUTHDR_TEXT_START
  136: #define PUT_AOUTHDR_TEXT_START H_PUT_32
  137: #endif
  138: #ifndef GET_AOUTHDR_DATA_START
  139: #define GET_AOUTHDR_DATA_START H_GET_32
  140: #endif
  141: #ifndef PUT_AOUTHDR_DATA_START
  142: #define PUT_AOUTHDR_DATA_START H_PUT_32
  143: #endif
  144: 
  145: /* Some fields in the scnhdr are sometimes 64 bits.  */
  146: #ifndef GET_SCNHDR_PADDR
  147: #define GET_SCNHDR_PADDR H_GET_32
  148: #endif
  149: #ifndef PUT_SCNHDR_PADDR
  150: #define PUT_SCNHDR_PADDR H_PUT_32
  151: #endif
  152: #ifndef GET_SCNHDR_VADDR
  153: #define GET_SCNHDR_VADDR H_GET_32
  154: #endif
  155: #ifndef PUT_SCNHDR_VADDR
  156: #define PUT_SCNHDR_VADDR H_PUT_32
  157: #endif
  158: #ifndef GET_SCNHDR_SIZE
  159: #define GET_SCNHDR_SIZE H_GET_32
  160: #endif
  161: #ifndef PUT_SCNHDR_SIZE
  162: #define PUT_SCNHDR_SIZE H_PUT_32
  163: #endif
  164: #ifndef GET_SCNHDR_SCNPTR
  165: #define GET_SCNHDR_SCNPTR H_GET_32
  166: #endif
  167: #ifndef PUT_SCNHDR_SCNPTR
  168: #define PUT_SCNHDR_SCNPTR H_PUT_32
  169: #endif
  170: #ifndef GET_SCNHDR_RELPTR
  171: #define GET_SCNHDR_RELPTR H_GET_32
  172: #endif
  173: #ifndef PUT_SCNHDR_RELPTR
  174: #define PUT_SCNHDR_RELPTR H_PUT_32
  175: #endif
  176: #ifndef GET_SCNHDR_LNNOPTR
  177: #define GET_SCNHDR_LNNOPTR H_GET_32
  178: #endif
  179: #ifndef PUT_SCNHDR_LNNOPTR
  180: #define PUT_SCNHDR_LNNOPTR H_PUT_32
  181: #endif
  182: #ifndef GET_SCNHDR_NRELOC
  183: #define GET_SCNHDR_NRELOC H_GET_16
  184: #endif
  185: #ifndef MAX_SCNHDR_NRELOC
  186: #define MAX_SCNHDR_NRELOC 0xffff
  187: #endif
  188: #ifndef PUT_SCNHDR_NRELOC
  189: #define PUT_SCNHDR_NRELOC H_PUT_16
  190: #endif
  191: #ifndef GET_SCNHDR_NLNNO
  192: #define GET_SCNHDR_NLNNO H_GET_16
  193: #endif
  194: #ifndef MAX_SCNHDR_NLNNO
  195: #define MAX_SCNHDR_NLNNO 0xffff
  196: #endif
  197: #ifndef PUT_SCNHDR_NLNNO
  198: #define PUT_SCNHDR_NLNNO H_PUT_16
  199: #endif
  200: #ifndef GET_SCNHDR_FLAGS
  201: #define GET_SCNHDR_FLAGS H_GET_32
  202: #endif
  203: #ifndef PUT_SCNHDR_FLAGS
  204: #define PUT_SCNHDR_FLAGS H_PUT_32
  205: #endif
  206: 
  207: #ifndef GET_RELOC_VADDR
  208: #define GET_RELOC_VADDR H_GET_32
  209: #endif
  210: #ifndef PUT_RELOC_VADDR
  211: #define PUT_RELOC_VADDR H_PUT_32
  212: #endif
  213: 
  214: #ifndef NO_COFF_RELOCS
  215: 
  216: static void
  217: coff_swap_reloc_in (bfd * abfd, void * src, void * dst)
  218: {
  219:   RELOC *reloc_src = (RELOC *) src;
  220:   struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
  221: 
  222:   reloc_dst->r_vaddr  = GET_RELOC_VADDR (abfd, reloc_src->r_vaddr);
  223:   reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx);
  224:   reloc_dst->r_type   = H_GET_16 (abfd, reloc_src->r_type);
  225: 
  226: #ifdef SWAP_IN_RELOC_OFFSET
  227:   reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET (abfd, reloc_src->r_offset);
  228: #endif
  229: }
  230: 
  231: static unsigned int
  232: coff_swap_reloc_out (bfd * abfd, void * src, void * dst)
  233: {
  234:   struct internal_reloc *reloc_src = (struct internal_reloc *) src;
  235:   struct external_reloc *reloc_dst = (struct external_reloc *) dst;
  236: 
  237:   PUT_RELOC_VADDR (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
  238:   H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
  239:   H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
  240: 
  241: #ifdef SWAP_OUT_RELOC_OFFSET
  242:   SWAP_OUT_RELOC_OFFSET (abfd, reloc_src->r_offset, reloc_dst->r_offset);
  243: #endif
  244: #ifdef SWAP_OUT_RELOC_EXTRA
  245:   SWAP_OUT_RELOC_EXTRA (abfd, reloc_src, reloc_dst);
  246: #endif
  247: 
  248:   return bfd_coff_relsz (abfd);
  249: }
  250: 
  251: #endif /* NO_COFF_RELOCS */
  252: 
  253: static void
  254: coff_swap_filehdr_in (bfd * abfd, void * src, void * dst)
  255: {
  256:   FILHDR *filehdr_src = (FILHDR *) src;
  257:   struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
  258: 
  259: #ifdef COFF_ADJUST_FILEHDR_IN_PRE
  260:   COFF_ADJUST_FILEHDR_IN_PRE (abfd, src, dst);
  261: #endif
  262:   filehdr_dst->f_magic  = H_GET_16 (abfd, filehdr_src->f_magic);
  263:   filehdr_dst->f_nscns  = H_GET_16 (abfd, filehdr_src->f_nscns);
  264:   filehdr_dst->f_timdat = H_GET_32 (abfd, filehdr_src->f_timdat);
  265:   filehdr_dst->f_symptr = GET_FILEHDR_SYMPTR (abfd, filehdr_src->f_symptr);
  266:   filehdr_dst->f_nsyms  = H_GET_32 (abfd, filehdr_src->f_nsyms);
  267:   filehdr_dst->f_opthdr = H_GET_16 (abfd, filehdr_src->f_opthdr);
  268:   filehdr_dst->f_flags  = H_GET_16 (abfd, filehdr_src->f_flags);
  269: #ifdef TIC80_TARGET_ID
  270:   filehdr_dst->f_target_id = H_GET_16 (abfd, filehdr_src->f_target_id);
  271: #endif
  272: 
  273: #ifdef COFF_ADJUST_FILEHDR_IN_POST
  274:   COFF_ADJUST_FILEHDR_IN_POST (abfd, src, dst);
  275: #endif
  276: }
  277: 
  278: static  unsigned int
  279: coff_swap_filehdr_out (bfd *abfd, void * in, void * out)
  280: {
  281:   struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
  282:   FILHDR *filehdr_out = (FILHDR *) out;
  283: 
  284: #ifdef COFF_ADJUST_FILEHDR_OUT_PRE
  285:   COFF_ADJUST_FILEHDR_OUT_PRE (abfd, in, out);
  286: #endif
  287:   H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
  288:   H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
  289:   H_PUT_32 (abfd, filehdr_in->f_timdat, filehdr_out->f_timdat);
  290:   PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr, filehdr_out->f_symptr);
  291:   H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
  292:   H_PUT_16 (abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr);
  293:   H_PUT_16 (abfd, filehdr_in->f_flags, filehdr_out->f_flags);
  294: #ifdef TIC80_TARGET_ID
  295:   H_PUT_16 (abfd, filehdr_in->f_target_id, filehdr_out->f_target_id);
  296: #endif
  297: 
  298: #ifdef COFF_ADJUST_FILEHDR_OUT_POST
  299:   COFF_ADJUST_FILEHDR_OUT_POST (abfd, in, out);
  300: #endif
  301:   return bfd_coff_filhsz (abfd);
  302: }
  303: 
  304: #ifndef NO_COFF_SYMBOLS
  305: 
  306: static void
  307: coff_swap_sym_in (bfd * abfd, void * ext1, void * in1)
  308: {
  309:   SYMENT *ext = (SYMENT *) ext1;
  310:   struct internal_syment *in = (struct internal_syment *) in1;
  311: 
  312:   if (ext->e.e_name[0] == 0)
  313:     {
  314:       in->_n._n_n._n_zeroes = 0;
  315:       in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset);
  316:     }
  317:   else
  318:     {
  319: #if SYMNMLEN != E_SYMNMLEN
  320: #error we need to cope with truncating or extending SYMNMLEN
  321: #else
  322:       memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
  323: #endif
  324:     }
  325: 
  326:   in->n_value = H_GET_32 (abfd, ext->e_value);
  327:   in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
  328:   if (sizeof (ext->e_type) == 2)
  329:     in->n_type = H_GET_16 (abfd, ext->e_type);
  330:   else
  331:     in->n_type = H_GET_32 (abfd, ext->e_type);
  332:   in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
  333:   in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
  334: #ifdef COFF_ADJUST_SYM_IN_POST
  335:   COFF_ADJUST_SYM_IN_POST (abfd, ext1, in1);
  336: #endif
  337: }
  338: 
  339: static unsigned int
  340: coff_swap_sym_out (bfd * abfd, void * inp, void * extp)
  341: {
  342:   struct internal_syment *in = (struct internal_syment *) inp;
  343:   SYMENT *ext =(SYMENT *) extp;
  344: 
  345: #ifdef COFF_ADJUST_SYM_OUT_PRE
  346:   COFF_ADJUST_SYM_OUT_PRE (abfd, inp, extp);
  347: #endif
  348: 
  349:   if (in->_n._n_name[0] == 0)
  350:     {
  351:       H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
  352:       H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
  353:     }
  354:   else
  355:     {
  356: #if SYMNMLEN != E_SYMNMLEN
  357: #error we need to cope with truncating or extending SYMNMLEN
  358: #else
  359:       memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);
  360: #endif
  361:     }
  362: 
  363:   H_PUT_32 (abfd, in->n_value, ext->e_value);
  364:   H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
  365: 
  366:   if (sizeof (ext->e_type) == 2)
  367:     H_PUT_16 (abfd, in->n_type, ext->e_type);
  368:   else
  369:     H_PUT_32 (abfd, in->n_type, ext->e_type);
  370: 
  371:   H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
  372:   H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
  373: 
  374: #ifdef COFF_ADJUST_SYM_OUT_POST
  375:   COFF_ADJUST_SYM_OUT_POST (abfd, inp, extp);
  376: #endif
  377: 
  378:   return SYMESZ;
  379: }
  380: 
  381: static void
  382: coff_swap_aux_in (bfd *abfd,
  383:                   void * ext1,
  384:                   int type,
  385:                   int class,
  386:                   int indx,
  387:                   int numaux,
  388:                   void * in1)
  389: {
  390:   AUXENT *ext = (AUXENT *) ext1;
  391:   union internal_auxent *in = (union internal_auxent *) in1;
  392: 
  393: #ifdef COFF_ADJUST_AUX_IN_PRE
  394:   COFF_ADJUST_AUX_IN_PRE (abfd, ext1, type, class, indx, numaux, in1);
  395: #endif
  396: 
  397:   switch (class)
  398:     {
  399:     case C_FILE:
  400:       if (ext->x_file.x_fname[0] == 0)
  401:         {
  402:           in->x_file.x_n.x_zeroes = 0;
  403:           in->x_file.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
  404:         }
  405:       else
  406:         {
  407: #if FILNMLEN != E_FILNMLEN
  408: #error we need to cope with truncating or extending FILNMLEN
  409: #else
  410:           if (numaux > 1)
  411:             {
  412:               if (indx == 0)
  413:                 memcpy (in->x_file.x_fname, ext->x_file.x_fname,
  414:                         numaux * sizeof (AUXENT));
  415:             }
  416:           else
  417:             memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
  418: #endif
  419:         }
  420:       goto end;
  421: 
  422:     case C_STAT:
  423: #ifdef C_LEAFSTAT
  424:     case C_LEAFSTAT:
  425: #endif
  426:     case C_HIDDEN:
  427:       if (type == T_NULL)
  428:         {
  429:           in->x_scn.x_scnlen = GET_SCN_SCNLEN (abfd, ext);
  430:           in->x_scn.x_nreloc = GET_SCN_NRELOC (abfd, ext);
  431:           in->x_scn.x_nlinno = GET_SCN_NLINNO (abfd, ext);
  432: 
  433:           /* PE defines some extra fields; we zero them out for
  434:              safety.  */
  435:           in->x_scn.x_checksum = 0;
  436:           in->x_scn.x_associated = 0;
  437:           in->x_scn.x_comdat = 0;
  438: 
  439:           goto end;
  440:         }
  441:       break;
  442:     }
  443: 
  444:   in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
  445: #ifndef NO_TVNDX
  446:   in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
  447: #endif
  448: 
  449:   if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
  450:     {
  451:       in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
  452:       in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
  453:     }
  454:   else
  455:     {
  456: #if DIMNUM != E_DIMNUM
  457: #error we need to cope with truncating or extending DIMNUM
  458: #endif
  459:       in->x_sym.x_fcnary.x_ary.x_dimen[0] =
  460:         H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
  461:       in->x_sym.x_fcnary.x_ary.x_dimen[1] =
  462:         H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
  463:       in->x_sym.x_fcnary.x_ary.x_dimen[2] =
  464:         H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
  465:       in->x_sym.x_fcnary.x_ary.x_dimen[3] =
  466:         H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
  467:     }
  468: 
  469:   if (ISFCN (type))
  470:     in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, ext->x_sym.x_misc.x_fsize);
  471:   else
  472:     {
  473:       in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO (abfd, ext);
  474:       in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE (abfd, ext);
  475:     }
  476: 
  477:  end: ;
  478: 
  479: #ifdef COFF_ADJUST_AUX_IN_POST
  480:   COFF_ADJUST_AUX_IN_POST (abfd, ext1, type, class, indx, numaux, in1);
  481: #endif
  482: }
  483: 
  484: static unsigned int
  485: coff_swap_aux_out (bfd * abfd,
  486:                    void * inp,
  487:                    int type,
  488:                    int class,
  489:                    int indx