srconv.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,032 行 · 第 1/3 页

C
2,032
字号
/* srconv.c -- Sysroff conversion program   Copyright 1994, 1995, 1996, 1998, 1999, 2000   Free Software Foundation, Inc.   This file is part of GNU Binutils.   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., 59 Temple Place - Suite 330, Boston, MA   02111-1307, USA.  *//* Written by Steve Chamberlain (sac@cygnus.com)   This program can be used to convert a coff object file   into a Hitachi OM/LM (Sysroff) format.   All debugging information is preserved */#include <bfd.h>#include "bucomm.h"#include "sysroff.h"#include "coffgrok.h"#include <libiberty.h>#include <getopt.h>#include "coff/internal.h"#include "../bfd/libcoff.h"#define PROGRAM_VERSION "1.5"/*#define FOOP1 1 */static int addrsize;static char *toolname;static char **rnames;static void wr_cs ();static void walk_tree_scope ();static void wr_globals ();static int find_base ();static FILE *file;static bfd *abfd;static int debug = 0;static int quick = 0;static int noprescan = 0;static struct coff_ofile *tree;/* Obsolete ??    static int absolute_p; */static int segmented_p;static int code;static int ids1[20000];static int ids2[20000];static int base1 = 0x18;static int base2 = 0x2018;static intget_member_id (x)     int x;{  if (ids2[x])    {      return ids2[x];    }  ids2[x] = base2++;  return ids2[x];}static intget_ordinary_id (x)     int x;{  if (ids1[x])    {      return ids1[x];    }  ids1[x] = base1++;  return ids1[x];}static char *section_translate (n)     char *n;{  if (strcmp (n, ".text") == 0)    return "P";  if (strcmp (n, ".data") == 0)    return "D";  if (strcmp (n, ".bss") == 0)    return "B";  return n;}#define DATE "940201073000";	/* Just a time on my birthday */staticchar *strip_suffix (name)     char *name;{  int i;  char *res;  for (i = 0; name[i] != 0 && name[i] != '.'; i++)    ;  res = (char *) xmalloc (i + 1);  memcpy (res, name, i);  res[i] = 0;  return res;}/* IT LEN stuff CS */static voidchecksum (file, ptr, size, code)     FILE *file;     char *ptr;     int size;     int code;{  int j;  int last;  int sum = 0;  int bytes = size / 8;  last = !(code & 0xff00);  if (size & 0x7)    abort ();  ptr[0] = code | (last ? 0x80 : 0);  ptr[1] = bytes + 1;  for (j = 0; j < bytes; j++)    {      sum += ptr[j];    }  /* Glue on a checksum too */  ptr[bytes] = ~sum;  fwrite (ptr, bytes + 1, 1, file);}static voidwriteINT (n, ptr, idx, size, file)     int n;     char *ptr;     int *idx;     int size;     FILE *file;{  int byte = *idx / 8;  if (size == -2)    size = addrsize;  else if (size == -1)    size = 0;  if (byte > 240)    {      /* Lets write out that record and do another one */      checksum (file, ptr, *idx, code | 0x1000);      *idx = 16;      byte = *idx / 8;    }  switch (size)    {    case 0:      break;    case 1:      ptr[byte] = n;      break;    case 2:      ptr[byte + 0] = n >> 8;      ptr[byte + 1] = n;      break;    case 4:      ptr[byte + 0] = n >> 24;      ptr[byte + 1] = n >> 16;      ptr[byte + 2] = n >> 8;      ptr[byte + 3] = n >> 0;      break;    default:      abort ();    }  *idx += size * 8;}static voidwriteBITS (val, ptr, idx, size)     int val;     char *ptr;     int *idx;     int size;{  int byte = *idx / 8;  int bit = *idx % 8;  int old;  *idx += size;  old = ptr[byte];  /* Turn off all about to change bits */  old &= ~((~0 >> (8 - bit - size)) & ((1 << size) - 1));  /* Turn on the bits we want */  old |= (val & ((1 << size) - 1)) << (8 - bit - size);  ptr[byte] = old;}static voidwriteBARRAY (data, ptr, idx, size, file)     barray data;     char *ptr;     int *idx;     int size ATTRIBUTE_UNUSED;     FILE *file;{  int i;  writeINT (data.len, ptr, idx, 1, file);  for (i = 0; i < data.len; i++)    {      writeINT (data.data[i], ptr, idx, 1, file);    }}static voidwriteCHARS (string, ptr, idx, size, file)     char *string;     char *ptr;     int *idx;     int size;     FILE *file;{  int i = *idx / 8;  if (i > 240)    {      /* Lets write out that record and do another one */      checksum (file, ptr, *idx, code | 0x1000);      *idx = 16;      i = *idx / 8;    }  if (size == 0)    {      /* Variable length string */      size = strlen (string);      ptr[i++] = size;    }  /* BUG WAITING TO HAPPEN */  memcpy (ptr + i, string, size);  i += size;  *idx = i * 8;}#define SYSROFF_SWAP_OUT#include "sysroff.c"static char *rname_sh[] ={  "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"};static char *rname_h8300[] ={  "ER0", "ER1", "ER2", "ER3", "ER4", "ER5", "ER6", "ER7", "PC", "CCR"};static voidwr_tr (){  /* The TR block is not normal - it doesn't have any contents. */  static char b[] = {    0xff,			/* IT */    0x03,			/* RL */    0xfd,			/* CS */  };  fwrite (b, 1, sizeof (b), file);}static voidwr_un (ptr, sfile, first, nsecs)     struct coff_ofile *ptr;     struct coff_sfile *sfile;     int first;     int nsecs ATTRIBUTE_UNUSED;{  struct IT_un un;  struct coff_symbol *s;  un.spare1 = 0;  if (bfd_get_file_flags (abfd) & EXEC_P)    un.format = FORMAT_LM;  else    un.format = FORMAT_OM;  un.spare1 = 0;#if 1  un.nsections = ptr->nsections - 1;	/*  Don't count the abs section */#else  /*NEW - only count sections with size */  un.nsections = nsecs;#endif  un.nextdefs = 0;  un.nextrefs = 0;  /* Count all the undefined and defined variables with global scope */  if (first)    {      for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list)	{	  if (s->visible->type == coff_vis_ext_def	      || s->visible->type == coff_vis_common)	    un.nextdefs++;	  if (s->visible->type == coff_vis_ext_ref)	    un.nextrefs++;	}    }  un.tool = toolname;  un.tcd = DATE;  un.linker = "L_GX00";  un.lcd = DATE;  un.name = sfile->name;  sysroff_swap_un_out (file, &un);}static voidwr_hd (p)     struct coff_ofile *p;{  struct IT_hd hd;  hd.spare1 = 0;  if (bfd_get_file_flags (abfd) & EXEC_P)    {      hd.mt = MTYPE_ABS_LM;    }  else    {      hd.mt = MTYPE_OMS_OR_LMS;    }  hd.cd = DATE;  hd.nu = p->nsources;		/* Always one unit */  hd.code = 0;			/* Always ASCII */  hd.ver = "0200";		/* Version 2.00 */  switch (bfd_get_arch (abfd))    {    case bfd_arch_h8300:      hd.au = 8;      hd.si = 0;      hd.spcsz = 32;      hd.segsz = 0;      hd.segsh = 0;      switch (bfd_get_mach (abfd))	{	case bfd_mach_h8300:	  hd.cpu = "H8300";	  hd.afl = 2;	  addrsize = 2;	  toolname = "C_H8/300";	  break;	case bfd_mach_h8300h:	  hd.cpu = "H8300H";	  hd.afl = 4;	  addrsize = 4;	  toolname = "C_H8/300H";	  break;	case bfd_mach_h8300s:	  hd.cpu = "H8300S";	  hd.afl = 4;	  addrsize = 4;	  toolname = "C_H8/300S";	  break;	default:	  abort();	}      rnames = rname_h8300;      break;    case bfd_arch_sh:      hd.au = 8;      hd.si = 0;      hd.afl = 4;      hd.spcsz = 32;      hd.segsz = 0;      hd.segsh = 0;      hd.cpu = "SH";      addrsize = 4;      toolname = "C_SH";      rnames = rname_sh;      break;    default:      abort ();    }  if (! bfd_get_file_flags(abfd) & EXEC_P)    {      hd.ep = 0;    }  else    {      hd.ep = 1;      hd.uan = 0;      hd.sa = 0;      hd.sad = 0;      hd.address = bfd_get_start_address (abfd);    }  hd.os = "";  hd.sys = "";  hd.mn = strip_suffix (bfd_get_filename (abfd));  sysroff_swap_hd_out (file, &hd);}static voidwr_sh (p, sec)     struct coff_ofile *p ATTRIBUTE_UNUSED;     struct coff_section *sec;{  struct IT_sh sh;  sh.unit = 0;  sh.section = sec->number;#ifdef FOOP1  sh.section = 0;#endif  sysroff_swap_sh_out (file, &sh);}static voidwr_ob (p, section)     struct coff_ofile *p ATTRIBUTE_UNUSED;     struct coff_section *section;{  bfd_size_type i;  int first = 1;  unsigned char stuff[200];  i = 0;  while (i < section->bfd_section->_raw_size)    {      struct IT_ob ob;      int todo = 200;		/* Copy in 200 byte lumps */      ob.spare = 0;      if (i + todo > section->bfd_section->_raw_size)	todo = section->bfd_section->_raw_size - i;      if (first)	{	  ob.saf = 1;	  if (bfd_get_file_flags (abfd) & EXEC_P)	    ob.address = section->address;	  else	    ob.address = 0;	  first = 0;	}      else	{	  ob.saf = 0;	}      ob.cpf = 0;		/* Never compress */      ob.data.len = todo;      bfd_get_section_contents (abfd, section->bfd_section, stuff, i, todo);      ob.data.data = stuff;      sysroff_swap_ob_out (file, &ob /*, i + todo < section->size */ );      i += todo;    }  /* Now fill the rest with blanks */  while (i < (bfd_size_type) section->size)    {      struct IT_ob ob;      int todo = 200;		/* Copy in 200 byte lumps */      ob.spare = 0;      if (i + todo > (bfd_size_type) section->size)	todo = section->size - i;      ob.saf = 0;      ob.cpf = 0;		/* Never compress */      ob.data.len = todo;      memset (stuff, 0, todo);      ob.data.data = stuff;      sysroff_swap_ob_out (file, &ob);      i += todo;    }  /* Now fill the rest with blanks */}static voidwr_rl (ptr, sec)     struct coff_ofile *ptr ATTRIBUTE_UNUSED;     struct coff_section *sec;{  int nr = sec->nrelocs;  int i;  for (i = 0; i < nr; i++)    {      struct coff_reloc *r = sec->relocs + i;      struct coff_symbol *ref;      struct IT_rl rl;      rl.apol = 0;      rl.boundary = 0;      rl.segment = 1;      rl.sign = 0;      rl.check = 0;      rl.addr = r->offset;      rl.bitloc = 0;      rl.flen = 32;		/* SH Specific */      /* What sort of reloc ? Look in the section to find out */      ref = r->symbol;      if (ref->visible->type == coff_vis_ext_ref)	{	  rl.bcount = 4;	/* Always 4 for us */	  rl.op = OP_EXT_REF;	  rl.symn = ref->er_number;	}      else if (ref->visible->type == coff_vis_common)	{	  rl.bcount = 11;	/* Always 11 for us */	  rl.op = OP_SEC_REF;	  rl.secn = ref->where->section->number;	  rl.copcode_is_3 = 3;	  rl.alength_is_4 = 4;	  rl.addend = ref->where->offset - ref->where->section->address;	  rl.aopcode_is_0x20 = 0x20;	}      else	{	  rl.bcount = 11;	/* Always 11 for us */	  rl.op = OP_SEC_REF;	  rl.secn = ref->where->section->number;	  rl.copcode_is_3 = 3;	  rl.alength_is_4 = 4;	  rl.addend = -ref->where->section->address;	  rl.aopcode_is_0x20 = 0x20;	}      rl.end = 0xff;      if (rl.op == OP_SEC_REF	  || rl.op == OP_EXT_REF)	{	  sysroff_swap_rl_out (file, &rl);	}    }}static voidwr_object_body (p)     struct coff_ofile *p;{  int i;  for (i = 1; i < p->nsections; i++)    {      wr_sh (p, p->sections + i);      wr_ob (p, p->sections + i);      wr_rl (p, p->sections + i);    }}static voidwr_dps_start (sfile, section, scope, type, nest)     struct coff_sfile *sfile;     struct coff_section *section ATTRIBUTE_UNUSED;     struct coff_scope *scope;     int type;     int nest;{  struct IT_dps dps;  dps.end = 0;  dps.opt = 0;  dps.type = type;  if (scope->sec)    {      dps.san = scope->sec->number;      dps.address = scope->offset - find_base (sfile, scope->sec);      dps.block_size = scope->size;      if (debug)	{	  printf ("DPS %s %d %x\n",		  sfile->name,		  nest,		  dps.address);	}    }  else    {      dps.san = 0;      dps.address = 0;      dps.block_size = 0;    }  dps.nesting = nest;  dps.neg = 0x1001;  sysroff_swap_dps_out (file, &dps);}static voidwr_dps_end (section, scope, type)     struct coff_section *section ATTRIBUTE_UNUSED;     struct coff_scope *scope ATTRIBUTE_UNUSED;     int type;{  struct IT_dps dps;  dps.end = 1;  dps.type = type;  sysroff_swap_dps_out (file, &dps);}static int *nints (x)     int x;{  return (int *) (xcalloc (sizeof (int), x));}static void walk_tree_symbol ();static voidwalk_tree_type_1 (sfile, symbol, type, nest)     struct coff_sfile *sfile;     struct coff_symbol *symbol;     struct coff_type *type;     int nest;{  switch (type->type)    {    case coff_secdef_type:    case coff_basic_type:      {	struct IT_dbt dbt;	switch (type->u.basic)	  {	  case T_NULL:	  case T_VOID:	    dbt.btype = BTYPE_VOID;	    dbt.sign = BTYPE_UNSPEC;	    dbt.fptype = FPTYPE_NOTSPEC;	    break;	  case T_CHAR:	    dbt.btype = BTYPE_CHAR;	    dbt.sign = BTYPE_UNSPEC;	    dbt.fptype = FPTYPE_NOTSPEC;	    break;	  case T_SHORT:	  case T_INT:	  case T_LONG:	    dbt.btype = BTYPE_INT;	    dbt.sign = SIGN_SIGNED;	    dbt.fptype = FPTYPE_NOTSPEC;	    break;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?