|
|
1.1 root 1: #!/bin/sh -f
2: # Generate a source code listing for C or C++ code with assembler code. The
3: # listing is always written to stdout.
4: # Author: Igor Metz <[email protected]>
5:
1.1.1.4 ! root 6: # Revision 1.4 94/08/26 13:58:27 coxs <[email protected]>
! 7: # lister now guesses how to should be configured. Added elf and coff support.
! 8: #
1.1 root 9: # Revision 1.3 89/12/18 13:58:27 metz
10: # lister must now be configured before it can be used. This is done in the
11: # /bin/sh part of the code.
12: #
13: #
14: # Revision 1.2 89/08/16 17:35:02 metz
15: # Support for SPARC added.
16: #
17: # Revision 1.1 89/08/16 16:49:22 metz
18: # Initial revision
19: #
20:
21: # Requires: gawk (may be it works also with nawk)
22:
23: # usage: lister filename [compiler-options]
24:
25: # Method:
26: # compile the source with -g option to assembler code, then merge the
27: # generated assembler code with the source code. Compiler options
28: # can be supplied on the command line (for example -O)
29:
30: # To install lister, assign one of the supported values to the variable MYSYS:
31: # mc68020 for Motorola 68020 (Sun-3, ..)
32: # mc68030 for Motorola 68030 (Sun-3, ..)
33: # sparc for SPARC (SUN-4, ..)
34: # i386 for i386 (Sun i386, ...)
1.1.1.3 root 35: # i386-linux for i386 (Linux, ...)
1.1 root 36:
1.1.1.4 ! root 37: # Guess what kind of objects we are creating and thus what type of assembler
! 38: # symbols to look for
! 39:
! 40: ex /tmp/$$.c <<END >/dev/null
! 41: a
! 42: main (){}
! 43: .
! 44: w
! 45: q
! 46: END
! 47: WD=`pwd`
! 48: cd /tmp
! 49: gcc -c $$.c
! 50: case "`file $$.o`" in
! 51: *ELF*) MYSYS=elf ;;
! 52: *COFF*|*BCS*) MYSYS=coff ;;
! 53: *mc68k*|*M68000*) MYSYS=mc68030 ;;
! 54: *SPARC*) MYSYS=sparc ;;
! 55: *386*) MYSYS=i386 ;;
! 56: esac
! 57: rm $$.c $$.o
! 58: cd $WD
! 59:
! 60: # uncomment the line you need if the above guesses incorrectly:
1.1 root 61: # MYSYS=mc68020
62: # MYSYS=mc68030
63: # MYSYS=sparc
64: # MYSYS=i386
1.1.1.3 root 65: # MYSYS=i386-linux
1.1 root 66: # MYSYS=`mach` # this will work on Suns with SunOS > 4.0.0
1.1.1.4 ! root 67: # MYSYS=elf
! 68: # MYSYS=coff
1.1 root 69:
1.1.1.4 ! root 70: WHOAMI=$0
! 71: if [ $# -gt 0 ] ; then
1.1.1.3 root 72: FILENAME=$1
73: shift
1.1.1.4 ! root 74: fi
1.1.1.3 root 75:
1.1.1.4 ! root 76: exec gawk -v whoami=$WHOAMI -vsys=$MYSYS -voptions="$*" '
1.1 root 77: # commandline arguments:
78: # ARGV[0] = "gawk"
79: # ARGV[1] = processid
80: # ARGV[2] = filename
81: BEGIN {
1.1.1.3 root 82: if (ARGC != 3) {
1.1 root 83: usage()
84: exit 1
85: }
86:
87: # Declaration of global variables
88: c_filename = ""
89: asm_filename = ""
90: cmdline = ""
91: asm_code = ""
92: c_code = ""
93: c_lineno = 0
94: oldlineno = 0
95: newlineno = 0
96: ignore_stabd = 0
97: num_of_fields = 0
98:
99: # check processor architecture and set sourcecode line_hint accordingly
100: if (sys == "sparc" || sys == "i386") {
101: line_hint = "^[ \t]*\.stabn.*"
1.1.1.4 ! root 102: line_field = 3;
! 103: line_delimiter = ",";
! 104: line_offset = 0;
1.1 root 105: }
1.1.1.3 root 106: else if (sys == "mc68020" || sys == "mc68030" || sys == "i386-linux") {
1.1 root 107: line_hint = "^[ \t]*\.stabd.*"
1.1.1.4 ! root 108: line_field = 3;
! 109: line_delimiter = ",";
! 110: line_offset = 0;
! 111: }
! 112: else if (sys == "elf") {
! 113: line_hint = "section.*\.line"
! 114: line_field = 3;
! 115: line_delimiter = "\t";
! 116: line_offset = 0;
! 117: }
! 118: else if (sys == "coff") {
! 119: line_hint = "^[ \t]*ln"
! 120: line_field = 3;
! 121: line_delimiter = "\t";
1.1 root 122: }
123: else {
124: error("Processor type " sys " is not supported yet, sorry")
125: }
126:
127: parse_cmdline()
128:
129: printf("compiling %s to asm code\n", c_filename ) > "/dev/stderr"
130:
131: if (system(cmdline) != 0 ) {
132: error("Compilation of " c_filename " failed")
133: }
134:
135: printf("generating listing\n") > "/dev/stderr"
136:
137:
138: while ( getline asm_code < asm_filename > 0 ) {
139: if ( (ignore_stabd==0) && (asm_code ~ line_hint)) {
1.1.1.4 ! root 140: while ( sys == "elf" && (asm_code !~ "word" && asm_code !~ "byte") &&
! 141: getline asm_code < asm_filename > 0);
1.1.1.2 root 142: # source line hint found. Split the line into fields separated by commas.
1.1 root 143: # num_of_fields is 4 for sparc, 3 for m68k
1.1.1.4 ! root 144: num_of_fields = split(asm_code, fields, line_delimiter)
! 145: newlineno = fields[line_field] + line_offset;
1.1 root 146:
147: if (newlineno > oldlineno) {
1.1.1.4 ! root 148: while ( newlineno > c_lineno && getline c_code < c_filename > 0) {
1.1 root 149: c_lineno++
150: printf("%4d %s\n", c_lineno, c_code)
151: }
152: oldlineno = newlineno
153: }
154: }
155: else if ( asm_code ~ ".*Ltext[ \t]*$" ) {
156: # filename hint found
157: if ( match(asm_code, c_filename)) {
158: ignore_stabd = 0
159: }
160: else {
161: ignore_stabd = 1
162: }
163: }
1.1.1.4 ! root 164: else if ( sys == "elf" && asm_code ~ "section.*\.debug" ) {
! 165: while ( asm_code !~ "^[ \t]*[.]*previous" &&
! 166: asm_code !~ "\.popsection" &&
! 167: getline asm_code < asm_filename > 0 );
! 168: if ( ! (getline asm_code < asm_filename > 0)) break;
! 169: }
! 170: else if ( sys == "coff" && asm_code ~ "^[ \t]*sdef" ) {
! 171: if ( asm_code ~ "\.bf" ) {
! 172: while ( asm_code !~ "^[ \t]*line" &&
! 173: getline asm_code < asm_filename > 0 ) {
! 174: num_of_fields = split(asm_code, fields, "\t")
! 175: line_offset = fields[line_field] - 1;
! 176: }
! 177: }
! 178: while ( asm_code !~ "^[ \t]*endef" &&
! 179: getline asm_code < asm_filename > 0 ) {
! 180: }
! 181: if ( ! (getline asm_code < asm_filename > 0)) break;
! 182: }
1.1 root 183: printf("\t\t\t%s\n", asm_code)
184: }
185:
186: # general cleanup
187: system("/bin/rm " asm_filename)
188: }
189:
190: function usage() {
1.1.1.4 ! root 191: printf("usage: %s filename compiler-options\n", whoami) > "/dev/stderr"
1.1 root 192: }
193:
194: function error(s) {
195: printf("error: %s\n", s) > "/dev/stderr"
196: exit 1
197: }
198:
199: function parse_cmdline( i) {
200: # construct filenames to use
201: asm_filename = "/tmp/lister" ARGV[1] ".s"
202: ARGV[1] = ""
203: c_filename = ARGV[2]
204: ARGV[2] = ""
205:
206: # construct commandline to use
207: if ( match(c_filename, ".C") || match(c_filename, ".cc") ) {
208: cmdline = "g++"
209: }
1.1.1.4 ! root 210: else if (match(c_filename, ".c") || match(c_filename, ".i")) {
1.1 root 211: cmdline = "gcc"
212: }
213: else {
214: error("unknown extension for file " c_filename)
215: }
216:
217: cmdline = cmdline " -g -S -o " asm_filename
218:
219: # now we append the compiler options specified by the user
1.1.1.3 root 220: cmdline = cmdline " " options
1.1 root 221:
222: # last but not least: the name of the file to compile
223: cmdline = cmdline " " c_filename
224: }
225:
1.1.1.3 root 226: ' $$ $FILENAME
227:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.