253 lines
7.9 KiB
Awk
253 lines
7.9 KiB
Awk
|
#!/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")
|
||
|
}
|
||
|
|