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 + -
显示快捷键?