diff options
author | Greg Clayton <gclayton@apple.com> | 2012-02-01 08:09:32 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2012-02-01 08:09:32 +0000 |
commit | 6b2bd93918bceac12b0aea61fd13a65676cd4577 (patch) | |
tree | 74c4eb0c2a271070e4606a396dc1f2ff79deefd1 /lldb/scripts/Python | |
parent | 0e48c70ba79cb9224a3e5cc1be60efdf8f840f23 (diff) | |
download | bcm5719-llvm-6b2bd93918bceac12b0aea61fd13a65676cd4577.tar.gz bcm5719-llvm-6b2bd93918bceac12b0aea61fd13a65676cd4577.zip |
Added many more python convenience accessors:
You can now access a frame in a thread using:
lldb.SBThread.frame[int] -> lldb.SBFrame object for a frame in a thread
Where "int" is an integer index. You can also access a list object with all of
the frames using:
lldb.SBThread.frames => list() of lldb.SBFrame objects
All SB objects that give out SBAddress objects have properties named "addr"
lldb.SBInstructionList now has the following convenience accessors for len() and
instruction access using an index:
insts = lldb.frame.function.instructions
for idx in range(len(insts)):
print insts[idx]
Instruction lists can also lookup an isntruction using a lldb.SBAddress as the key:
pc_inst = lldb.frame.function.instructions[lldb.frame.addr]
lldb.SBProcess now exposes:
lldb.SBProcess.is_alive => BOOL Check if a process is exists and is alive
lldb.SBProcess.is_running => BOOL check if a process is running (or stepping):
lldb.SBProcess.is_running => BOOL check if a process is currently stopped or crashed:
lldb.SBProcess.thread[int] => lldb.SBThreads for a given "int" zero based index
lldb.SBProcess.threads => list() containing all lldb.SBThread objects in a process
SBInstruction now exposes:
lldb.SBInstruction.mnemonic => python string for instruction mnemonic
lldb.SBInstruction.operands => python string for instruction operands
lldb.SBInstruction.command => python string for instruction comment
SBModule now exposes:
lldb.SBModule.uuid => uuid.UUID(), an UUID object from the "uuid" python module
lldb.SBModule.symbol[int] => lldb.Symbol, lookup symbol by zero based index
lldb.SBModule.symbol[str] => list() of lldb.Symbol objects that match "str"
lldb.SBModule.symbol[re] => list() of lldb.Symbol objecxts that match the regex
lldb.SBModule.symbols => list() of all symbols in a module
SBAddress objects can now access the current load address with the "lldb.SBAddress.load_addr"
property. The current "lldb.target" will be used to try and resolve the load address.
Load addresses can also be set using this accessor:
addr = lldb.SBAddress()
addd.load_addr = 0x123023
Then you can check the section and offset to see if the address got resolved.
SBTarget now exposes:
lldb.SBTarget.module[int] => lldb.SBModule from zero based module index
lldb.SBTarget.module[str] => lldb.SBModule by basename or fullpath or uuid string
lldb.SBTarget.module[uuid.UUID()] => lldb.SBModule whose UUID matches
lldb.SBTarget.module[re] => list() of lldb.SBModule objects that match the regex
lldb.SBTarget.modules => list() of all lldb.SBModule objects in the target
SBSymbol now exposes:
lldb.SBSymbol.name => python string for demangled symbol name
lldb.SBSymbol.mangled => python string for mangled symbol name or None if there is none
lldb.SBSymbol.type => lldb.eSymbolType enum value
lldb.SBSymbol.addr => SBAddress object that represents the start address for this symbol (if there is one)
lldb.SBSymbol.end_addr => SBAddress for the end address of the symbol (if there is one)
lldb.SBSymbol.prologue_size => pythin int containing The size of the prologue in bytes
lldb.SBSymbol.instructions => SBInstructionList containing all instructions for this symbol
SBFunction now also has these new properties in addition to what is already has:
lldb.SBFunction.addr => SBAddress object that represents the start address for this function
lldb.SBFunction.end_addr => SBAddress for the end address of the function
lldb.SBFunction.instructions => SBInstructionList containing all instructions for this function
SBFrame now exposes the SBAddress for the frame:
lldb.SBFrame.addr => SBAddress which is the section offset address for the current frame PC
These are all in addition to what was already added. Documentation and website
updates coming soon.
llvm-svn: 149489
Diffstat (limited to 'lldb/scripts/Python')
-rw-r--r-- | lldb/scripts/Python/interface/SBAddress.i | 26 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBFileSpec.i | 14 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBFrame.i | 3 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBFunction.i | 10 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBInstruction.i | 20 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBInstructionList.i | 28 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBLineEntry.i | 2 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBModule.i | 73 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBProcess.i | 67 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBSymbol.i | 28 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBTarget.i | 67 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBThread.i | 26 |
12 files changed, 356 insertions, 8 deletions
diff --git a/lldb/scripts/Python/interface/SBAddress.i b/lldb/scripts/Python/interface/SBAddress.i index 47fa67b70e0..1472c4f3588 100644 --- a/lldb/scripts/Python/interface/SBAddress.i +++ b/lldb/scripts/Python/interface/SBAddress.i @@ -129,6 +129,28 @@ public: GetLineEntry (); %pythoncode %{ + def __get_load_addr_property__ (self): + '''Get the load address for a lldb.SBAddress using the current target.''' + return self.GetLoadAddress (target) + + def __set_load_addr_property__ (self, load_addr): + '''Set the load address for a lldb.SBAddress using the current target.''' + return self.SetLoadAddress (load_addr, target) + + def __int__(self): + '''Convert an address to a load address if there is a process and that + process is alive, or to a file address otherwise.''' + if process.is_alive: + return self.GetLoadAddress (target) + else: + return self.GetFileAddress () + + def __oct__(self): + return '%o' % int(self) + + def __hex__(self): + return '0x%x' % int(self) + __swig_getmethods__["module"] = GetModule if _newclass: x = property(GetModule, None) @@ -156,6 +178,10 @@ public: __swig_getmethods__["file_addr"] = GetFileAddress if _newclass: x = property(GetFileAddress, None) + __swig_getmethods__["load_addr"] = __get_load_addr_property__ + __swig_setmethods__["load_addr"] = __set_load_addr_property__ + if _newclass: x = property(__get_load_addr_property__, __set_load_addr_property__) + %} }; diff --git a/lldb/scripts/Python/interface/SBFileSpec.i b/lldb/scripts/Python/interface/SBFileSpec.i index d3fae44de8b..ae23c8fd5fc 100644 --- a/lldb/scripts/Python/interface/SBFileSpec.i +++ b/lldb/scripts/Python/interface/SBFileSpec.i @@ -68,6 +68,20 @@ public: GetDescription (lldb::SBStream &description) const; %pythoncode %{ + def __get_fullpath__(self): + spec_dir = self.GetDirectory() + spec_file = self.GetFilename() + if spec_dir and spec_file: + return '%s/%s' % (spec_dir, spec_file) + elif spec_dir: + return spec_dir + elif spec_file: + return spec_file + return None + + __swig_getmethods__["fullpath"] = __get_fullpath__ + if _newclass: x = property(__get_fullpath__, None) + __swig_getmethods__["basename"] = GetFilename if _newclass: x = property(GetFilename, None) diff --git a/lldb/scripts/Python/interface/SBFrame.i b/lldb/scripts/Python/interface/SBFrame.i index 9c5e0981f13..3a6e7999edc 100644 --- a/lldb/scripts/Python/interface/SBFrame.i +++ b/lldb/scripts/Python/interface/SBFrame.i @@ -223,6 +223,9 @@ public: __swig_setmethods__["pc"] = SetPC if _newclass: x = property(GetPC, SetPC) + __swig_getmethods__["addr"] = GetPCAddress + if _newclass: x = property(GetPCAddress, None) + __swig_getmethods__["fp"] = GetFP if _newclass: x = property(GetFP, None) diff --git a/lldb/scripts/Python/interface/SBFunction.i b/lldb/scripts/Python/interface/SBFunction.i index 76c80661b4f..37b957fd5cf 100644 --- a/lldb/scripts/Python/interface/SBFunction.i +++ b/lldb/scripts/Python/interface/SBFunction.i @@ -78,13 +78,16 @@ public: GetDescription (lldb::SBStream &description); %pythoncode %{ + def get_instructions_from_current_target (self): + return self.GetInstructions (target) + __swig_getmethods__["name"] = GetName if _newclass: x = property(GetName, None) __swig_getmethods__["mangled"] = GetMangledName if _newclass: x = property(GetMangledName, None) - __swig_getmethods__["start_addr"] = GetStartAddress + __swig_getmethods__["addr"] = GetStartAddress if _newclass: x = property(GetStartAddress, None) __swig_getmethods__["end_addr"] = GetEndAddress @@ -92,7 +95,10 @@ public: __swig_getmethods__["prologue_size"] = GetPrologueByteSize if _newclass: x = property(GetPrologueByteSize, None) - + + __swig_getmethods__["instructions"] = get_instructions_from_current_target + if _newclass: x = property(get_instructions_from_current_target, None) + %} }; diff --git a/lldb/scripts/Python/interface/SBInstruction.i b/lldb/scripts/Python/interface/SBInstruction.i index a0595addf1c..01cebb1590c 100644 --- a/lldb/scripts/Python/interface/SBInstruction.i +++ b/lldb/scripts/Python/interface/SBInstruction.i @@ -64,6 +64,26 @@ public: TestEmulation (lldb::SBStream &output_stream, const char *test_file); %pythoncode %{ + def __mnemonic_property__ (self): + return self.GetMnemonic (target) + def __operands_property__ (self): + return self.GetOperands (target) + def __comment_property__ (self): + return self.GetComment (target) + def __file_addr_property__ (self): + return self.GetAddress ().GetFileAddress() + def __load_adrr_property__ (self): + return self.GetComment (target) + + __swig_getmethods__["mnemonic"] = __mnemonic_property__ + if _newclass: x = property(__mnemonic_property__, None) + + __swig_getmethods__["operands"] = __operands_property__ + if _newclass: x = property(__operands_property__, None) + + __swig_getmethods__["comment"] = __comment_property__ + if _newclass: x = property(__comment_property__, None) + __swig_getmethods__["addr"] = GetAddress if _newclass: x = property(GetAddress, None) diff --git a/lldb/scripts/Python/interface/SBInstructionList.i b/lldb/scripts/Python/interface/SBInstructionList.i index 488bbc81676..b2bb3496e34 100644 --- a/lldb/scripts/Python/interface/SBInstructionList.i +++ b/lldb/scripts/Python/interface/SBInstructionList.i @@ -58,6 +58,34 @@ public: bool DumpEmulationForAllInstructions (const char *triple); + + %pythoncode %{ + def __len__(self): + '''Access len of the instruction list.''' + return self.GetSize(); + + def __getitem__(self, key): + '''Access instructions by integer index.''' + if type(key) is int: + # Find an instruction by index + if key < len(self): + return self.GetInstructionAtIndex(key) + elif type(key) is SBAddress: + # Find an instruction using a lldb.SBAddress object + lookup_file_addr = key.file_addr + closest_inst = None + for idx in range(self.GetSize()): + inst = self.GetInstructionAtIndex(idx) + inst_file_addr = inst.addr.file_addr + if inst_file_addr == lookup_file_addr: + return inst + elif inst_file_addr > lookup_file_addr: + return closest_inst + else: + closest_inst = inst + return None + %} + }; } // namespace lldb diff --git a/lldb/scripts/Python/interface/SBLineEntry.i b/lldb/scripts/Python/interface/SBLineEntry.i index bb613827ba5..61d6a64e9ca 100644 --- a/lldb/scripts/Python/interface/SBLineEntry.i +++ b/lldb/scripts/Python/interface/SBLineEntry.i @@ -87,7 +87,7 @@ public: __swig_getmethods__["column"] = GetColumn if _newclass: x = property(GetColumn, None) - __swig_getmethods__["start_addr"] = GetStartAddress + __swig_getmethods__["addr"] = GetStartAddress if _newclass: x = property(GetStartAddress, None) __swig_getmethods__["end_addr"] = GetEndAddress diff --git a/lldb/scripts/Python/interface/SBModule.i b/lldb/scripts/Python/interface/SBModule.i index 547b4a27357..d3c43523604 100644 --- a/lldb/scripts/Python/interface/SBModule.i +++ b/lldb/scripts/Python/interface/SBModule.i @@ -247,15 +247,82 @@ public: GetTriple (); %pythoncode %{ + class symbols_access(object): + re_type = type(re.compile('.')) + '''A helper object that will lazily hand out lldb.SBModule objects for a target when supplied an index, or by full or partial path.''' + def __init__(self, sbmodule): + self.sbmodule = sbmodule + + def __len__(self): + if self.sbmodule: + return self.sbmodule.GetNumSymbols() + return 0 + + def __getitem__(self, key): + count = self.sbmodule.GetNumSymbols() + if type(key) is int: + if key < count: + return self.sbmodule.GetSymbolAtIndex(key) + elif type(key) is str: + matches = [] + for idx in range(count): + symbol = self.sbmodule.GetSymbolAtIndex(idx) + if symbol.name == key or symbol.mangled == key: + matches.append(symbol) + if len(matches): + return matches + elif isinstance(key, self.re_type): + matches = [] + for idx in range(count): + symbol = self.sbmodule.GetSymbolAtIndex(idx) + added = False + name = symbol.name + if name: + re_match = key.search(name) + if re_match: + matches.append(symbol) + added = True + if not added: + mangled = symbol.mangled + if mangled: + re_match = key.search(mangled) + if re_match: + matches.append(symbol) + if len(matches): + return matches + else: + print "error: unsupported item type: %s" % type(key) + return None + + def get_symbols_access_object(self): + '''An accessor function that retuns a symbols_access() object which allows lazy module array access.''' + return self.symbols_access (self) + + def get_symbols_array(self): + '''An accessor function that retuns an array object that contains all modules in this target object.''' + symbols = [] + for idx in range(self.GetNumSymbols()): + symbols.append(self.GetSymbolAtIndex(idx)) + return symbols + + __swig_getmethods__["symbols"] = get_symbols_array + if _newclass: x = property(get_symbols_array, None) + + __swig_getmethods__["symbol"] = get_symbols_access_object + if _newclass: x = property(get_symbols_access_object, None) + + def get_uuid(self): + return uuid.UUID (self.GetUUIDString()) + + __swig_getmethods__["uuid"] = get_uuid + if _newclass: x = property(get_uuid, None) + __swig_getmethods__["file"] = GetFileSpec if _newclass: x = property(GetFileSpec, None) __swig_getmethods__["platform_file"] = GetPlatformFileSpec if _newclass: x = property(GetPlatformFileSpec, None) - __swig_getmethods__["uuid"] = GetUUIDString - if _newclass: x = property(GetUUIDString, None) - __swig_getmethods__["byte_order"] = GetByteOrder if _newclass: x = property(GetByteOrder, None) diff --git a/lldb/scripts/Python/interface/SBProcess.i b/lldb/scripts/Python/interface/SBProcess.i index 2087f4683ce..77b65b74394 100644 --- a/lldb/scripts/Python/interface/SBProcess.i +++ b/lldb/scripts/Python/interface/SBProcess.i @@ -282,6 +282,73 @@ public: UnloadImage (uint32_t image_token); %pythoncode %{ + def __get_is_alive__(self): + '''Returns "True" if the process is currently alive, "False" otherwise''' + s = self.GetState() + if (s == eStateAttaching or + s == eStateLaunching or + s == eStateStopped or + s == eStateRunning or + s == eStateStepping or + s == eStateCrashed or + s == eStateSuspended): + return True + return False + + def __get_is_running__(self): + '''Returns "True" if the process is currently running, "False" otherwise''' + state = self.GetState() + if state == eStateRunning or state == eStateStepping: + return True + return False + + def __get_is_running__(self): + '''Returns "True" if the process is currently stopped, "False" otherwise''' + state = self.GetState() + if state == eStateStopped or state == eStateCrashed or state == eStateSuspended: + return True + return False + + class thread_array_access(object): + '''A helper object that will lazily hand out thread for a process when supplied an index.''' + def __init__(self, sbprocess): + self.sbprocess = sbprocess + + def __len__(self): + if self.sbprocess: return self.sbprocess.GetNumThreads() + return 0 + + def __getitem__(self, key): + if type(key) is int and key < len(self): + return self.sbprocess.GetThreadAtIndex(key) + return None + + def get_thread_array_access_object(self): + '''An accessor function that retuns a thread_array_access() object which allows lazy thread array access.''' + return self.thread_array_access (self) + + def get_process_thread_list(self): + '''An accessor function that retuns an array object that contains all threads in this process object.''' + threads = [] + for idx in range(self.GetNumThreads()): + threads.append(GetThreadAtIndex(idx)) + return threads + + __swig_getmethods__["threads"] = get_process_thread_list + if _newclass: x = property(get_process_thread_list, None) + + __swig_getmethods__["thread"] = get_thread_array_access_object + if _newclass: x = property(get_thread_array_access_object, None) + + __swig_getmethods__["is_alive"] = __get_is_alive__ + if _newclass: x = property(__get_is_alive__, None) + + __swig_getmethods__["is_running"] = __get_is_running__ + if _newclass: x = property(__get_is_running__, None) + + __swig_getmethods__["is_stopped"] = __get_is_running__ + if _newclass: x = property(__get_is_running__, None) + __swig_getmethods__["id"] = GetProcessID if _newclass: x = property(GetProcessID, None) diff --git a/lldb/scripts/Python/interface/SBSymbol.i b/lldb/scripts/Python/interface/SBSymbol.i index c0cb710f262..0b5342a53f6 100644 --- a/lldb/scripts/Python/interface/SBSymbol.i +++ b/lldb/scripts/Python/interface/SBSymbol.i @@ -52,6 +52,34 @@ public: bool GetDescription (lldb::SBStream &description); + + %pythoncode %{ + def get_instructions_from_current_target (self): + return self.GetInstructions (target) + + __swig_getmethods__["name"] = GetName + if _newclass: x = property(GetName, None) + + __swig_getmethods__["mangled"] = GetMangledName + if _newclass: x = property(GetMangledName, None) + + __swig_getmethods__["type"] = GetType + if _newclass: x = property(GetType, None) + + __swig_getmethods__["addr"] = GetStartAddress + if _newclass: x = property(GetStartAddress, None) + + __swig_getmethods__["end_addr"] = GetEndAddress + if _newclass: x = property(GetEndAddress, None) + + __swig_getmethods__["prologue_size"] = GetPrologueByteSize + if _newclass: x = property(GetPrologueByteSize, None) + + __swig_getmethods__["instructions"] = get_instructions_from_current_target + if _newclass: x = property(get_instructions_from_current_target, None) + + %} + }; } // namespace lldb diff --git a/lldb/scripts/Python/interface/SBTarget.i b/lldb/scripts/Python/interface/SBTarget.i index 5bf218b0995..0307ec14af6 100644 --- a/lldb/scripts/Python/interface/SBTarget.i +++ b/lldb/scripts/Python/interface/SBTarget.i @@ -487,6 +487,73 @@ public: GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level); %pythoncode %{ + class modules_access(object): + '''A helper object that will lazily hand out lldb.SBModule objects for a target when supplied an index, or by full or partial path.''' + def __init__(self, sbtarget): + self.sbtarget = sbtarget + + def __len__(self): + if self.sbtarget: + return self.sbtarget.GetNumModules() + return 0 + + def __getitem__(self, key): + num_modules = self.sbtarget.GetNumModules() + if type(key) is int: + if key < num_modules: + return self.sbtarget.GetModuleAtIndex(key) + elif type(key) is str: + if key.find('/') == -1: + for idx in range(num_modules): + module = self.sbtarget.GetModuleAtIndex(idx) + if module.file.basename == key: + return module + else: + for idx in range(num_modules): + module = self.sbtarget.GetModuleAtIndex(idx) + if module.file.fullpath == key: + return module + # See if the string is a UUID + the_uuid = uuid.UUID(key) + if the_uuid: + for idx in range(num_modules): + module = self.sbtarget.GetModuleAtIndex(idx) + if module.uuid == the_uuid: + return module + elif type(key) is uuid.UUID: + for idx in range(num_modules): + module = self.sbtarget.GetModuleAtIndex(idx) + if module.uuid == key: + return module + elif type(key) is re.SRE_Pattern: + matching_modules = [] + for idx in range(num_modules): + module = self.sbtarget.GetModuleAtIndex(idx) + re_match = key.search(module.path.fullpath) + if re_match: + matching_modules.append(module) + return matching_modules + else: + print "error: unsupported item type: %s" % type(key) + return None + + def get_modules_access_object(self): + '''An accessor function that retuns a modules_access() object which allows lazy module array access.''' + return self.modules_access (self) + + def get_modules_array(self): + '''An accessor function that retuns an array object that contains all modules in this target object.''' + modules = [] + for idx in range(self.GetNumModules()): + modules.append(self.GetModuleAtIndex(idx)) + return modules + + __swig_getmethods__["modules"] = get_modules_array + if _newclass: x = property(get_modules_array, None) + + __swig_getmethods__["module"] = get_modules_access_object + if _newclass: x = property(get_modules_access_object, None) + __swig_getmethods__["process"] = GetProcess if _newclass: x = property(GetProcess, None) diff --git a/lldb/scripts/Python/interface/SBThread.i b/lldb/scripts/Python/interface/SBThread.i index fbb1e4ebd6d..4d3cb719126 100644 --- a/lldb/scripts/Python/interface/SBThread.i +++ b/lldb/scripts/Python/interface/SBThread.i @@ -175,13 +175,32 @@ public: GetDescription (lldb::SBStream &description) const; %pythoncode %{ + class frame_array_access(object): + '''A helper object that will lazily hand out frames for a thread when supplied an index.''' + def __init__(self, sbthread): + self.sbthread = sbthread + + def __len__(self): + if self.sbthread: + return self.sbthread.GetNumFrames() + return 0 + + def __getitem__(self, key): + if type(key) is int and key < self.sbthread.GetNumFrames(): + return self.sbthread.GetFrameAtIndex(key) + return None + + def get_frame_array_access_object(self): + '''An accessor function that retuns a frame_array_access() object which allows lazy frame array access.''' + return self.frame_array_access (self) + def get_thread_frames(self): + '''An accessor function that retuns an array object that contains all frames in this thread object.''' frames = [] for frame in self: frames.append(frame) return frames - - + __swig_getmethods__["id"] = GetThreadID if _newclass: x = property(GetThreadID, None) @@ -200,6 +219,9 @@ public: __swig_getmethods__["frames"] = get_thread_frames if _newclass: x = property(get_thread_frames, None) + __swig_getmethods__["frame"] = get_frame_array_access_object + if _newclass: x = property(get_frame_array_access_object, None) + __swig_getmethods__["name"] = GetName if _newclass: x = property(GetName, None) |