1# Ben Myers <0003571400@mcimail.com> 2 3# Sum up segment sizes of all Windows EXEs in current directory 4# requires DOS 5.0 and Borland TDUMP 5# run with 6# awk -fwinexe.awk work1 7# where work1 is a work file 8# You must have at least one filename as an arg, else awk will want to read 9# from con:, hence the requirement for work1 10BEGIN { 11# redirection done by shelled command 12system("del workfile.$%$") # Will probably cause a File Not Found message 13# Generate a list of EXEs 14system("dir *.exe /b > workfile.$%$") 15while (getline < "workfile.$%$" > 0) { 16# TDUMP keeps on piping to the workfile 17system("tdump " $1 ">> " ARGV[1]) 18} 19module_name = "" # initialize 20# Now read workfile back, processing lines that: 21# 1. contain EXE file name 22# 2. contain segment type 23# Print EXE name and stats for each segment type processed 24# When there is a new EXE name, print summary for EXE just processed 25j = 1 26while (getline < ARGV[1] > 0) { 27# module name 28if($1 == "Display" && $2 == "of" && $3 == "File") { 29# Print program summary for all but last program 30if(module_name != "") { Print_Summary() } 31otcount = 0 # text segment counter 32odcount = 0 # data segment counter 33otsize = 0 # text size accumulator 34odsize = 0 # data size accumulator 35module_name = $4 } 36# File Size 37if($1 == "DOS" && $2 == "File" && $3 == "Size") { 38# 6+ digit file size with leading left paren 39DOS_Size = substr($5,2,7) 40# file size < 6 digits 41if(DOS_Size == 0 || DOS_Size == "") { DOS_Size = $6 } 42} 43# CODE segment 44if($1 == "Segment" && $2 == "Type:" && $3 =="CODE") { 45decval = hexdec(substr($7,1,4)) 46otsize += decval 47# printf ("%12s CODE %4s %7u\n", module_name, $7, decval) 48otcount++ } 49# DATA segment 50if($1 == "Segment" && $2 == "Type:" && $3 =="DATA") { 51decval = hexdec(substr($7,1,4)) 52odsize += decval 53# printf ("%12s DATA %4s %7u\n", module_name, $7, decval) 54odcount++ } 55} # while 56} # end of BEGIN section 57# no main loop at all! 58END { 59# print record for last program 60Print_Summary() 61# delete work files 62system("del "ARGV[1]) 63system("del workfile.$%$") 64} # end of END section 65 66# No scanf in awk, so convert hex string x to decimal the hard way 67function hexdec (x) { 68result = 0 69for (i=1; i<=length(x); i++) { 70thechar = substr(x,i,1) 71# digits 0-9 and lower case hex produced by TDUMP 72# use brute force 73if (thechar == "0") {result = result*16} 74if (thechar == "1") {result = result*16 + 1} 75if (thechar == "2") {result = result*16 + 2} 76if (thechar == "3") {result = result*16 + 3} 77if (thechar == "4") {result = result*16 + 4} 78if (thechar == "5") {result = result*16 + 5} 79if (thechar == "6") {result = result*16 + 6} 80if (thechar == "7") {result = result*16 + 7} 81if (thechar == "8") {result = result*16 + 8} 82if (thechar == "9") {result = result*16 + 9} 83if (thechar == "a") {result = result*16 + 10} 84if (thechar == "b") {result = result*16 + 11} 85if (thechar == "c") {result = result*16 + 12} 86if (thechar == "d") {result = result*16 + 13} 87if (thechar == "e") {result = result*16 + 14} 88if (thechar == "f") {result = result*16 + 15} 89if (thechar == "A") {result = result*16 + 10} 90if (thechar == "B") {result = result*16 + 11} 91if (thechar == "C") {result = result*16 + 12} 92if (thechar == "D") {result = result*16 + 13} 93if (thechar == "E") {result = result*16 + 14} 94if (thechar == "F") {result = result*16 + 15} 95} # for (i=1;i<length(x);i++) 96return result 97} # function hexdec (x) 98 99function Print_Summary () { 100# zero segment counts mean non-Windows EXE, so don't print 101if (otcount+otcount != 0) { 102printf ("%12s - %10.0f bytes\n", module_name, DOS_Size) 103printf ("%5.0f TEXT segments with %10.0f bytes\n", otcount, otsize) 104printf ("%5.0f DATA segments with %10.0f bytes\n", odcount, odsize) 105} 106} 107