home *** CD-ROM | disk | FTP | other *** search
- #!/bin/sh -f
- # Generate a source code listing for C or C++ code with assembler code. The
- # listing is always written to stdout.
- # Author: Igor Metz <metz@iam.unibe.ch>
-
- # Revision 1.4 94/08/26 13:58:27 coxs <coxs@dg-rtp.dg.com>
- # lister now guesses how to should be configured. Added elf and coff support.
- #
- # Revision 1.3 89/12/18 13:58:27 metz
- # lister must now be configured before it can be used. This is done in the
- # /bin/sh part of the code.
- #
- #
- # Revision 1.2 89/08/16 17:35:02 metz
- # Support for SPARC added.
- #
- # Revision 1.1 89/08/16 16:49:22 metz
- # Initial revision
- #
-
- # Requires: gawk (may be it works also with nawk)
-
- # usage: lister filename [compiler-options]
-
- # Method:
- # compile the source with -g option to assembler code, then merge the
- # generated assembler code with the source code. Compiler options
- # can be supplied on the command line (for example -O)
-
- # To install lister, assign one of the supported values to the variable MYSYS:
- # mc68020 for Motorola 68020 (Sun-3, ..)
- # mc68030 for Motorola 68030 (Sun-3, ..)
- # sparc for SPARC (SUN-4, ..)
- # i386 for i386 (Sun i386, ...)
- # i386-linux for i386 (Linux, ...)
-
- # Guess what kind of objects we are creating and thus what type of assembler
- # symbols to look for
-
- ex /tmp/$$.c <<END >/dev/null
- a
- main (){}
- .
- w
- q
- END
- WD=`pwd`
- cd /tmp
- gcc -c $$.c
- case "`file $$.o`" in
- *ELF*) MYSYS=elf ;;
- *COFF*|*BCS*) MYSYS=coff ;;
- *mc68k*|*M68000*) MYSYS=mc68030 ;;
- *SPARC*) MYSYS=sparc ;;
- *386*) MYSYS=i386 ;;
- esac
- rm $$.c $$.o
- cd $WD
-
- # uncomment the line you need if the above guesses incorrectly:
- # MYSYS=mc68020
- # MYSYS=mc68030
- # MYSYS=sparc
- # MYSYS=i386
- # MYSYS=i386-linux
- # MYSYS=`mach` # this will work on Suns with SunOS > 4.0.0
- # MYSYS=elf
- # MYSYS=coff
-
- WHOAMI=$0
- if [ $# -gt 0 ] ; then
- FILENAME=$1
- shift
- fi
-
- exec gawk -v whoami=$WHOAMI -vsys=$MYSYS -voptions="$*" '
- # commandline arguments:
- # ARGV[0] = "gawk"
- # ARGV[1] = processid
- # ARGV[2] = filename
- BEGIN {
- if (ARGC != 3) {
- usage()
- exit 1
- }
-
- # Declaration of global variables
- c_filename = ""
- asm_filename = ""
- cmdline = ""
- asm_code = ""
- c_code = ""
- c_lineno = 0
- oldlineno = 0
- newlineno = 0
- ignore_stabd = 0
- num_of_fields = 0
-
- # check processor architecture and set sourcecode line_hint accordingly
- if (sys == "sparc" || sys == "i386") {
- line_hint = "^[ \t]*\.stabn.*"
- line_field = 3;
- line_delimiter = ",";
- line_offset = 0;
- }
- else if (sys == "mc68020" || sys == "mc68030" || sys == "i386-linux") {
- line_hint = "^[ \t]*\.stabd.*"
- line_field = 3;
- line_delimiter = ",";
- line_offset = 0;
- }
- else if (sys == "elf") {
- line_hint = "section.*\.line"
- line_field = 3;
- line_delimiter = "\t";
- line_offset = 0;
- }
- else if (sys == "coff") {
- line_hint = "^[ \t]*ln"
- line_field = 3;
- line_delimiter = "\t";
- }
- else {
- error("Processor type " sys " is not supported yet, sorry")
- }
-
- parse_cmdline()
-
- printf("compiling %s to asm code\n", c_filename ) > "/dev/stderr"
-
- if (system(cmdline) != 0 ) {
- error("Compilation of " c_filename " failed")
- }
-
- printf("generating listing\n") > "/dev/stderr"
-
-
- while ( getline asm_code < asm_filename > 0 ) {
- if ( (ignore_stabd==0) && (asm_code ~ line_hint)) {
- while ( sys == "elf" && (asm_code !~ "word" && asm_code !~ "byte") &&
- getline asm_code < asm_filename > 0);
- # source line hint found. Split the line into fields separated by commas.
- # num_of_fields is 4 for sparc, 3 for m68k
- num_of_fields = split(asm_code, fields, line_delimiter)
- newlineno = fields[line_field] + line_offset;
-
- if (newlineno > oldlineno) {
- while ( newlineno > c_lineno && getline c_code < c_filename > 0) {
- c_lineno++
- printf("%4d %s\n", c_lineno, c_code)
- }
- oldlineno = newlineno
- }
- }
- else if ( asm_code ~ ".*Ltext[ \t]*$" ) {
- # filename hint found
- if ( match(asm_code, c_filename)) {
- ignore_stabd = 0
- }
- else {
- ignore_stabd = 1
- }
- }
- else if ( sys == "elf" && asm_code ~ "section.*\.debug" ) {
- while ( asm_code !~ "^[ \t]*[.]*previous" &&
- asm_code !~ "\.popsection" &&
- getline asm_code < asm_filename > 0 );
- if ( ! (getline asm_code < asm_filename > 0)) break;
- }
- else if ( sys == "coff" && asm_code ~ "^[ \t]*sdef" ) {
- if ( asm_code ~ "\.bf" ) {
- while ( asm_code !~ "^[ \t]*line" &&
- getline asm_code < asm_filename > 0 ) {
- num_of_fields = split(asm_code, fields, "\t")
- line_offset = fields[line_field] - 1;
- }
- }
- while ( asm_code !~ "^[ \t]*endef" &&
- getline asm_code < asm_filename > 0 ) {
- }
- if ( ! (getline asm_code < asm_filename > 0)) break;
- }
- printf("\t\t\t%s\n", asm_code)
- }
-
- # general cleanup
- system("/bin/rm " asm_filename)
- }
-
- function usage() {
- printf("usage: %s filename compiler-options\n", whoami) > "/dev/stderr"
- }
-
- function error(s) {
- printf("error: %s\n", s) > "/dev/stderr"
- exit 1
- }
-
- function parse_cmdline( i) {
- # construct filenames to use
- asm_filename = "/tmp/lister" ARGV[1] ".s"
- ARGV[1] = ""
- c_filename = ARGV[2]
- ARGV[2] = ""
-
- # construct commandline to use
- if ( match(c_filename, ".C") || match(c_filename, ".cc") ) {
- cmdline = "g++"
- }
- else if (match(c_filename, ".c") || match(c_filename, ".i")) {
- cmdline = "gcc"
- }
- else {
- error("unknown extension for file " c_filename)
- }
-
- cmdline = cmdline " -g -S -o " asm_filename
-
- # now we append the compiler options specified by the user
- cmdline = cmdline " " options
-
- # last but not least: the name of the file to compile
- cmdline = cmdline " " c_filename
- }
-
- ' $$ $FILENAME
-
-