Annotation of gcc/listing, revision 1.1.1.4

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.