#!/usr/bin/awk -f # arrays of arrays are support only after gawk v4.0 # arguments: m for module count, o for subobj count, d for debugging, f for the mapfile, t for segment(.text .rodata .data). # m: [0, 50], module count, can control the number of output primary goals(*.a/*.o). # o: if (m=0); then o=0;elif (m>0); then o=[0, 30]; fi,subobj count,can control the number of output secondary goals(*.o). # d: 0 or 1, control whether to printout Debugging Accumulation info. # f: mapfile to be processed. # t: ".text" ".rodata" ".data", segment type BEGIN { # Array element's sorted by value in descending order PROCINFO["sorted_in"] = "@val_num_desc" # Additional module moduleName["linker"] = "linker" } #1 extract loaded module name as in the leaf folder path #moduleName[module]=module=the module name /^LOAD/ { match($2, /\/[^\/]*\.[^\/]*$/) module = substr($2, RSTART+1) if (!moduleName[module]){ moduleName[module] = module #print "module="module " moduleName["module"]="moduleName[module] } } #2 extrac the .text, .rodata and .data totalsize the beginning of each interested section /^\..*0x.*0x/ { if ($1 == ".text" || $1 == ".rodata" || $1 == ".data" || $1 == ".rom"){ section = $1 sectionSize[$1] = strtonum($3) #print "section="section " sectionSize["section"]="sectionSize[$1] } else{ section = "" } next } #3 accumulate module(*.a/*.o) size and subobj(*.o) size in each interested section section && $0 ~ /.*[[:blank:]]0x.*[[:blank:]]0x/ { #print $0 #3.1 filter valid rows if (((NF == 4 && $1 ~ /^\./) || (NF == 3 && $1 ~ /^0x/ && strtonum($1) > 0)) && $0 !~ /.*\.mod\.o$/) { #print $0 match($NF, /\/[^\/]*\.[^\/\(]*\(/) #3.2 separater primary and secondary goals by filtering if (RSTART){ #3.3 separater secondary goals #print $0 curModule = substr($NF, RSTART+1, RLENGTH-2) match($NF, /\([^\(]*\.[^\(]*\)/) curSubObj = substr($NF, RSTART+1, RLENGTH-2) curSize = $(NF-1) #printf("%-30s%-50s%-26s\n", sprintf("curModule=%s", curModule), sprintf("curSubObj=%s", curSubObj), sprintf("curSize=%s", curSize)) } else{ #print $0 #3.4 separater primary goals match($NF, /\/[^\/]*\.[^\/\(]*$/) #print "NF="$NF" RSTART="RSTART if (RSTART) { curModule = substr($NF, RSTART+1, RLENGTH-1) curSize = $(NF-1) #printf("%-60s%-26s\n", sprintf("curModule=%s", curModule), sprintf("curSize=%s", curSize)) } else{ curModule = $NF curSize = $(NF-1) #print "section="section " curModule="curModule " curSize="curSize } curSubObj = "" } #3.5 use curModule curSubObj curSize to calculate the size of each primary and secondary goals, and store them in arrays #if (moduleName[curModule]) if ( 1 ) { accSize += strtonum(curSize) moduleSize[".total"][curModule] += strtonum(curSize) moduleSize[section][curModule] += strtonum(curSize) if (section == ".rodata") { textsize += strtonum(curSize) #print "moduleSize["section"]["curModule"]="moduleSize[section][curModule] " textsize="textsize } if (curSubObj){ subObjSize[curModule][".total"][curSubObj] += strtonum(curSize) subObjSize[curModule][section][curSubObj] += strtonum(curSize) isContainObj[curModule] = 1 } else { isContainObj[curModule] = 0 #directObjSize[curModule][".total"] += strtonum(curSize) #directObjSize[curModule][section] += strtonum(curSize) } } else { printf("module:\"%s\" Not Exist!\n", module) } } else{ #print $0 #3.6 calculate size of *fill* line if ($1 == "*fill*") { moduleSize[section]["*fill*"] += strtonum($NF) #print "section="section " "$0 " "$NF } else { #printf("NF[%d]:\"%s\" invalid!\n", NF, $0) } } } END { #4.1 parse params: m, o, d, f, t # Module count to have break-down analysis if (m > 50) MODULECOUNT = 50 else MODULECOUNT = m # Object counts in each interested module to have break-down analysis if (MODULECOUNT > 0) { if (o > 30) SUBOBJCOUNT = 30 else SUBOBJCOUNT = o } else { SUBOBJCOUNT = 0 } if ("X" != "X"f ) { SRCFILENAME = sprintf("THD_%s", f) } if (".text" == t || ".rodata" == t || ".data" == t) { SEGTYPE = t } # Code section @ ".rom" or ".text" if (sectionSize[".rom"]) codeSection = ".rom" else codeSection = ".text" #print "MODULECOUNT="MODULECOUNT " SUBOBJCOUNT="SUBOBJCOUNT " d="d #4.2 printout summary info include .text .rodata .data and total size totalSize = sectionSize[codeSection] + sectionSize[".rodata"] + sectionSize[".data"] #printf("#####################################################################################################\n") #printf("%-36s%16s%16s%16s%16s\n", "Module", ".total", codeSection, ".rodata", ".data") #printf("=====================================================================================================\n") # print out total and section size summary if("" == t) { printf("%-46s%16s%16s%16s%16s\n", SRCFILENAME, sprintf("0x%x",totalSize), sprintf("0x%x",sectionSize[codeSection]), sprintf("0x%x",sectionSize[".rodata"]), sprintf("0x%x",sectionSize[".data"])) } #4.3 printout the size of a certain segment if (SEGTYPE == ".text") { printf("0x%x\n",sectionSize[codeSection]) } else if (".rodata" == SEGTYPE) { printf("0x%x\n",sectionSize[".rodata"]) } else if (".data" == SEGTYPE) { printf("0x%x\n",sectionSize[".data"]) } #4.4 printout Debugging Accumulation info include .text .rodata .data and total size # if debugging option's on, print section accumuation size as well if (d){ sectionAccSize[".total"] = accSize for (section in sectionSize) { sectionAccSize[".total"] += moduleSize[section]["*fill*"] if (sectionSize[section]){ for (module in moduleSize[section]){ sectionAccSize[section] += moduleSize[section][module] } } } printf("%-36s%16s%16s%16s%16s\n", "Debugging Accumulation", sprintf("0x%x",sectionAccSize[".total"]), sprintf("0x%x",sectionAccSize[codeSection]), sprintf("0x%x",sectionAccSize[".rodata"]), sprintf("0x%x",sectionAccSize[".data"])) } #4.5 printout primary goals's total .text .rodata and .data size. #print out module size summary if (MODULECOUNT) { printf("=============================================Module_List=============================================\n") i = 0 #for循环依次取二级数组moduleSize[".total"]的二级下标 for (module in moduleSize[".total"]) { #print "module="module #print "moduleSize[.total]" printf("%-36.36s%16s%16s%16s%16s\n", sprintf("%s",module), sprintf("0x%x",moduleSize[".total"][module]), sprintf("0x%x",moduleSize[codeSection][module]), sprintf("0x%x",moduleSize[".rodata"][module]), sprintf("0x%x",moduleSize[".data"][module])) if (++i >= MODULECOUNT) break } } #4.6 printout secondary goals's total .text .rodata and .data size. if (SUBOBJCOUNT) { i = 0 for (module in moduleSize[".total"]) { #print "isContainObj["module"]="isContainObj[module] if (isContainObj[module] == 0) { continue } printf("=============================================SubObj_List=============================================\n") printf("%-36.36s%16s%16s%16s%16s\n", sprintf("%s",module), sprintf("0x%x",moduleSize[".total"][module]), sprintf("0x%x",moduleSize[codeSection][module]), sprintf("0x%x",moduleSize[".rodata"][module]), sprintf("0x%x",moduleSize[".data"][module])) j = 0 for (subObj in subObjSize[module][".total"]) { printf("%-36.36s%16s%16s%16s%16s\n", subObj, sprintf("0x%x",subObjSize[module][".total"][subObj]), sprintf("0x%x",subObjSize[module][codeSection][subObj]), sprintf("0x%x",subObjSize[module][".rodata"][subObj]), sprintf("0x%x",subObjSize[module][".data"][subObj])) if (++j >= SUBOBJCOUNT) break } if (++i >= MODULECOUNT) break } } #printf("#####################################################################################################\n") }