From e0fdc2088d297089b10849fe72800d5942763e95 Mon Sep 17 00:00:00 2001 From: iipeace Date: Mon, 10 Jun 2024 22:17:22 +0900 Subject: [PATCH] readelf: Support multiple files for input Signed-off-by: iipeace --- guider/guider.py | 105 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 25 deletions(-) diff --git a/guider/guider.py b/guider/guider.py index b5035947..300f3629 100755 --- a/guider/guider.py +++ b/guider/guider.py @@ -7,7 +7,7 @@ __credits__ = "Peace Lee" __license__ = "GPLv2" __version__ = "3.9.8" -__revision__ = "240608" +__revision__ = "240610" __maintainer__ = "Peace Lee" __email__ = "iipeace5@gmail.com" __repository__ = "https://github.com/iipeace/guider" @@ -15975,10 +15975,11 @@ def printMemoryArea( fname = UtilMgr.convOverlayPath(fname, overlayInfo) # add anon size # - if fname == " " and vma in amap and amap[vma]["size"]: - fname = "anon(%s)" % UtilMgr.convNum( - long(amap[vma]["size"]) << 10 - ) + rsize = amap.get(vma, {}).get("size", 0) + if rsize: + if fname == " ": + fname = "anon" + fname += " <%s>" % UtilMgr.convNum(long(rsize) << 10) SysMgr.printPipe( "%18s %18s %4s %8s %6s %12s %5s %s" @@ -40869,6 +40870,7 @@ def _getDesc(s, t=0): Examples: - {2:1} # {0:1} {1:1} {3:1} + # {0:1} {1:1} -I "/usr/lib/*.so" # {0:1} {1:1} -I test.zip # {0:1} {1:1} -I test.apk @@ -40884,6 +40886,9 @@ def _getDesc(s, t=0): - {2:1} with debug information # {0:1} {1:1} {3:1} -q DEBUGINFO + - {2:1} only for header + # {0:1} {1:1} {3:1} -q ONLYHEADER + - {2:1} with string sections # {0:1} {1:1} {3:1} -q PRINTSTR @@ -41323,9 +41328,14 @@ def _getDesc(s, t=0): - {2:1} and print process summary list finally # {0:1} {1:1} "a.out, java" -q SKIPDUP, PRINTLIST - - {2:1} and print duplicated stats for each memory segment + - {2:1} and print duplicated stats for each memory area # {0:1} {1:1} "a.out, java" -q PRINTDUPSTAT + - {2:1} and print duplicated chunk histogram for each memory area + # {0:1} {1:1} "a.out, java" -q PRINTDUPAREA + # {0:1} {1:1} "a.out, java" -q PRINTDUPAREA, INCALLBT:1 + # {0:1} {1:1} "a.out, java" -q PRINTDUPAREA, INCALLLT:1024 + - {2:1} only for specific size of areas # {0:1} {1:1} "a.out, java" -q PRINTDUPSTAT, CHUNKBT:1024000 # {0:1} {1:1} "a.out, java" -q PRINTDUPSTAT, CHUNKLT:8096000 @@ -53203,19 +53213,39 @@ def checkCmdMode(): # set debug flag # debug = not SysMgr.jsonEnable + onlyHdr = "ONLYHEADER" in SysMgr.environList + + def _printJson(path, obj): + if not SysMgr.jsonEnable: + return + jsonStr = UtilMgr.convDict2Str( + obj.attr, pretty=not SysMgr.streamEnable + ) + SysMgr.printPipe(('"%s": ' % path) + jsonStr) # run ELF analyzer # try: + # print vdso # if path == "vdso": obj = SysMgr.getVDSO(debug=debug) + _printJson(path, obj) else: - obj = ElfAnalyzer(path, debug, incArg=True) + # get path list # + pathList = path.split(",") + pathList = UtilMgr.getFileList(pathList) + if not pathList: + SysMgr.printErr("invalid path '%s'" % path) + sys.exit(-1) - if SysMgr.jsonEnable: - jsonStr = UtilMgr.convDict2Str( - obj.attr, pretty=not SysMgr.streamEnable - ) - SysMgr.printPipe(jsonStr) + # convert to hard-linked path set # + pathList = set(map(os.path.realpath, pathList)) + + # print items # + for p in pathList: + obj = ElfAnalyzer( + p, debug, onlyHdr=onlyHdr, incArg=True + ) + _printJson(p, obj) except SystemExit: sys.exit(0) except: @@ -60859,10 +60889,7 @@ def _printMemHist(mtable): # check zero chunk # if checkSingleChar and len(set(key)) == 1: - key = "(%s * %s)" % ( - key[0], - convNum(len(key)), - ) + key = "(%s * %s)" % (key[0], convNum(len(key))) else: # convert to string # key = repr(key).replace("\\x", "").strip("b'") @@ -61439,10 +61466,15 @@ def _isValidPage(pagemap, idx): for item in SysMgr.environList["MEMAREA"]: addMems.append(item.split("-")) - # get skip checkdup # + # get variables # onlyStat = "ONLYSTAT" in SysMgr.environList skipDup = "SKIPDUP" in SysMgr.environList - printDupStat = "PRINTDUPSTAT" in SysMgr.environList + printDupArea = "PRINTDUPAREA" in SysMgr.environList + if printDupArea: + printDupStat = True + checkSingleChar = True + else: + printDupStat = "PRINTDUPSTAT" in SysMgr.environList # get chunk info for processes # for pid in sorted(pids, key=lambda x: long(x)): @@ -61485,6 +61517,7 @@ def _isValidPage(pagemap, idx): # check duplicated memory # for idx, segment in enumerate(mems): + simpleMap = {} UtilMgr.printProgress(idx, len(mems)) try: @@ -61504,6 +61537,7 @@ def _isValidPage(pagemap, idx): % ", ".join(segment), True, ) + continue # check file filter # if skipFile: @@ -61613,9 +61647,14 @@ def _isValidPage(pagemap, idx): except: mergeTable[frame] = 1 + # save dup table # if printDupStat: dupMems[frame] = dupMems.get(frame, 0) + 1 + # save simple table # + if printDupArea: + simpleMap[frame] = simpleMap.get(frame, 0) + 1 + pos += PAGESIZE # merge allocs # else: @@ -61643,9 +61682,14 @@ def _isValidPage(pagemap, idx): except: mergeTable[mem] = 1 + # save dup table # if printDupStat: dupMems[mem] = dupMems.get(mem, 0) + 1 + # save simple table # + if printDupArea: + simpleMap[mem] = simpleMap.get(mem, 0) + 1 + # make commands # if SysMgr.customCmd: # convert START and SIZE values # @@ -61686,6 +61730,16 @@ def _isValidPage(pagemap, idx): ) ) + # print simple data # + if printDupArea: + SysMgr.printPipe( + "{5:1}\n{0:>20} {1:>12} {2:>7} {3:9} {4:1}".format( + " ", "Count", "Size", "Total", "Data", dotLine + ) + ) + _printMemHist(simpleMap) + SysMgr.printPipe(dotLine) + # execute commands # if cmds: dbgObj.executeCmd(cmds, force=True) @@ -61729,7 +61783,8 @@ def _isValidPage(pagemap, idx): # check result # if not mergeTable: - SysMgr.printErr("no memory area to be checked") + if not drawDupFlame: + SysMgr.printErr("no memory area to be checked") sys.exit(0) # calculate results # @@ -104493,7 +104548,6 @@ def _printer(item): oneLineLoc = oneLine[:maxLineLen] twoLineLoc = twoLine[:maxLineLen] - convNum = UtilMgr.convNum # structures # @@ -105985,13 +106039,14 @@ def _printStrSect(sh_name, strtab): return None # check debug option # - if not "DEBUGINFO" in SysMgr.environList or not SysMgr.dwarfEnable: + dbginfoList = SysMgr.environList.get("DEBUGINFO") + if not dbginfoList or not SysMgr.dwarfEnable: debuginfo = False - elif "DEBUGINFO" in SysMgr.environList: + elif dbginfoList: if ( - SysMgr.environList["DEBUGINFO"][0] == "SET" - or self.path in SysMgr.environList["DEBUGINFO"] - or origPath in SysMgr.environList["DEBUGINFO"] + dbginfoList[0] == "SET" + or self.path in dbginfoList + or origPath in dbginfoList ): debuginfo = True else: