-
Notifications
You must be signed in to change notification settings - Fork 92
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Debugger: Apply unwinding table compression
Signed-off-by: iipeace <[email protected]>
- Loading branch information
Showing
1 changed file
with
129 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ | |
__credits__ = "Peace Lee" | ||
__license__ = "GPLv2" | ||
__version__ = "3.9.8" | ||
__revision__ = "240526" | ||
__revision__ = "240527" | ||
__maintainer__ = "Peace Lee" | ||
__email__ = "[email protected]" | ||
__repository__ = "https://github.com/iipeace/guider" | ||
|
@@ -7005,6 +7005,30 @@ def ungzip(path): | |
gzip = SysMgr.getPkg("gzip") | ||
return gzip.open(path, "rb").read() | ||
|
||
@staticmethod | ||
def compObj(obj): | ||
try: | ||
return SysMgr.getPkg("zlib", False).compress( | ||
SysMgr.getPicklePkg(False).dumps(obj) | ||
) | ||
except SystemExit: | ||
sys.exit(0) | ||
except: | ||
SysMgr.printWarn("failed to compress object", reason=True) | ||
return obj | ||
|
||
@staticmethod | ||
def decompObj(obj): | ||
try: | ||
return SysMgr.getPicklePkg(False).loads( | ||
SysMgr.getPkg("zlib", False).decompress(obj) | ||
) | ||
except SystemExit: | ||
sys.exit(0) | ||
except: | ||
SysMgr.printWarn("failed to decompress object", reason=True) | ||
return obj | ||
|
||
@staticmethod | ||
def unzip(fd, name): | ||
# get pkg # | ||
|
@@ -12886,7 +12910,7 @@ def read_struct(self, structure, offset, platform64=None): | |
return structure._from_buffer_copy( | ||
raw, | ||
platform64=platform64 | ||
if platform64 != None | ||
if platform64 is not None | ||
else self.platform64, | ||
) | ||
else: | ||
|
@@ -12936,7 +12960,7 @@ def __len__(self): | |
return int(self.inode.i_size) | ||
|
||
def __repr__(self): | ||
if self.inode_idx != None: | ||
if self.inode_idx is not None: | ||
return ( | ||
"%s(inode_idx = %s, offset = 0x%X, volume_uuid = %s" | ||
) % ( | ||
|
@@ -13548,7 +13572,7 @@ def read_block(self, fileBlkIdx): | |
""" | ||
diskBlkIdx = self.get_block_mapping(fileBlkIdx) | ||
|
||
if diskBlkIdx != None: | ||
if diskBlkIdx is not None: | ||
return self.volume.read( | ||
diskBlkIdx * self.volume.block_size, | ||
self.volume.block_size, | ||
|
@@ -37025,6 +37049,9 @@ def printHelp(force=False, isExit=True): | |
# {0:1} {1:1} {2:1} -q DEBUGINFO -H | ||
# {0:1} {1:1} {2:1} -q DEBUGINFO:/usr/lib/libc.so | ||
|
||
- Use debug info without compression | ||
# {0:1} {1:1} {2:1} -q NODEBUGCOMP | ||
|
||
- Apply DWARF file filter | ||
# {0:1} {1:1} {2:1} -eD -q TARGETDWARF:"*deno" | ||
# {0:1} {1:1} {2:1} -eD -q EXCEPTDWARF:"*deno" | ||
|
@@ -57588,7 +57615,7 @@ def _enableSigPipe(): | |
break | ||
|
||
# check process status # | ||
if procObj.poll() != None: | ||
if procObj.poll() is not None: | ||
break | ||
|
||
SysMgr.printInfo("terminated '%s' for %s" % (value, addr)) | ||
|
@@ -65380,7 +65407,7 @@ def _waitAndKill(tobj, pid, comm, cond, sig, purpose, hookCmd=None): | |
utime = long(procData[utimeIdx]) | ||
stime = long(procData[stimeIdx]) | ||
ttime = utime + stime | ||
if prevCpu != None: | ||
if prevCpu is not None: | ||
cpu = ttime - prevCpu | ||
cpustr = "%.1f" % (cpu / SysMgr.uptimeDiff) | ||
else: | ||
|
@@ -93754,7 +93781,10 @@ def _getRetAddr(): | |
|
||
# get CFA rules # | ||
rules = dwarf["CFATable"].get(faddr) | ||
if not rules: | ||
# decompress rules # | ||
if not isinstance(rules, list): | ||
dwarf["CFATable"][faddr] = rules = UtilMgr.decompObj(rules) | ||
elif not rules: | ||
SysMgr.printWarn( | ||
"failed to find CFA table info for %s(%s) in %s" | ||
% (sym, hex(faddr), fname) | ||
|
@@ -93820,7 +93850,6 @@ def _getRetAddr(): | |
continue | ||
offset = value[argIdx] | ||
if offset is None: | ||
print(rule) | ||
continue | ||
rval = readMem(cfa + offset) | ||
reg = ConfigMgr.regList[num] | ||
|
@@ -100431,6 +100460,9 @@ class ElfAnalyzer(object): | |
|
||
DT_VERSIONTAGNUM = 16 | ||
|
||
ruleCacheList = {} | ||
regCacheList = {} | ||
|
||
rustChars = [ | ||
[",", "$C$"], | ||
["@", "$SP$"], | ||
|
@@ -102470,11 +102502,18 @@ class RegisterRule(object): | |
TYPE = 0 | ||
ARG = 1 | ||
|
||
def __init__(self, type, arg=None): | ||
def __init__(self, t, arg=None): | ||
pass | ||
|
||
def __new__(self, type, arg=None): | ||
return (type, arg) | ||
def __new__(self, t, arg=None): | ||
if not t in ElfAnalyzer.ruleCacheList: | ||
ElfAnalyzer.ruleCacheList[t] = {} | ||
|
||
args = str(arg) if type(arg) is list else arg | ||
|
||
if not args in ElfAnalyzer.ruleCacheList[t]: | ||
ElfAnalyzer.ruleCacheList[t][args] = (t, arg) | ||
return ElfAnalyzer.ruleCacheList[t][args] | ||
|
||
class CFARule(object): | ||
""" | ||
|
@@ -103557,13 +103596,13 @@ def getRangeBySymbol(self, symbol): | |
return None | ||
|
||
# use each symbol tables # | ||
val = self.attr["symTable"].get(symbol) | ||
if val: | ||
return [val["value"], val["value"] + val["size"]] | ||
for sname in ("symTable", "dynsymTable", "dwarfsymTable"): | ||
if not sname in self.attr: | ||
continue | ||
|
||
val = self.attr["dynsymTable"].get(symbol) | ||
if val: | ||
return [val["value"], val["value"] + val["size"]] | ||
val = self.attr[sname].get(symbol) | ||
if val: | ||
return [val["value"], val["value"] + val["size"]] | ||
|
||
return None | ||
|
||
|
@@ -106579,7 +106618,7 @@ def _getAugData(string, table, pos, size): | |
|
||
return augdict, adstr.strip(), augdata | ||
|
||
def _decodeCFI(self, entry, cfi, cie, offset): | ||
def _decodeCFI(self, entry, cfi, cie, offset, prt): | ||
def _add2Order(regnum): | ||
""" | ||
DW_CFA_restore and others remove registers from curLine, | ||
|
@@ -106727,7 +106766,7 @@ def _add2Order(regnum): | |
try: | ||
if len(curLine[n]) != 2: | ||
continue | ||
elif curLine[n][1] != None: | ||
elif curLine[n][1] is not None: | ||
continue | ||
|
||
curLine.pop(n) | ||
|
@@ -106743,11 +106782,22 @@ def _add2Order(regnum): | |
if curLine["cfa"][regIdx] is not None or len(curLine) > 2: | ||
table.append(curLine) | ||
|
||
# save result # | ||
# compress dwarf table # | ||
if ( | ||
entry == "FDE" | ||
and not prt | ||
and not "NODEBUGCOMP" in SysMgr.environList | ||
): | ||
table = UtilMgr.compObj(table) | ||
|
||
# save table # | ||
myObj["table"] = table | ||
myObj["regOrder"] = regOrder | ||
|
||
return table, regOrder | ||
# save regOrder # | ||
regOrders = str(regOrder) | ||
if not regOrders in ElfAnalyzer.regCacheList: | ||
ElfAnalyzer.regCacheList[regOrders] = regOrder | ||
myObj["regOrder"] = ElfAnalyzer.regCacheList[regOrders] | ||
|
||
def _makeCFATable(self, entry, offset, regList, prt=False): | ||
def _getCFARule(cfa): | ||
|
@@ -106773,10 +106823,9 @@ def _getRegRule(reg): | |
|
||
return s | ||
|
||
# get values # | ||
myObj = self.attr["dwarf"][entry][offset] | ||
table = myObj["table"] | ||
regOrder = myObj["regOrder"] | ||
|
||
initLoc = myObj.get("initLoc", 0) | ||
|
||
# get return address register # | ||
|
@@ -106790,48 +106839,49 @@ def _getRegRule(reg): | |
self.attr["dwarf"]["CFAIndex"].append(initLoc) | ||
self.attr["dwarf"]["CFATable"][initLoc] = table | ||
|
||
if prt: | ||
# remove return address register # | ||
if not prt: | ||
# remove FDE to save memory # | ||
if entry == "FDE": | ||
self.attr["dwarf"][entry].pop(offset) | ||
return | ||
|
||
# remove return address register # | ||
regOrder = myObj["regOrder"] | ||
try: | ||
regOrder.remove(rar) | ||
except SystemExit: | ||
sys.exit(0) | ||
except: | ||
pass | ||
|
||
# define default title # | ||
if not self.cfaTableTitle: | ||
self.cfaTableTitle = "{0:^16} {1:<10}".format("LOC", "CFA") | ||
|
||
# copy default title # | ||
s = str(self.cfaTableTitle) | ||
|
||
# add reg name # | ||
for regnum in regOrder: | ||
try: | ||
regOrder.remove(rar) | ||
s += "%-6s" % regList[regnum] | ||
except SystemExit: | ||
sys.exit(0) | ||
except: | ||
pass | ||
|
||
# define default title # | ||
if not self.cfaTableTitle: | ||
self.cfaTableTitle = "{0:^16} {1:<10}".format( | ||
"LOC", "CFA" | ||
SysMgr.printWarn( | ||
"failed to get register name", reason=True | ||
) | ||
|
||
# copy default title # | ||
s = str(self.cfaTableTitle) | ||
s += "%-6s\n" % "ra" | ||
regOrder.append(rar) | ||
|
||
# add reg name # | ||
for regnum in regOrder: | ||
try: | ||
s += "%-6s" % regList[regnum] | ||
except SystemExit: | ||
sys.exit(0) | ||
except: | ||
SysMgr.printWarn( | ||
"failed to get register name", reason=True | ||
) | ||
|
||
s += "%-6s\n" % "ra" | ||
regOrder.append(rar) | ||
|
||
# mark line # | ||
s = "." * len(s) + "\n" + s | ||
# mark line # | ||
s = "." * len(s) + "\n" + s | ||
|
||
# add decoded CFA lines # | ||
for line in table: | ||
pc = line["pc"] | ||
|
||
if not prt: | ||
continue | ||
|
||
# pc # | ||
s += "%016x" % pc | ||
|
||
|
@@ -106852,8 +106902,16 @@ def _getRegRule(reg): | |
|
||
s += "\n" | ||
|
||
if prt: | ||
printer(s) | ||
printer(s) | ||
|
||
# remove FDE to save memory # | ||
if entry == "FDE": | ||
self.attr["dwarf"][entry].pop(offset) | ||
|
||
# compress CFA table # | ||
if initLoc > 0 and not "NODEBUGCOMP" in SysMgr.environList: | ||
table = UtilMgr.compObj(table) | ||
self.attr["dwarf"]["CFATable"][initLoc] = table | ||
|
||
def _printCFIs(cfi, cie=None, pc=None, regList=None): | ||
def _convRegName(arg, regList): | ||
|
@@ -107363,7 +107421,7 @@ def _decodeData2(table, pos): | |
printer(printStr) | ||
|
||
# decode instructions to make CFA table # | ||
_decodeCFI(self, entry, cfi, cie, offset) | ||
_decodeCFI(self, entry, cfi, cie, offset, prt=printable) | ||
|
||
# print CFI # | ||
if printable: | ||
|
@@ -109465,6 +109523,20 @@ def _addEntryOldState(cmd, args, isExtended=False): | |
except: | ||
SysMgr.printErr("failed to parse %s" % secName, True) | ||
|
||
# compress dwarf table # | ||
if not "NODEBUGCOMP" in SysMgr.environList: | ||
for x in list( | ||
self.attr.get("dwarf", {}).get("CFATable", {}).keys() | ||
): | ||
obj = self.attr["dwarf"]["CFATable"][x] | ||
if not isinstance(obj, list): | ||
continue | ||
self.attr["dwarf"]["CFATable"][x] = UtilMgr.compObj(obj) | ||
|
||
# remove dwarf caches # | ||
ElfAnalyzer.ruleCacheList = {} | ||
ElfAnalyzer.regCacheList = {} | ||
|
||
# check dynamic section # | ||
if e_shdynamic < 0: | ||
return None | ||
|