diff --git a/binutils/.Sanitize b/binutils/.Sanitize index 6a600517d9..74b92ee699 100644 --- a/binutils/.Sanitize +++ b/binutils/.Sanitize @@ -51,9 +51,12 @@ binutils.texi bucomm.c bucomm.h c++filt.1 +coffdump.c +coffgrok.c +coffgrok.h +config configure.bat configure.in -config filemode.c gmalloc.c is-ranlib.c @@ -77,9 +80,14 @@ ranlib.sh sanity.sh size.1 size.c +srconv.c strings.1 strings.c strip.1 +sysdump.c +sysinfo.y +syslex.l +sysroff.info testsuite version.c diff --git a/binutils/ChangeLog b/binutils/ChangeLog index c84977e375..8f7f1da477 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,14 @@ +Tue Mar 8 13:14:43 1994 Steve Chamberlain (sac@jonny.cygnus.com) + + * coffgrok.[ch]: New files, understand coff objects. + * coffdump.c: Uses coffgrok to dump out the debug info of a coff + file. + * sysroff.info: Description of a SYSROFF object file. + * sysinfo.y, syslex.l: Parse info file, generate a reader, writer, + header files and a printer. + * srconv.c: Uses coffgrok.c and sysroff.info to convert a coff + file to a SYSROFF file. + Sat Feb 26 13:35:26 1994 Stan Shebs (shebs@andros.cygnus.com) * ar.c (do_quick_append): Pad with a genuine character 10, diff --git a/binutils/Makefile.in b/binutils/Makefile.in index 297044a95b..462d561540 100644 --- a/binutils/Makefile.in +++ b/binutils/Makefile.in @@ -64,7 +64,7 @@ NM_FOR_TARGET = nm NM = $(NM_FOR_TARGET) SYMLINK = ln -s -BISON = `if [ -f ../byacc/byacc ] ; then echo ../byacc/byacc ; else echo byacc ; fi` +BISON = `if [ -f ../bison/bison ] ; then echo ../bison/bison -y -L../bison/bison ; else echo bison -y ; fi` # Comment these out if using lex. LEX_OPTIONS = -I -Cem LEX = `if [ -f ../flex/flex ] ; then echo ../flex/flex ; else echo flex ; fi` @@ -102,7 +102,9 @@ DEMANGLER_PROG=c++filt NLMCONV_PROG=nlmconv -PROGS = $(SIZE_PROG) $(OBJDUMP_PROG) $(NM_PROG) $(AR_PROG) $(STRINGS_PROG) $(STRIP_PROG) $(RANLIB_PROG) $(DEMANGLER_PROG) $(OBJCOPY_PROG) $(BUILD_NLMCONV) +SRCONV_PROG=srconv sysdump coffdump + +PROGS = $(SIZE_PROG) $(OBJDUMP_PROG) $(NM_PROG) $(AR_PROG) $(STRINGS_PROG) $(STRIP_PROG) $(RANLIB_PROG) $(DEMANGLER_PROG) $(OBJCOPY_PROG) $(BUILD_NLMCONV) $(BUILD_SRCONV) STAGESTUFF = $(PROGS) *.o # Files that can be generated, but should be in the distribution. DISTSTUFF=arparse.c arlex.c nlmheader.c info @@ -154,16 +156,7 @@ FLAGS_TO_PASS = \ "CC=$(CC)" \ "CFLAGS=$(CFLAGS)" \ "RUNTEST=$(RUNTEST)" \ - "RUNTESTFLAGS=$(RUNTESTFLAGS) \ - SIZE=`if [ -f $$rootme/$(SIZE_PROG) ] ; then echo $$rootme/$(SIZE_PROG) ; else echo $(SIZE_PROG); fi` \ - OBJCOPY=`if [ -f $$rootme/$(OBJCOPY_PROG) ] ; then echo $$rootme/$(OBJCOPY_PROG) ; else echo $(OBJCOPY_PROG); fi` \ - NM=`if [ -f $$rootme/$(NM_PROG) ] ; then echo $$rootme/$(NM_PROG) ; else echo $(NM_PROG); fi` \ - AR=`if [ -f $$rootme/$(AR_PROG) ] ; then echo $$rootme/$(AR_PROG) ; else echo $(AR_PROG); fi` \ - OBJDUMP=`if [ -f $$rootme/$(OBJDUMP_PROG) ] ; then echo $$rootme/$(OBJDUMP_PROG) ; else echo $(OBJDUMP_PROG); fi` \ - STRINGS=`if [ -f $$rootme/$(STRINGS_PROG) ] ; then echo $$rootme/$(STRINGS_PROG) ; else echo $(STRINGS_PROG); fi` \ - STRIP=`if [ -f $$rootme/$(STRIP_PROG) ] ; then echo $$rootme/$(STRIP_PROG) ; else echo $(STRIP_PROG); fi` \ - RANLIB=`if [ -f $$rootme/$(RANLIB_PROG) ] ; then echo $$rootme/$(RANLIB_PROG) ; else echo $(RANLIB_PROG); fi` \ - DEMANGLE=`if [ -f $$rootme/$(DEMANGLER_PROG) ] ; then echo $$rootme/$(DEMANGLER_PROG) ; else echo $(DEMANGLER_PROG); fi`" + "RUNTESTFLAGS=$(RUNTESTFLAGS)" # ## The rules @@ -180,7 +173,6 @@ testsuite: check: force rootme=`pwd`; export rootme; cd testsuite ; \ $(MAKE) check $(FLAGS_TO_PASS) -# /bin/sh $(srcdir)/sanity.sh . installcheck: /bin/sh $(srcdir)/sanity.sh $(bindir) @@ -270,6 +262,35 @@ objcopy_with_strip: $(ADDL_LIBS) objcopy.o maybe-strip.o $(BFD) -rm -f $(STRIP_PROG) -ln $(OBJCOPY_PROG) $(STRIP_PROG) +sysroff.c: sysinfo sysroff.info + ./sysinfo -c <$(srcdir)/sysroff.info >sysroff.c + ./sysinfo -i <$(srcdir)/sysroff.info >>sysroff.c + ./sysinfo -g <$(srcdir)/sysroff.info >>sysroff.c + +sysroff.h: sysinfo sysroff.info + ./sysinfo -d <$(srcdir)/sysroff.info >sysroff.h + +sysinfo.c: sysinfo.y + $(BISON) -tvd $(srcdir)/sysinfo.y + rm -f sysinfo.c + -mv y.tab.c sysinfo.c + +syslex.c : syslex.l + $(LEX) $(LEX_OPTIONS) $(srcdir)/syslex.l + mv lex.yy.c syslex.c + +sysinfo: sysinfo.o syslex.o $(ADDL_LIBS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ sysinfo.o syslex.o $(ADDL_LIBS) $(EXTRALIBS) + +srconv: sysroff.c srconv.o sysroff.c sysroff.h coffgrok.o $(ADDL_LIBS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ srconv.o coffgrok.o $(ADDL_LIBS) $(EXTRALIBS) + +coffdump: coffdump.o coffgrok.o $(ADDL_LIBS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ coffdump.o coffgrok.o $(ADDL_LIBS) $(EXTRALIBS) + +sysdump: sysroff.h sysroff.c sysdump.o $(ADDL_LIBS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ sysdump.o $(ADDL_LIBS) $(EXTRALIBS) + nlmheader.c: nlmheader.y $(BISON) $(srcdir)/nlmheader.y rm -f nlmheader.c diff --git a/binutils/coffgrok.h b/binutils/coffgrok.h new file mode 100644 index 0000000000..e321217672 --- /dev/null +++ b/binutils/coffgrok.h @@ -0,0 +1,183 @@ +#define T_NULL 0 +#define T_VOID 1 /* function argument (only used by compiler) */ +#define T_CHAR 2 /* character */ +#define T_SHORT 3 /* short integer */ +#define T_INT 4 /* integer */ +#define T_LONG 5 /* long integer */ +#define T_FLOAT 6 /* floating point */ +#define T_DOUBLE 7 /* double word */ +#define T_STRUCT 8 /* structure */ +#define T_UNION 9 /* union */ +#define T_ENUM 10 /* enumeration */ +#define T_MOE 11 /* member of enumeration*/ +#define T_UCHAR 12 /* unsigned character */ +#define T_USHORT 13 /* unsigned short */ +#define T_UINT 14 /* unsigned integer */ +#define T_ULONG 15 /* unsigned long */ +#define T_LNGDBL 16 /* long double */ + + + struct coff_reloc + { + int offset; + struct coff_symbol *symbol; + int addend; + }; + + struct coff_section + { + char *name; + int code; + int data; + int address; + int number; /* 0..n, .text = 0 */ + int nrelocs; + int size; + struct coff_reloc *relocs; + struct sec *bfd_section; + }; + +struct coff_ofile +{ + int nsources; + struct coff_sfile *source_head; + struct coff_sfile *source_tail; + int nsections; + struct coff_section *sections; + struct coff_symbol *symbol_list_head; + struct coff_symbol *symbol_list_tail; +}; + + +struct coff_sfile +{ + char *name; + struct coff_scope *scope; + struct coff_sfile *next; + + +}; + + + struct coff_type +{ + int size; + enum + { + coff_pointer_type, coff_function_type, coff_array_type, coff_structdef_type, coff_basic_type, + coff_structref_type, coff_enumref_type, coff_enumdef_type + } type; + union + { + struct + { + int isstruct; + struct coff_scope *elements; + int idx; + } + astructdef; + struct + { + struct coff_symbol *ref; + } astructref; + + struct + { + struct coff_scope *elements; + int idx; + } aenumdef; + struct + { + struct coff_symbol *ref; + } aenumref; + + struct + { + struct coff_type *points_to; + } pointer; + struct + { + int dim; + struct coff_type *array_of; + } array; + + struct + { + struct coff_type *function_returns; + struct coff_scope *parameters; + struct coff_scope *code; + struct coff_line *lines; + } function; + int basic; /* One of T_VOID.. T_UINT */ + } u; +}; + + + struct coff_line + { + int nlines; + int *lines; + int *addresses; + }; + + + struct coff_scope + { + struct coff_scope *parent; /* one up */ + + struct coff_scope *next; /*next along */ + + int nvars; + struct coff_symbol *vars_head; /* symbols */ + struct coff_symbol *vars_tail; + + struct coff_scope *list_head; /* children */ + struct coff_scope *list_tail; + + }; + + + struct coff_visible + { + enum coff_vis_type + { + coff_vis_ext_def, + coff_vis_ext_ref, + coff_vis_int_def, + coff_vis_common, + coff_vis_auto, + coff_vis_register, + coff_vis_tag, + coff_vis_member_of_struct, + coff_vis_member_of_enum, + } type; + }; + + struct coff_where + { + enum + { + coff_where_stack, coff_where_memory, coff_where_register, coff_where_unknown, + coff_where_strtag, coff_where_member_of_struct, + coff_where_member_of_enum, coff_where_entag, coff_where_typedef + + } where; + int offset; + int bitoffset; + int bitsize; + struct coff_section *section; + }; + + struct coff_symbol + { + char *name; + int tag; + struct coff_type *type; + struct coff_where *where; + struct coff_visible *visible; + struct coff_symbol *next; + struct coff_symbol *next_in_ofile_list; /* For the ofile list */ + int number; + }; + +struct coff_ofile *coff_grok(); diff --git a/binutils/sysinfo.y b/binutils/sysinfo.y new file mode 100644 index 0000000000..d5f9c64756 --- /dev/null +++ b/binutils/sysinfo.y @@ -0,0 +1,426 @@ +%{ +extern char *word; +extern char writecode; +extern int number; +extern int unit; +char nice_name[1000]; +char *it; +int sofar; +int width; +int code; +char * repeat; +char *oldrepeat; +char *name; +int rdepth; +char *loop [] = {"","n","m","/*BAD*/"}; +char *names[] = {" ","[n]","[n][m]"}; +char *pnames[]= {"","*","**"}; +%} + + +%union { + int i; + char *s; +} +%token COND +%token REPEAT +%token '(' ')' '[' ']' +%token TYPE +%token NAME +%token NUMBER UNIT +%type attr_size +%type attr_desc attr_id attr_type +%% + +top: { + switch (writecode) + { + case 'i': + printf("#ifdef SYSROFF_SWAP_IN\n"); + break; + case 'p': + printf("#ifdef SYSROFF_p\n"); + break; + case 'd': + break; + case 'g': + printf("#ifdef SYSROFF_SWAP_OUT\n"); + break; + case 'c': + printf("#ifdef SYSROFF_PRINT\n"); + printf("#include \n"); + printf("#include \n"); + break; + } + } +it_list { + switch (writecode) { + case 'i': + case 'p': + case 'g': + case 'c': + printf("#endif\n"); + break; + case 'd': + break; + } +} + + ; + + +it_list: it it_list + | + ; + +it: + '(' NAME NUMBER + { + it = $2; code = $3; + switch (writecode) + { + case 'd': + printf("\n\n\n#define IT_%s_CODE 0x%x\n", it,code); + printf("struct IT_%s { \n", it); + break; + case 'i': + printf("void sysroff_swap_%s_in(ptr)\n",$2); + printf("struct IT_%s *ptr;\n", it); + printf("{\n"); + printf("char raw[255];\n"); + printf("\tint idx = 0 ;\n"); + printf("\tint size;\n"); + printf("memset(raw,0,255);\n"); + printf("memset(ptr,0,sizeof(*ptr));\n"); + printf("size = fillup(raw);\n"); + break; + case 'g': + printf("void sysroff_swap_%s_out(file,ptr,last)\n",$2); + printf("FILE * file;\n"); + printf("struct IT_%s *ptr;\n", it); + printf("int last;\n"); + printf("{\n"); + printf("\tchar raw[255];\n"); + printf("\tint idx = 16 ;\n"); + printf("\tmemset (raw, 0, 255);\n"); + printf("\tcode = IT_%s_CODE;\n", it); + break; + case 'o': + printf("void sysroff_swap_%s_out(abfd,ptr)\n",$2); + printf("bfd * abfd;\n"); + printf("struct IT_%s *ptr;\n",it); + printf("{\n"); + printf("int idx = 0 ;\n"); + break; + case 'c': + printf("void sysroff_print_%s_out(ptr)\n",$2); + printf("struct IT_%s *ptr;\n", it); + printf("{\n"); + printf("itheader(\"%s\", IT_%s_CODE);\n",$2,$2); + break; + + case 't': + break; + } + + } + it_field_list +')' +{ + switch (writecode) { + case 'd': + printf("};\n"); + break; + case 'g': + printf("\tchecksum(file,raw, idx, IT_%s_CODE, last);\n", it); + + case 'i': + + case 'o': + case 'c': + printf("}\n"); + } +} +; + + + +it_field_list: + it_field it_field_list + | cond_it_field it_field_list + | repeat_it_field it_field_list + | + ; + +repeat_it_field: '(' REPEAT NAME + { + rdepth++; + switch (writecode) + { + case 'c': + if (rdepth==1) + printf("\tprintf(\"repeat %%d\\n\", %s);\n",$3); + if (rdepth==2) + printf("\tprintf(\"repeat %%d\\n\", %s[n]);\n",$3); + case 'i': + case 'g': + case 'o': + + if (rdepth==1) + { + printf("\t{ int n; for (n = 0; n < %s; n++) {\n", $3); + } + if (rdepth == 2) { + printf("\t{ int m; for (m = 0; m < %s[n]; m++) {\n", $3); + } + + break; + } + + oldrepeat = repeat; + repeat = $3; + } + + it_field_list ')' + + { + repeat = oldrepeat; + oldrepeat =0; + rdepth--; + switch (writecode) + { + case 'i': + case 'g': + case 'o': + case 'c': + printf("\t}}\n"); + } + } + ; + + +cond_it_field: '(' COND NAME + { + switch (writecode) + { + case 'i': + case 'g': + case 'o': + case 'c': + printf("\tif (%s) {\n", $3); + break; + } + } + + it_field_list ')' + { + switch (writecode) + { + case 'i': + case 'g': + case 'o': + case 'c': + printf("\t}\n"); + } + } + ; + +it_field: + '(' attr_desc '(' attr_type attr_size ')' attr_id + {name = $7; } + enums ')' + { + char *desc = $2; + char *type = $4; + int size = $5; + char *id = $7; +char *p = names[rdepth]; +char *ptr = pnames[rdepth]; + switch (writecode) + { + case 'g': + if (size % 8) + { + + printf("\twriteBITS(ptr->%s%s,raw,&idx,%d);\n", + id, + names[rdepth], size); + + } + else { + printf("\twrite%s(ptr->%s%s,raw,&idx,%d,file);\n", + type, + id, + names[rdepth],size/8); + } + break; + case 'i': + { + + if (rdepth >= 1) + + { + printf("if (!ptr->%s) ptr->%s = (%s*)xcalloc(%s, sizeof(ptr->%s[0]));\n", + id, + id, + type, + repeat, + id); + } + + if (rdepth == 2) + { + printf("if (!ptr->%s[n]) ptr->%s[n] = (%s**)calloc(%s[n], sizeof(ptr->%s[n][0]));\n", + id, + id, + type, + repeat, + id); + } + + } + + if (size % 8) + { + printf("\tptr->%s%s = getBITS(raw,&idx, %d,size);\n", + id, + names[rdepth], + size); + } + else { + printf("\tptr->%s%s = get%s(raw,&idx, %d,size);\n", + id, + names[rdepth], + type, + size/8); + } + break; + case 'o': + printf("\tput%s(raw,%d,%d,&idx,ptr->%s%s);\n", type,size/8,size%8,id,names[rdepth]); + break; + case 'd': + if (repeat) + printf("\t/* repeat %s */\n", repeat); + + if (type[0] == 'I') { + printf("\tint %s%s; \t/* %s */\n",ptr,id, desc); + } + else if (type[0] =='C') { + printf("\tchar %s*%s;\t /* %s */\n",ptr,id, desc); + } + else { + printf("\tbarray %s%s;\t /* %s */\n",ptr,id, desc); + } + break; + case 'c': + printf("tabout();\n"); + printf("\tprintf(\"/*%-30s*/ ptr->%s = \");\n", desc, id); + + if (type[0] == 'I') + printf("\tprintf(\"%%d\\n\",ptr->%s%s);\n", id,p); + else if (type[0] == 'C') + printf("\tprintf(\"%%s\\n\",ptr->%s%s);\n", id,p); + + else if (type[0] == 'B') + { + printf("\tpbarray(&ptr->%s%s);\n", id,p); + } + else abort(); + break; + } + } + + ; + + +attr_type: + TYPE { $$ = $1; } + | { $$ = "INT";} + ; + +attr_desc: + '(' NAME ')' + { $$ = $2; } + ; + +attr_size: + NUMBER UNIT + { $$ = $1 * $2; } + ; + + +attr_id: + '(' NAME ')' { $$ = $2; } + | { $$ = "dummy";} + ; + +enums: + | '(' enum_list ')' ; + +enum_list: + | + enum_list '(' NAME NAME ')' { + switch (writecode) + { + case 'd': + printf("#define %s %s\n", $3,$4); + break; + case 'c': + printf("if (ptr->%s%s == %s) { tabout(); printf(\"%s\\n\");}\n", name, names[rdepth],$4,$3); + } + } + + ; + + + + +name: + NAME + { + printf("Got %s\n", word); + } + ; + + + + + + + +%% +/* four modes + + -d write structure defintions for sysroff in host format + -i write functions to swap into sysroff format in + -o write functions to swap into sysroff format out + -c write code to print info in human form */ + +#include +#include +int yydebug; +char writecode; + +int +main(ac,av) +int ac; +char **av; +{ + yydebug=0; + if (ac > 1) + writecode = av[1][1]; +if (writecode == 'd') + { + printf("typedef struct { unsigned char *data; int len; } barray; \n"); + printf("typedef int INT;\n"); + printf("typedef char * CHARS;\n"); + + } + yyparse(); +return 0; +} + +int yyerror() +{ + printf("Error twathead\n"); +}