Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 1 | //===-- MICmdCmdSymbol.cpp --------------------------------------*- C++ -*-===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | |
Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 10 | // Overview: CMICmdCmdSymbolListLines implementation. |
Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 11 | |
| 12 | // Third Party Headers: |
Alexander Polyakov | 8c670ec | 2018-07-03 15:40:20 +0000 | [diff] [blame] | 13 | #include "llvm/ADT/Twine.h" |
Alexander Polyakov | 83e3ec5 | 2018-07-03 16:07:30 +0000 | [diff] [blame] | 14 | #include "lldb/API/SBAddress.h" |
| 15 | #include "lldb/API/SBLineEntry.h" |
| 16 | #include "lldb/API/SBFileSpec.h" |
| 17 | #include "lldb/API/SBCompileUnit.h" |
| 18 | #include "lldb/API/SBSymbolContext.h" |
| 19 | #include "lldb/API/SBSymbolContextList.h" |
Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 20 | |
| 21 | // In-house headers: |
| 22 | #include "MICmdArgValFile.h" |
| 23 | #include "MICmdCmdSymbol.h" |
| 24 | #include "MICmnLLDBDebugSessionInfo.h" |
| 25 | #include "MICmnMIResultRecord.h" |
Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 26 | #include "MICmnMIValueTuple.h" |
Alexander Polyakov | 8c670ec | 2018-07-03 15:40:20 +0000 | [diff] [blame] | 27 | #include "MICmnMIValueResult.h" |
| 28 | |
| 29 | namespace { |
| 30 | const CMICmnMIValueTuple |
| 31 | CreateMITuplePCLine(const uint32_t addr, const uint32_t line_number) { |
| 32 | const CMICmnMIValueConst miValueConstAddr("0x" + llvm::Twine::utohexstr(addr).str()); |
| 33 | const CMICmnMIValueConst miValueConstLine(llvm::Twine(line_number).str()); |
| 34 | const CMICmnMIValueResult miValueResultAddr("pc", miValueConstAddr); |
| 35 | const CMICmnMIValueResult miValueResultLine("line", miValueConstLine); |
| 36 | CMICmnMIValueTuple miValueTuple(miValueResultAddr); |
| 37 | miValueTuple.Add(miValueResultLine); |
| 38 | return miValueTuple; |
| 39 | } |
| 40 | } // namespace |
Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 41 | |
Alexander Polyakov | 67cdc92 | 2018-07-03 22:51:01 +0000 | [diff] [blame] | 42 | using namespace lldb; // For operator==(const SBAddress &, const SBAddress &). |
| 43 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 44 | //++ |
| 45 | //------------------------------------------------------------------------------------ |
Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 46 | // Details: CMICmdCmdSymbolListLines constructor. |
| 47 | // Type: Method. |
| 48 | // Args: None. |
| 49 | // Return: None. |
| 50 | // Throws: None. |
| 51 | //-- |
Bruce Mitchener | e2453af | 2015-08-04 10:24:20 +0000 | [diff] [blame] | 52 | CMICmdCmdSymbolListLines::CMICmdCmdSymbolListLines() |
Alexander Polyakov | 8c670ec | 2018-07-03 15:40:20 +0000 | [diff] [blame] | 53 | : m_resultList(false), m_constStrArgNameFile("file") { |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 54 | // Command factory matches this name with that received from the stdin stream |
| 55 | m_strMiCmd = "symbol-list-lines"; |
Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 56 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 57 | // Required by the CMICmdFactory when registering *this command |
| 58 | m_pSelfCreatorFn = &CMICmdCmdSymbolListLines::CreateSelf; |
Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 59 | } |
| 60 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 61 | //++ |
| 62 | //------------------------------------------------------------------------------------ |
Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 63 | // Details: CMICmdCmdSymbolListLines destructor. |
| 64 | // Type: Overrideable. |
| 65 | // Args: None. |
| 66 | // Return: None. |
| 67 | // Throws: None. |
| 68 | //-- |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 69 | CMICmdCmdSymbolListLines::~CMICmdCmdSymbolListLines() {} |
Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 70 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 71 | //++ |
| 72 | //------------------------------------------------------------------------------------ |
| 73 | // Details: The invoker requires this function. The parses the command line |
| 74 | // options |
Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 75 | // arguments to extract values for each of those arguments. |
| 76 | // Type: Overridden. |
| 77 | // Args: None. |
| 78 | // Return: MIstatus::success - Functional succeeded. |
| 79 | // MIstatus::failure - Functional failed. |
| 80 | // Throws: None. |
| 81 | //-- |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 82 | bool CMICmdCmdSymbolListLines::ParseArgs() { |
| 83 | m_setCmdArgs.Add(new CMICmdArgValFile(m_constStrArgNameFile, true, true)); |
| 84 | return ParseValidateCmdOptions(); |
Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 85 | } |
| 86 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 87 | //++ |
| 88 | //------------------------------------------------------------------------------------ |
| 89 | // Details: The invoker requires this function. The command does work in this |
| 90 | // function. |
| 91 | // The command is likely to communicate with the LLDB SBDebugger in |
| 92 | // here. |
Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 93 | // Synopsis: -symbol-list-lines file |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 94 | // Ref: |
| 95 | // http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Symbol-Query.html#GDB_002fMI-Symbol-Query |
Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 96 | // Type: Overridden. |
| 97 | // Args: None. |
| 98 | // Return: MIstatus::success - Functional succeeded. |
| 99 | // MIstatus::failure - Functional failed. |
| 100 | // Throws: None. |
| 101 | //-- |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 102 | bool CMICmdCmdSymbolListLines::Execute() { |
| 103 | CMICMDBASE_GETOPTION(pArgFile, File, m_constStrArgNameFile); |
Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 104 | |
Alexander Polyakov | 8c670ec | 2018-07-03 15:40:20 +0000 | [diff] [blame] | 105 | const auto &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); |
| 106 | if (rSessionInfo.GetTarget() == rSessionInfo.GetDebugger().GetDummyTarget()) { |
| 107 | SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT), |
| 108 | m_cmdData.strMiCmd.c_str())); |
| 109 | return MIstatus::failure; |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 110 | } |
Alexander Polyakov | 8c670ec | 2018-07-03 15:40:20 +0000 | [diff] [blame] | 111 | |
| 112 | const lldb::SBFileSpec source_file_spec(pArgFile->GetValue().c_str(), true); |
| 113 | const char *source_file_name = source_file_spec.GetFilename(); |
| 114 | const char *source_file_directory = source_file_spec.GetDirectory(); |
| 115 | const bool has_path = source_file_directory; |
| 116 | |
| 117 | lldb::SBSymbolContextList sc_cu_list = |
| 118 | CMICmnLLDBDebugSessionInfo::Instance().GetTarget().FindCompileUnits( |
| 119 | source_file_spec); |
| 120 | |
| 121 | bool found_something = false; |
| 122 | for (uint32_t i = 0, e = sc_cu_list.GetSize(); i < e; ++i) { |
| 123 | const lldb::SBCompileUnit cu = |
| 124 | sc_cu_list.GetContextAtIndex(i).GetCompileUnit(); |
| 125 | for (uint32_t j = 0, e = cu.GetNumLineEntries(); j < e; ++j) { |
| 126 | const lldb::SBLineEntry line = cu.GetLineEntryAtIndex(j); |
| 127 | const lldb::SBFileSpec line_spec = line.GetFileSpec(); |
| 128 | if (line_spec.GetFilename() == source_file_name) { |
| 129 | if (has_path && (line_spec.GetDirectory() != source_file_directory)) |
| 130 | continue; |
| 131 | // We don't need a line with start address equals to end one, |
| 132 | // so just skip it. |
| 133 | const lldb::SBAddress line_start_address = line.GetStartAddress(); |
| 134 | const lldb::SBAddress line_end_address = line.GetEndAddress(); |
| 135 | if (line_start_address == line_end_address) |
| 136 | continue; |
| 137 | // We have a matching line. |
| 138 | found_something = true; |
| 139 | m_resultList.Add(CreateMITuplePCLine( |
| 140 | line_start_address.GetFileAddress(), |
| 141 | line.GetLine())); |
| 142 | } |
| 143 | } |
| 144 | } |
| 145 | if (!found_something) { |
| 146 | SetError(MIRSRC(IDS_UTIL_FILE_ERR_INVALID_PATHNAME)); |
| 147 | return MIstatus::failure; |
| 148 | } |
| 149 | return MIstatus::success; |
Dawn Perchik | b013100 | 2015-09-17 16:22:30 +0000 | [diff] [blame] | 150 | } |
| 151 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 152 | //++ |
| 153 | //------------------------------------------------------------------------------------ |
| 154 | // Details: The invoker requires this function. The command prepares a MI Record |
| 155 | // Result |
Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 156 | // for the work carried out in the Execute(). |
| 157 | // Type: Overridden. |
| 158 | // Args: None. |
| 159 | // Return: MIstatus::success - Functional succeeded. |
| 160 | // MIstatus::failure - Functional failed. |
| 161 | // Throws: None. |
| 162 | //-- |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 163 | bool CMICmdCmdSymbolListLines::Acknowledge() { |
Alexander Polyakov | 8c670ec | 2018-07-03 15:40:20 +0000 | [diff] [blame] | 164 | // MI print "%s^done,lines=[{pc=\"%d\",line=\"%d\"}...]" |
| 165 | const CMICmnMIValueResult miValueResult("lines", m_resultList); |
| 166 | m_miResultRecord = CMICmnMIResultRecord( |
| 167 | m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, |
| 168 | miValueResult); |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 169 | return MIstatus::success; |
Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 170 | } |
| 171 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 172 | //++ |
| 173 | //------------------------------------------------------------------------------------ |
| 174 | // Details: Required by the CMICmdFactory when registering *this command. The |
| 175 | // factory |
Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 176 | // calls this function to create an instance of *this command. |
| 177 | // Type: Static method. |
| 178 | // Args: None. |
| 179 | // Return: CMICmdBase * - Pointer to a new command. |
| 180 | // Throws: None. |
| 181 | //-- |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 182 | CMICmdBase *CMICmdCmdSymbolListLines::CreateSelf() { |
| 183 | return new CMICmdCmdSymbolListLines(); |
Ilia K | c12d88d | 2015-02-20 13:07:41 +0000 | [diff] [blame] | 184 | } |