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

binutils/2.18/binutils/srconv.c

    1: /* srconv.c -- Sysroff conversion program
    2:    Copyright 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
    3:    2005, 2007 Free Software Foundation, Inc.
    4: 
    5:    This file is part of GNU Binutils.
    6: 
    7:    This program is free software; you can redistribute it and/or modify
    8:    it under the terms of the GNU General Public License as published by
    9:    the Free Software Foundation; either version 3 of the License, or
   10:    (at your option) any later version.
   11: 
   12:    This program is distributed in the hope that it will be useful,
   13:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   14:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15:    GNU General Public License for more details.
   16: 
   17:    You should have received a copy of the GNU General Public License
   18:    along with this program; if not, write to the Free Software
   19:    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
   20:    02110-1301, USA.  */
   21: 
   22: /* Written by Steve Chamberlain (sac@cygnus.com)
   23: 
   24:    This program can be used to convert a coff object file
   25:    into a Hitachi OM/LM (Sysroff) format.
   26: 
   27:    All debugging information is preserved */
   28: 
   29: #include "sysdep.h"
   30: #include "bfd.h"
   31: #include "bucomm.h"
   32: #include "sysroff.h"
   33: #include "coffgrok.h"
   34: #include "libiberty.h"
   35: #include "getopt.h"
   36: 
   37: #include "coff/internal.h"
   38: #include "../bfd/libcoff.h"
   39: 
   40: /*#define FOOP1 1 */
   41: 
   42: static int addrsize;
   43: static char *toolname;
   44: static char **rnames;
   45: 
   46: static int get_member_id (int);
   47: static int get_ordinary_id (int);
   48: static char *section_translate (char *);
   49: static char *strip_suffix (const char *);
   50: static void checksum (FILE *, unsigned char *, int, int);
   51: static void writeINT (int, unsigned char *, int *, int, FILE *);
   52: static void writeBITS (int, unsigned char *, int *, int);
   53: static void writeBARRAY (barray, unsigned char *, int *, int, FILE *);
   54: static void writeCHARS (char *, unsigned char *, int *, int, FILE *);
   55: static void wr_tr (void);
   56: static void wr_un (struct coff_ofile *, struct coff_sfile *, int, int);
   57: static void wr_hd (struct coff_ofile *);
   58: static void wr_sh (struct coff_ofile *, struct coff_section *);
   59: static void wr_ob (struct coff_ofile *, struct coff_section *);
   60: static void wr_rl (struct coff_ofile *, struct coff_section *);
   61: static void wr_object_body (struct coff_ofile *);
   62: static void wr_dps_start
   63:   (struct coff_sfile *, struct coff_section *, struct coff_scope *, int, int);
   64: static void wr_dps_end (struct coff_section *, struct coff_scope *, int);
   65: static int *nints (int);
   66: static void walk_tree_type_1
   67:   (struct coff_sfile *, struct coff_symbol *, struct coff_type *, int);
   68: static void walk_tree_type
   69:   (struct coff_sfile *, struct coff_symbol *, struct coff_type *, int);
   70: static void walk_tree_symbol
   71:   (struct coff_sfile *, struct coff_section *, struct coff_symbol *, int);
   72: static void walk_tree_scope
   73:   (struct coff_section *, struct coff_sfile *, struct coff_scope *, int, int);
   74: static void walk_tree_sfile (struct coff_section *, struct coff_sfile *);
   75: static void wr_program_structure (struct coff_ofile *, struct coff_sfile *);
   76: static void wr_du (struct coff_ofile *, struct coff_sfile *, int);
   77: static void wr_dus (struct coff_ofile *, struct coff_sfile *);
   78: static int find_base (struct coff_sfile *, struct coff_section *);
   79: static void wr_dln (struct coff_ofile *, struct coff_sfile *, int);
   80: static void wr_globals (struct coff_ofile *, struct coff_sfile *, int);
   81: static void wr_debug (struct coff_ofile *);
   82: static void wr_cs (void);
   83: static int wr_sc (struct coff_ofile *, struct coff_sfile *);
   84: static void wr_er (struct coff_ofile *, struct coff_sfile *, int);
   85: static void wr_ed (struct coff_ofile *, struct coff_sfile *, int);
   86: static void wr_unit_info (struct coff_ofile *);
   87: static void wr_module (struct coff_ofile *);
   88: static int align (int);
   89: static void prescan (struct coff_ofile *);
   90: static void show_usage (FILE *, int);
   91: extern int main (int, char **);
   92: 
   93: static FILE *file;
   94: static bfd *abfd;
   95: static int debug = 0;
   96: static int quick = 0;
   97: static int noprescan = 0;
   98: static struct coff_ofile *tree;
   99: /* Obsolete ??
  100:    static int absolute_p;
  101:  */
  102: 
  103: static int segmented_p;
  104: static int code;
  105: 
  106: static int ids1[20000];
  107: static int ids2[20000];
  108: 
  109: static int base1 = 0x18;
  110: static int base2 = 0x2018;
  111: 
  112: static int
  113: get_member_id (int x)
  114: {
  115:   if (ids2[x])
  116:     return ids2[x];
  117: 
  118:   ids2[x] = base2++;
  119:   return ids2[x];
  120: }
  121: 
  122: static int
  123: get_ordinary_id (int x)
  124: {
  125:   if (ids1[x])
  126:     return ids1[x];
  127: 
  128:   ids1[x] = base1++;
  129:   return ids1[x];
  130: }
  131: static char *
  132: section_translate (char *n)
  133: {
  134:   if (strcmp (n, ".text") == 0)
  135:     return "P";
  136:   if (strcmp (n, ".data") == 0)
  137:     return "D";
  138:   if (strcmp (n, ".bss") == 0)
  139:     return "B";
  140:   return n;
  141: }
  142: 
  143: #define DATE "940201073000";    /* Just a time on my birthday */
  144: 
  145: static char *
  146: strip_suffix (const char *name)
  147: {
  148:   int i;
  149:   char *res;
  150: 
  151:   for (i = 0; name[i] != 0 && name[i] != '.'; i++)
  152:     ;
  153:   res = (char *) xmalloc (i + 1);
  154:   memcpy (res, name, i);
  155:   res[i] = 0;
  156:   return res;
  157: }
  158: 
  159: /* IT LEN stuff CS */
  160: static void
  161: checksum (FILE *file, unsigned char *ptr, int size, int code)
  162: {
  163:   int j;
  164:   int last;
  165:   int sum = 0;
  166:   int bytes = size / 8;
  167: 
  168:   last = !(code & 0xff00);
  169:   if (size & 0x7)
  170:     abort ();
  171:   ptr[0] = code | (last ? 0x80 : 0);
  172:   ptr[1] = bytes + 1;
  173: 
  174:   for (j = 0; j < bytes; j++)
  175:     sum += ptr[j];
  176: 
  177:   /* Glue on a checksum too.  */
  178:   ptr[bytes] = ~sum;
  179:   fwrite (ptr, bytes + 1, 1, file);
  180: }
  181: 
  182: 
  183: static void
  184: writeINT (int n, unsigned char *ptr, int *idx, int size, FILE *file)
  185: {
  186:   int byte = *idx / 8;
  187: 
  188:   if (size == -2)
  189:     size = addrsize;
  190:   else if (size == -1)
  191:     size = 0;
  192: 
  193:   if (byte > 240)
  194:     {
  195:       /* Lets write out that record and do another one.  */
  196:       checksum (file, ptr, *idx, code | 0x1000);
  197:       *idx = 16;
  198:       byte = *idx / 8;
  199:     }
  200: 
  201:   switch (size)
  202:     {
  203:     case 0:
  204:       break;
  205:     case 1:
  206:       ptr[byte] = n;
  207:       break;
  208:     case 2:
  209:       ptr[byte + 0] = n >> 8;
  210:       ptr[byte + 1] = n;
  211:       break;
  212:     case 4:
  213:       ptr[byte + 0] = n >> 24;
  214:       ptr[byte + 1] = n >> 16;
  215:       ptr[byte + 2] = n >> 8;
  216:       ptr[byte + 3] = n >> 0;
  217:       break;
  218:     default:
  219:       abort ();
  220:     }
  221:   *idx += size * 8;
  222: }
  223: 
  224: static void
  225: writeBITS (int val, unsigned char *ptr, int *idx, int size)
  226: {
  227:   int byte = *idx / 8;
  228:   int bit = *idx % 8;
  229:   int old;
  230: 
  231:   *idx += size;
  232: 
  233:   old = ptr[byte];
  234:   /* Turn off all about to change bits.  */
  235:   old &= ~((~0 >> (8 - bit - size)) & ((1 << size) - 1));
  236:   /* Turn on the bits we want.  */
  237:   old |= (val & ((1 << size) - 1)) << (8 - bit - size);
  238:   ptr[byte] = old;
  239: }
  240: 
  241: static void
  242: writeBARRAY (barray data, unsigned char *ptr, int *idx,
  243:              int size ATTRIBUTE_UNUSED, FILE *file)
  244: {
  245:   int i;
  246: 
  247:   writeINT (data.len, ptr, idx, 1, file);
  248:   for (i = 0; i < data.len; i++)
  249:     writeINT (data.data[i], ptr, idx, 1, file);
  250: }
  251: 
  252: static void
  253: writeCHARS (char *string, unsigned char *ptr, int *idx, int size, FILE *file)
  254: {
  255:   int i = *idx / 8;
  256: 
  257:   if (i > 240)
  258:     {
  259:       /* Lets write out that record and do another one.  */
  260:       checksum (file, ptr, *idx, code | 0x1000);
  261:       *idx = 16;
  262:       i = *idx / 8;
  263:     }
  264: 
  265:   if (size == 0)
  266:     {
  267:       /* Variable length string.  */
  268:       size = strlen (string);
  269:       ptr[i++] = size;
  270:     }
  271: 
  272:   /* BUG WAITING TO HAPPEN.  */
  273:   memcpy (ptr + i, string, size);
  274:   i += size;
  275:   *idx = i * 8;
  276: }
  277: 
  278: #define SYSROFF_SWAP_OUT
  279: #include "sysroff.c"
  280: 
  281: static char *rname_sh[] =
  282: {
  283:   "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"
  284: };
  285: 
  286: static char *rname_h8300[] =
  287: {
  288:   "ER0", "ER1", "ER2", "ER3", "ER4", "ER5", "ER6", "ER7", "PC", "CCR"
  289: };
  290: 
  291: static void
  292: wr_tr (void)
  293: {
  294:   /* The TR block is not normal - it doesn't have any contents.  */
  295: 
  296:   static char b[] =
  297:     {
  298:       0xff,                     /* IT */
  299:       0x03,                     /* RL */
  300:       0xfd,                     /* CS */
  301:     };
  302:   fwrite (b, 1, sizeof (b), file);
  303: }
  304: 
  305: static void
  306: wr_un (struct coff_ofile *ptr, struct coff_sfile *sfile, int first,
  307:        int nsecs ATTRIBUTE_UNUSED)
  308: {
  309:   struct IT_un un;
  310:   struct coff_symbol *s;
  311: 
  312:   un.spare1 = 0;
  313: 
  314:   if (bfd_get_file_flags (abfd) & EXEC_P)
  315:     un.format = FORMAT_LM;
  316:   else
  317:     un.format = FORMAT_OM;
  318:   un.spare1 = 0;
  319: 
  320:   /* Don't count the abs section.  */
  321:   un.nsections = ptr->nsections - 1;
  322: 
  323:   un.nextdefs = 0;
  324:   un.nextrefs = 0;
  325:   /* Count all the undefined and defined variables with global scope.  */
  326: 
  327:   if (first)
  328:     {
  329:       for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list)
  330:         {
  331:           if (s->visible->type == coff_vis_ext_def
  332:               || s->visible->type == coff_vis_common)
  333:             un.nextdefs++;
  334: 
  335:           if (s->visible->type == coff_vis_ext_ref)
  336:             un.nextrefs++;
  337:         }
  338:     }
  339:   un.tool = toolname;
  340:   un.tcd = DATE;
  341:   un.linker = "L_GX00";
  342:   un.lcd = DATE;
  343:   un.name = sfile->name;
  344:   sysroff_swap_un_out (file, &un);
  345: }
  346: 
  347: static void
  348: wr_hd (struct coff_ofile *p)
  349: {
  350:   struct IT_hd hd;
  351: 
  352:   hd.spare1 = 0;
  353:   if (bfd_get_file_flags (abfd) & EXEC_P)
  354:     hd.mt = MTYPE_ABS_LM;
  355:   else
  356:     hd.mt = MTYPE_OMS_OR_LMS;
  357: 
  358:   hd.cd = DATE;
  359: 
  360:   hd.nu = p->nsources;          /* Always one unit */
  361:   hd.code = 0;                  /* Always ASCII */
  362:   hd.ver = "0200";              /* Version 2.00 */
  363: 
  364:   switch (bfd_get_arch (abfd))
  365:     {
  366:     case bfd_arch_h8300:
  367:       hd.au = 8;
  368:       hd.si = 0;
  369:       hd.spcsz = 32;
  370:       hd.segsz = 0;
  371:       hd.segsh = 0;
  372:       switch (bfd_get_mach (abfd))
  373:         {
  374:         case bfd_mach_h8300:
  375:           hd.cpu = "H8300";
  376:           hd.afl = 2;
  377:           addrsize = 2;
  378:           toolname = "C_H8/300";
  379:           break;
  380:         case bfd_mach_h8300h:
  381:           hd.cpu = "H8300H";
  382:           hd.afl = 4;
  383:           addrsize = 4;
  384:           toolname = "C_H8/300H";
  385:           break;
  386:         case bfd_mach_h8300s:
  387:           hd.cpu = "H8300S";
  388:           hd.afl = 4;
  389:           addrsize = 4;
  390:           toolname = "C_H8/300S";
  391:           break;
  392:         default:
  393:           abort();
  394:         }
  395:       rnames = rname_h8300;
  396:       break;
  397:     case bfd_arch_sh:
  398:       hd.au = 8;
  399:       hd.si = 0;
  400:       hd.afl = 4;
  401:       hd.spcsz = 32;
  402:       hd.segsz = 0;
  403:       hd.segsh = 0;
  404:       hd.cpu = "SH";
  405:       addrsize = 4;
  406:       toolname = "C_SH";
  407:       rnames = rname_sh;
  408:       break;
  409:     default:
  410:       abort ();
  411:     }
  412: 
  413:   if (! bfd_get_file_flags(abfd) & EXEC_P)
  414:     {
  415:       hd.ep = 0;
  416:     }
  417:   else
  418:     {
  419:       hd.ep = 1;
  420:       hd.uan = 0;
  421:       hd.sa = 0;
  422:       hd.sad = 0;
  423:       hd.address = bfd_get_start_address (abfd);
  424:     }
  425: 
  426:   hd.os = "";
  427:   hd.sys = "";
  428:   hd.mn = strip_suffix (bfd_get_filename (abfd));
  429: 
  430:   sysroff_swap_hd_out (file, &hd);
  431: }
  432: 
  433: 
  434: static void
  435: wr_sh (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_section *sec)
  436: {
  437:   struct IT_sh sh;
  438:   sh.unit = 0;
  439:   sh.section = sec->number;
  440: #ifdef FOOP1
  441:   sh.section = 0;
  442: #endif
  443:   sysroff_swap_sh_out (file, &sh);
  444: }
  445: 
  446: 
  447: static void
  448: wr_ob (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_section *section)
  449: {
  450:   bfd_size_type i;
  451:   int first = 1;
  452:   unsigned char stuff[200];
  453: 
  454:   i = 0;
  455:   while (i < bfd_get_section_size (section->bfd_section))
  456:     {
  457:       struct IT_ob ob;
  458:       int todo = 200;           /* Copy in 200 byte lumps.  */
  459: 
  460:       ob.spare = 0;
  461:       if (i + todo > bfd_get_section_size (section->bfd_section))
  462:         todo = bfd_get_section_size (section->bfd_section) - i;
  463: 
  464:       if (first)
  465:         {
  466:           ob.saf = 1;
  467:           if (bfd_get_file_flags (abfd) & EXEC_P)
  468:             ob.address = section->address;
  469:           else
  470:             ob.address = 0;
  471: 
  472:           first = 0;
  473:         }
  474:       else
  475:         {
  476:           ob.saf = 0;
  477:         }
  478: 
  479:       ob.cpf = 0;               /* Never compress.  */
  480:       ob.data.len = todo;
  481:       bfd_get_section_contents (abfd, section->bfd_section, stuff, i, todo);
  482:       ob.data.data = stuff;
  483:       sysroff_swap_ob_out (file, &ob /*, i + todo < section->size */ );
  484:       i += todo;
  485:     }
  486: 
  487:   /* Now fill the rest with blanks.  */
  488:   while (i < (bfd_size_type) section->size)
  489:     {
  490:       struct IT_ob ob;
  491:       int todo = 200;           /* Copy in 200 byte lumps.  */
  492: 
  493:       ob.spare = 0;
  494:       if (i + todo > (bfd_size_type) section->size)
  495:         todo = section->size - i;
  496:       ob.saf = 0;
  497: 
  498:       ob.cpf = 0;               /* Never compress.  */
  499:       ob.data.len = todo;
  500:       memset (stuff, 0, todo);
  501:       ob.data.data = stuff;
  502:       sysroff_swap_ob_out (file, &ob);
  503:       i += todo;
  504:     }
  505:   /* Now fill the rest with blanks.  */
  506: }
  507: 
  508: static void
  509: wr_rl (struct coff_ofile *ptr ATTRIBUTE_UNUSED, struct coff_section *sec)
  510: {
  511:   int nr = sec->nrelocs;
  512:   int i;
  513: 
  514:   for (i = 0; i < nr; i++)
  515:     {
  516:       struct coff_reloc *r = sec->relocs + i;
  517:       struct coff_symbol *ref;
  518:       struct IT_rl rl;
  519: 
  520:       rl.apol = 0;
  521:       rl.boundary = 0;
  522:       rl.segment = 1;
  523:       rl.sign = 0;
  524:       rl.check = 0;
  525:       rl.addr = r->offset;
  526:       rl.bitloc = 0;
  527:       rl.flen = 32;             /* SH Specific.  */
  528: 
  529:       /* What sort of reloc ? Look in the section to find out.  */
  530:       ref = r->symbol;
  531:       if (ref->visible->type == coff_vis_ext_ref)
  532:         {
  533:           rl.bcount = 4;       /* Always 4 for us.  */
  534:           rl.op = OP_EXT_REF;
  535:           rl.symn = ref->er_number;
  536:         }
  537:       else if (ref->visible->type == coff_vis_common)
  538:         {
  539:           rl.bcount = 11;      /* Always 11 for us.  */
  540:           rl.op = OP_SEC_REF;
  541:           rl.secn = ref->where->section->number;
  542:           rl.copcode_is_3 = 3;
  543:           rl.alength_is_4 = 4;
  544:           rl.addend = ref->where->offset - ref->where->section->address;
  545:           rl.aopcode_is_0x20 = 0x20;
  546:         }
  547:       else
  548:         {
  549:           rl.bcount = 11;      /* Always 11 for us.  */
  550:           rl.op = OP_SEC_REF;
  551:           rl.secn = ref->where->section->number;
  552: