srconv.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,032 行 · 第 1/3 页
C
2,032 行
}#else dus.drb[0] = 0; dus.fname[0] = sfile->name;#endif sysroff_swap_dus_out (file, &dus);}/* Find the offset of the .text section for this sfile in the .text section for the output file */static intfind_base (sfile, section) struct coff_sfile *sfile; struct coff_section *section;{ return sfile->section[section->number].low;}static voidwr_dln (p, sfile, n) struct coff_ofile *p ATTRIBUTE_UNUSED; struct coff_sfile *sfile; int n ATTRIBUTE_UNUSED;{#if 0 if (n == 0) { /* Count up all the linenumbers */ struct coff_symbol *sy; int lc = 0; struct IT_dln dln; int idx; for (sy = p->symbol_list_head; sy; sy = sy->next_in_ofile_list) { struct coff_type *t = sy->type; if (t->type == coff_function_type) { struct coff_line *l = t->u.function.lines; lc += l->nlines; } } dln.sfn = nints (lc); dln.sln = nints (lc); dln.lln = nints (lc); dln.section = nints (lc); dln.from_address = nints (lc); dln.to_address = nints (lc); dln.neg = 0x1001; dln.nln = lc; /* Run through once more and fill up the structure */ idx = 0; for (sy = p->symbol_list_head; sy; sy = sy->next_in_ofile_list) { if (sy->type->type == coff_function_type) { int i; struct coff_line *l = sy->type->u.function.lines; for (i = 0; i < l->nlines; i++) { dln.section[idx] = sy->where->section->number; dln.sfn[idx] = n; dln.sln[idx] = l->lines[i]; dln.from_address[idx] = l->addresses[i]; if (idx) dln.to_address[idx - 1] = dln.from_address[idx]; idx++; } } n++; } sysroff_swap_dln_out (file, &dln); }#endif#if 1 /* Count up all the linenumbers */ struct coff_symbol *sy; int lc = 0; struct IT_dln dln; int idx; for (sy = sfile->scope->vars_head; sy; sy = sy->next) { struct coff_type *t = sy->type; if (t->type == coff_function_type) { struct coff_line *l = t->u.function.lines; if (l) lc += l->nlines; } } dln.sfn = nints (lc); dln.sln = nints (lc); dln.cc = nints (lc); dln.section = nints (lc); dln.from_address = nints (lc); dln.to_address = nints (lc); dln.neg = 0x1001; dln.nln = lc; /* Run through once more and fill up the structure */ idx = 0; for (sy = sfile->scope->vars_head; sy; sy = sy->next) { if (sy->type->type == coff_function_type) { int i; struct coff_line *l = sy->type->u.function.lines; if (l) { int base = find_base (sfile, sy->where->section); for (i = 0; i < l->nlines; i++) { dln.section[idx] = sy->where->section->number; dln.sfn[idx] = 0; dln.sln[idx] = l->lines[i]; dln.from_address[idx] = l->addresses[i] + sy->where->section->address - base; dln.cc[idx] = 0; if (idx) dln.to_address[idx - 1] = dln.from_address[idx]; idx++; } dln.to_address[idx - 1] = dln.from_address[idx - 1] + 2; } } } if (lc) sysroff_swap_dln_out (file, &dln);#endif}/* Write the global symbols out to the debug info */static voidwr_globals (p, sfile, n) struct coff_ofile *p; struct coff_sfile *sfile; int n ATTRIBUTE_UNUSED;{ struct coff_symbol *sy; for (sy = p->symbol_list_head; sy; sy = sy->next_in_ofile_list) { if (sy->visible->type == coff_vis_ext_def || sy->visible->type == coff_vis_ext_ref) { /* Only write out symbols if they belong to the current source file */ if (sy->sfile == sfile) walk_tree_symbol (sfile, 0, sy, 0); } }}static voidwr_debug (p) struct coff_ofile *p;{ struct coff_sfile *sfile; int n = 0; for (sfile = p->source_head; sfile; sfile = sfile->next) { if (debug) { printf ("%s\n", sfile->name); } wr_du (p, sfile, n); wr_dus (p, sfile); wr_program_structure (p, sfile); wr_dln (p, sfile, n); n++; }}static voidwr_cs (){ /* It seems that the CS struct is not normal - the size is wrong heres one I prepared earlier.. */ static char b[] = { 0x80, /* IT */ 0x21, /* RL */ 0x00, /* number of chars in variable length part */ 0x80, /* hd */ 0x00, /* hs */ 0x80, /* un */ 0x00, /* us */ 0x80, /* sc */ 0x00, /* ss */ 0x80, /* er */ 0x80, /* ed */ 0x80, /* sh */ 0x80, /* ob */ 0x80, /* rl */ 0x80, /* du */ 0x80, /* dps */ 0x80, /* dsy */ 0x80, /* dty */ 0x80, /* dln */ 0x80, /* dso */ 0x80, /* dus */ 0x00, /* dss */ 0x80, /* dbt */ 0x00, /* dpp */ 0x80, /* dfp */ 0x80, /* den */ 0x80, /* dds */ 0x80, /* dar */ 0x80, /* dpt */ 0x00, /* dul */ 0x00, /* dse */ 0x00, /* dot */ 0xDE /* CS */ }; fwrite (b, 1, sizeof (b), file);}/* Write out the SC records for a unit. Create an SC for all the sections which appear in the output file, even if there isn't an equivalent one on the input */static intwr_sc (ptr, sfile) struct coff_ofile *ptr; struct coff_sfile *sfile;{ int i;int scount = 0; /* First work out the total number of sections */ int total_sec = ptr->nsections; struct myinfo { struct coff_section *sec; struct coff_symbol *symbol; }; struct coff_symbol *symbol; struct myinfo *info = (struct myinfo *) calloc (total_sec, sizeof (struct myinfo)); for (i = 0; i < total_sec; i++) { info[i].sec = ptr->sections + i; info[i].symbol = 0; } for (symbol = sfile->scope->vars_head; symbol; symbol = symbol->next) { if (symbol->type->type == coff_secdef_type) { for (i = 0; i < total_sec; i++) { if (symbol->where->section == info[i].sec) { info[i].symbol = symbol; break; } } } } /* Now output all the section info, and fake up some stuff for sections we don't have */ for (i = 1; i < total_sec; i++) { struct IT_sc sc; char *name; symbol = info[i].symbol; sc.spare = 0; sc.spare1 = 0; if (!symbol) { /* Don't have a symbol set aside for this section, which means that nothing in this file does anything for the section. */ sc.format = !(bfd_get_file_flags (abfd) & EXEC_P); sc.addr = 0; sc.length = 0; name = info[i].sec->name; } else { if (bfd_get_file_flags (abfd) & EXEC_P) { sc.format = 0; sc.addr = symbol->where->offset; } else { sc.format = 1; sc.addr = 0; } sc.length = symbol->type->size; name = symbol->name; } sc.align = 4; sc.concat = CONCAT_SIMPLE; sc.read = 3; sc.write = 3; sc.exec = 3; sc.init = 3; sc.mode = 3; sc.spare = 0; sc.segadd = 0; sc.spare1 = 0; /* If not zero, then it doesn't work */ sc.name = section_translate (name); if (strlen (sc.name) == 1) { switch (sc.name[0]) { case 'D': case 'B': sc.contents = CONTENTS_DATA; break; default: sc.contents = CONTENTS_CODE; } } else { sc.contents = CONTENTS_CODE; }#if 0 /* NEW */ if (sc.length) {#endif sysroff_swap_sc_out (file, &sc); scount++;#if 0 }#endif }return scount;}/* Write out the ER records for a unit. */static voidwr_er (ptr, sfile, first) struct coff_ofile *ptr; struct coff_sfile *sfile ATTRIBUTE_UNUSED; int first;{ int idx = 0; struct coff_symbol *sym; if (first) { for (sym = ptr->symbol_list_head; sym; sym = sym->next_in_ofile_list) { if (sym->visible->type == coff_vis_ext_ref) { struct IT_er er; er.spare = 0; er.type = ER_NOTSPEC; er.name = sym->name; sysroff_swap_er_out (file, &er); sym->er_number = idx++; } } }}/* Write out the ED records for a unit. */static voidwr_ed (ptr, sfile, first) struct coff_ofile *ptr; struct coff_sfile *sfile ATTRIBUTE_UNUSED; int first;{ struct coff_symbol *s; 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) { struct IT_ed ed; ed.section = s->where->section->number; ed.spare = 0; if (s->where->section->data) { ed.type = ED_TYPE_DATA; } else if (s->where->section->code & SEC_CODE) { ed.type = ED_TYPE_ENTRY; } else { ed.type = ED_TYPE_NOTSPEC; ed.type = ED_TYPE_DATA; } ed.address = s->where->offset - s->where->section->address; ed.name = s->name; sysroff_swap_ed_out (file, &ed); } } }}static voidwr_unit_info (ptr) struct coff_ofile *ptr;{ struct coff_sfile *sfile; int first = 1; for (sfile = ptr->source_head; sfile; sfile = sfile->next) { long p1; long p2; int nsecs; p1 = ftell (file); wr_un (ptr, sfile, first, 0); nsecs = wr_sc (ptr, sfile); p2 = ftell (file); fseek (file, p1, SEEK_SET); wr_un (ptr, sfile, first, nsecs); fseek (file, p2, SEEK_SET); wr_er (ptr, sfile, first); wr_ed (ptr, sfile, first); first = 0; }}static voidwr_module (p) struct coff_ofile *p;{ wr_cs (); wr_hd (p); wr_unit_info (p); wr_object_body (p); wr_debug (p); wr_tr ();}static intalign (x) int x;{ return (x + 3) & ~3;}/* Find all the common variables and turn them into ordinary defs - dunno why, but thats what hitachi does with 'em */static voidprescan (tree) struct coff_ofile *tree;{ struct coff_symbol *s; struct coff_section *common_section; /* Find the common section - always section 3 */ common_section = tree->sections + 3; for (s = tree->symbol_list_head; s; s = s->next_in_ofile_list) { if (s->visible->type == coff_vis_common) { struct coff_where *w = s->where; /* s->visible->type = coff_vis_ext_def; leave it as common */ common_section->size = align (common_section->size); w->offset = common_section->size + common_section->address; w->section = common_section; common_section->size += s->type->size; common_section->size = align (common_section->size); } }}char *program_name;static voidshow_usage (file, status) FILE *file; int status;{ fprintf (file, _("Usage: %s [-dhVq] in-file [out-file]\n"), program_name); exit (status);}static voidshow_help (){ printf (_("%s: Convert a COFF object file into a SYSROFF object file\n"), program_name); show_usage (stdout, 0);}intmain (ac, av) int ac; char *av[];{ int opt; static struct option long_options[] = { {"debug", no_argument, 0, 'd'}, {"quick", no_argument, 0, 'q'}, {"noprescan", no_argument, 0, 'n'}, {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, {NULL, no_argument, 0, 0} }; char **matching; char *input_file; char *output_file;#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) setlocale (LC_MESSAGES, "");#endif bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); program_name = av[0]; xmalloc_set_program_name (program_name); while ((opt = getopt_long (ac, av, "dhVqn", long_options, (int *) NULL)) != EOF) { switch (opt) { case 'q': quick = 1; break; case 'n': noprescan = 1; break; case 'd': debug = 1; break; case 'h': show_help (); /*NOTREACHED */ case 'V': printf (_("GNU %s version %s\n"), program_name, PROGRAM_VERSION); exit (0); /*NOTREACHED */ case 0: break; default: show_usage (stderr, 1); /*NOTREACHED */ } } /* The input and output files may be named on the command line. */ output_file = NULL; if (optind < ac) { input_file = av[optind]; ++optind; if (optind < ac) { output_file = av[optind]; ++optind; if (optind < ac) show_usage (stderr, 1); if (strcmp (input_file, output_file) == 0) { fatal (_("input and output files must be different")); } } } else input_file = 0; if (!input_file) { fatal (_("no input file specified")); } if (!output_file) { /* Take a .o off the input file and stick on a .obj. If it doesn't end in .o, then stick a .obj on anyway */ int len = strlen (input_file); output_file = xmalloc (len + 5); strcpy (output_file, input_file); if (len > 3 && output_file[len - 2] == '.' && output_file[len - 1] == 'o') { output_file[len] = 'b'; output_file[len + 1] = 'j'; output_file[len + 2] = 0; } else { strcat (output_file, ".obj"); } } abfd = bfd_openr (input_file, 0); if (!abfd) bfd_fatal (input_file); if (!bfd_check_format_matches (abfd, bfd_object, &matching)) { bfd_nonfatal (input_file); if (bfd_get_error () == bfd_error_file_ambiguously_recognized) { list_matching_formats (matching); free (matching); } exit (1); } file = fopen (output_file, FOPEN_WB); if (!file) { fatal (_("unable to open output file %s"), output_file); } if (debug) printf ("ids %d %d\n", base1, base2); tree = coff_grok (abfd); if (!noprescan) prescan (tree); wr_module (tree); return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?