[llvm-branch-commits] [lldb] r183468 - Update platform branch with top of tree.
Greg Clayton
gclayton at apple.com
Thu Jun 6 17:08:22 PDT 2013
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Thu Jun 6 19:06:43 2013
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
// C Includes
#include <errno.h>
#include <spawn.h>
@@ -31,13 +33,19 @@
#include "lldb/Host/FileSpec.h"
#include "lldb/Core/InputReader.h"
#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
#include "lldb/Core/Value.h"
+#include "lldb/Host/Symbols.h"
#include "lldb/Host/TimeValue.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandObject.h"
+#include "lldb/Interpreter/CommandObjectMultiword.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Target.h"
@@ -56,6 +64,7 @@
#include "ProcessGDBRemoteLog.h"
#include "ThreadGDBRemote.h"
+
namespace lldb
{
// Provide a function that can easily dump the packet history if we know a
@@ -107,10 +116,11 @@ get_random_port ()
}
-const char *
+lldb_private::ConstString
ProcessGDBRemote::GetPluginNameStatic()
{
- return "gdb-remote";
+ static ConstString g_name("gdb-remote");
+ return g_name;
}
const char *
@@ -180,6 +190,8 @@ ProcessGDBRemote::ProcessGDBRemote(Targe
m_register_info (),
m_async_broadcaster (NULL, "lldb.process.gdb-remote.async-broadcaster"),
m_async_thread (LLDB_INVALID_HOST_THREAD),
+ m_async_thread_state(eAsyncThreadNotStarted),
+ m_async_thread_state_mutex(Mutex::eMutexTypeRecursive),
m_thread_ids (),
m_continue_c_tids (),
m_continue_C_tids (),
@@ -190,7 +202,8 @@ ProcessGDBRemote::ProcessGDBRemote(Targe
m_addr_to_mmap_size (),
m_thread_create_bp_sp (),
m_waiting_for_attach (false),
- m_destroy_tried_resuming (false)
+ m_destroy_tried_resuming (false),
+ m_command_sp ()
{
m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue");
@@ -209,20 +222,20 @@ ProcessGDBRemote::~ProcessGDBRemote()
// destruct this class, then Process::~Process() might have problems
// trying to fully destroy the broadcaster.
Finalize();
+
+ // The general Finalize is going to try to destroy the process and that SHOULD
+ // shut down the async thread. However, if we don't kill it it will get stranded and
+ // its connection will go away so when it wakes up it will crash. So kill it for sure here.
+ StopAsyncThread();
+ KillDebugserverProcess();
}
//----------------------------------------------------------------------
// PluginInterface
//----------------------------------------------------------------------
-const char *
+ConstString
ProcessGDBRemote::GetPluginName()
{
- return "Process debugging plug-in that uses the GDB remote protocol";
-}
-
-const char *
-ProcessGDBRemote::GetShortPluginName()
-{
return GetPluginNameStatic();
}
@@ -259,6 +272,8 @@ ProcessGDBRemote::BuildDynamicRegisterIn
ConstString reg_name;
ConstString alt_name;
ConstString set_name;
+ std::vector<uint32_t> value_regs;
+ std::vector<uint32_t> invalidate_regs;
RegisterInfo reg_info = { NULL, // Name
NULL, // Alt name
0, // byte size
@@ -300,18 +315,16 @@ ProcessGDBRemote::BuildDynamicRegisterIn
}
else if (name.compare("encoding") == 0)
{
- if (value.compare("uint") == 0)
- reg_info.encoding = eEncodingUint;
- else if (value.compare("sint") == 0)
- reg_info.encoding = eEncodingSint;
- else if (value.compare("ieee754") == 0)
- reg_info.encoding = eEncodingIEEE754;
- else if (value.compare("vector") == 0)
- reg_info.encoding = eEncodingVector;
+ const Encoding encoding = Args::StringToEncoding (value.c_str());
+ if (encoding != eEncodingInvalid)
+ reg_info.encoding = encoding;
}
else if (name.compare("format") == 0)
{
- if (value.compare("binary") == 0)
+ Format format = eFormatInvalid;
+ if (Args::StringToFormat (value.c_str(), format, NULL).Success())
+ reg_info.format = format;
+ else if (value.compare("binary") == 0)
reg_info.format = eFormatBinary;
else if (value.compare("decimal") == 0)
reg_info.format = eFormatDecimal;
@@ -350,39 +363,54 @@ ProcessGDBRemote::BuildDynamicRegisterIn
}
else if (name.compare("generic") == 0)
{
- if (value.compare("pc") == 0)
- reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
- else if (value.compare("sp") == 0)
- reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
- else if (value.compare("fp") == 0)
- reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
- else if (value.compare("ra") == 0)
- reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
- else if (value.compare("flags") == 0)
- reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
- else if (value.find("arg") == 0)
+ reg_info.kinds[eRegisterKindGeneric] = Args::StringToGenericRegister (value.c_str());
+ }
+ else if (name.compare("container-regs") == 0)
+ {
+ std::pair<llvm::StringRef, llvm::StringRef> value_pair;
+ value_pair.second = value;
+ do
{
- if (value.size() == 4)
+ value_pair = value_pair.second.split(',');
+ if (!value_pair.first.empty())
{
- switch (value[3])
- {
- case '1': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG1; break;
- case '2': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG2; break;
- case '3': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG3; break;
- case '4': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG4; break;
- case '5': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG5; break;
- case '6': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG6; break;
- case '7': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG7; break;
- case '8': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG8; break;
- }
+ uint32_t reg = Args::StringToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, 16);
+ if (reg != LLDB_INVALID_REGNUM)
+ value_regs.push_back (reg);
}
- }
+ } while (!value_pair.second.empty());
+ }
+ else if (name.compare("invalidate-regs") == 0)
+ {
+ std::pair<llvm::StringRef, llvm::StringRef> value_pair;
+ value_pair.second = value;
+ do
+ {
+ value_pair = value_pair.second.split(',');
+ if (!value_pair.first.empty())
+ {
+ uint32_t reg = Args::StringToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, 16);
+ if (reg != LLDB_INVALID_REGNUM)
+ invalidate_regs.push_back (reg);
+ }
+ } while (!value_pair.second.empty());
}
}
reg_info.byte_offset = reg_offset;
assert (reg_info.byte_size != 0);
reg_offset += reg_info.byte_size;
+ if (!value_regs.empty())
+ {
+ value_regs.push_back(LLDB_INVALID_REGNUM);
+ reg_info.value_regs = value_regs.data();
+ }
+ if (!invalidate_regs.empty())
+ {
+ invalidate_regs.push_back(LLDB_INVALID_REGNUM);
+ reg_info.invalidate_regs = invalidate_regs.data();
+ }
+
m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
}
}
@@ -400,7 +428,16 @@ ProcessGDBRemote::BuildDynamicRegisterIn
bool from_scratch = (reg_num == 0);
const ArchSpec &target_arch = GetTarget().GetArchitecture();
- const ArchSpec &remote_arch = m_gdb_comm.GetHostArchitecture();
+ const ArchSpec &remote_host_arch = m_gdb_comm.GetHostArchitecture();
+ const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
+
+ // Use the process' architecture instead of the host arch, if available
+ ArchSpec remote_arch;
+ if (remote_process_arch.IsValid ())
+ remote_arch = remote_process_arch;
+ else
+ remote_arch = remote_host_arch;
+
if (!target_arch.IsValid())
{
if (remote_arch.IsValid()
@@ -413,11 +450,6 @@ ProcessGDBRemote::BuildDynamicRegisterIn
m_register_info.HardcodeARMRegisters(from_scratch);
}
- // Add some convenience registers (eax, ebx, ecx, edx, esi, edi, ebp, esp) to x86_64.
- if ((target_arch.IsValid() && target_arch.GetMachine() == llvm::Triple::x86_64)
- || (remote_arch.IsValid() && remote_arch.GetMachine() == llvm::Triple::x86_64))
- m_register_info.Addx86_64ConvenienceRegisters();
-
// At this point, we can finalize our register info.
m_register_info.Finalize ();
}
@@ -441,7 +473,7 @@ ProcessGDBRemote::WillAttachToProcessWit
}
Error
-ProcessGDBRemote::DoConnectRemote (const char *remote_url)
+ProcessGDBRemote::DoConnectRemote (Stream *strm, const char *remote_url)
{
Error error (WillLaunchOrAttach ());
@@ -475,17 +507,21 @@ ProcessGDBRemote::DoConnectRemote (const
SetPrivateState (state);
}
else
- error.SetErrorStringWithFormat ("Process %llu was reported after connecting to '%s', but state was not stopped: %s", pid, remote_url, StateAsCString (state));
+ error.SetErrorStringWithFormat ("Process %" PRIu64 " was reported after connecting to '%s', but state was not stopped: %s", pid, remote_url, StateAsCString (state));
}
else
- error.SetErrorStringWithFormat ("Process %llu was reported after connecting to '%s', but no stop reply packet was received", pid, remote_url);
+ error.SetErrorStringWithFormat ("Process %" PRIu64 " was reported after connecting to '%s', but no stop reply packet was received", pid, remote_url);
}
if (error.Success()
&& !GetTarget().GetArchitecture().IsValid()
&& m_gdb_comm.GetHostArchitecture().IsValid())
{
- GetTarget().SetArchitecture(m_gdb_comm.GetHostArchitecture());
+ // Prefer the *process'* architecture over that of the *host*, if available.
+ if (m_gdb_comm.GetProcessArchitecture().IsValid())
+ GetTarget().SetArchitecture(m_gdb_comm.GetProcessArchitecture());
+ else
+ GetTarget().SetArchitecture(m_gdb_comm.GetHostArchitecture());
}
return error;
@@ -536,7 +572,7 @@ ProcessGDBRemote::DoLaunch (Module *exe_
// ::LogSetBitMask (GDBR_LOG_DEFAULT);
// ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE | LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD);
// ::LogSetLogFile ("/dev/stdout");
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
ObjectFile * object_file = exe_module->GetObjectFile();
if (object_file)
@@ -696,7 +732,7 @@ ProcessGDBRemote::ConnectToDebugserver (
{
Error error;
// Sleep and wait a bit for debugserver to start to listen...
- std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
+ std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
if (conn_ap.get())
{
const uint32_t max_retry_count = 50;
@@ -748,7 +784,6 @@ ProcessGDBRemote::ConnectToDebugserver (
for (size_t idx = 0; idx < num_cmds; idx++)
{
StringExtractorGDBRemote response;
- printf ("Sending command: \%s.\n", GetExtraStartupCommands().GetArgumentAtIndex(idx));
m_gdb_comm.SendPacketAndWaitForResponse (GetExtraStartupCommands().GetArgumentAtIndex(idx), response, false);
}
return error;
@@ -757,7 +792,7 @@ ProcessGDBRemote::ConnectToDebugserver (
void
ProcessGDBRemote::DidLaunchOrAttach ()
{
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
if (log)
log->Printf ("ProcessGDBRemote::DidLaunch()");
if (GetID() != LLDB_INVALID_PROCESS_ID)
@@ -768,7 +803,15 @@ ProcessGDBRemote::DidLaunchOrAttach ()
// See if the GDB server supports the qHostInfo information
- const ArchSpec &gdb_remote_arch = m_gdb_comm.GetHostArchitecture();
+ ArchSpec gdb_remote_arch = m_gdb_comm.GetHostArchitecture();
+
+ // See if the GDB server supports the qProcessInfo packet, if so
+ // prefer that over the Host information as it will be more specific
+ // to our process.
+
+ if (m_gdb_comm.GetProcessArchitecture().IsValid())
+ gdb_remote_arch = m_gdb_comm.GetProcessArchitecture();
+
if (gdb_remote_arch.IsValid())
{
ArchSpec &target_arch = GetTarget().GetArchitecture();
@@ -864,7 +907,7 @@ ProcessGDBRemote::DoAttachToProcessWithI
if (error.Success())
{
char packet[64];
- const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%llx", attach_pid);
+ const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%" PRIx64, attach_pid);
SetID (attach_pid);
m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (packet, packet_len));
}
@@ -962,6 +1005,7 @@ ProcessGDBRemote::DidAttach ()
DidLaunchOrAttach ();
}
+
Error
ProcessGDBRemote::WillResume ()
{
@@ -976,7 +1020,7 @@ Error
ProcessGDBRemote::DoResume ()
{
Error error;
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
if (log)
log->Printf ("ProcessGDBRemote::Resume()");
@@ -985,58 +1029,68 @@ ProcessGDBRemote::DoResume ()
{
listener.StartListeningForEvents (&m_async_broadcaster, ProcessGDBRemote::eBroadcastBitAsyncThreadDidExit);
+ const size_t num_threads = GetThreadList().GetSize();
+
StreamString continue_packet;
bool continue_packet_error = false;
if (m_gdb_comm.HasAnyVContSupport ())
{
- continue_packet.PutCString ("vCont");
-
- if (!m_continue_c_tids.empty())
+ if (m_continue_c_tids.size() == num_threads)
{
- if (m_gdb_comm.GetVContSupported ('c'))
- {
- for (tid_collection::const_iterator t_pos = m_continue_c_tids.begin(), t_end = m_continue_c_tids.end(); t_pos != t_end; ++t_pos)
- continue_packet.Printf(";c:%4.4llx", *t_pos);
- }
- else
- continue_packet_error = true;
+ // All threads are continuing, just send a "c" packet
+ continue_packet.PutCString ("c");
}
-
- if (!continue_packet_error && !m_continue_C_tids.empty())
+ else
{
- if (m_gdb_comm.GetVContSupported ('C'))
+ continue_packet.PutCString ("vCont");
+
+ if (!m_continue_c_tids.empty())
+ {
+ if (m_gdb_comm.GetVContSupported ('c'))
+ {
+ for (tid_collection::const_iterator t_pos = m_continue_c_tids.begin(), t_end = m_continue_c_tids.end(); t_pos != t_end; ++t_pos)
+ continue_packet.Printf(";c:%4.4" PRIx64, *t_pos);
+ }
+ else
+ continue_packet_error = true;
+ }
+
+ if (!continue_packet_error && !m_continue_C_tids.empty())
{
- for (tid_sig_collection::const_iterator s_pos = m_continue_C_tids.begin(), s_end = m_continue_C_tids.end(); s_pos != s_end; ++s_pos)
- continue_packet.Printf(";C%2.2x:%4.4llx", s_pos->second, s_pos->first);
+ if (m_gdb_comm.GetVContSupported ('C'))
+ {
+ for (tid_sig_collection::const_iterator s_pos = m_continue_C_tids.begin(), s_end = m_continue_C_tids.end(); s_pos != s_end; ++s_pos)
+ continue_packet.Printf(";C%2.2x:%4.4" PRIx64, s_pos->second, s_pos->first);
+ }
+ else
+ continue_packet_error = true;
}
- else
- continue_packet_error = true;
- }
- if (!continue_packet_error && !m_continue_s_tids.empty())
- {
- if (m_gdb_comm.GetVContSupported ('s'))
+ if (!continue_packet_error && !m_continue_s_tids.empty())
{
- for (tid_collection::const_iterator t_pos = m_continue_s_tids.begin(), t_end = m_continue_s_tids.end(); t_pos != t_end; ++t_pos)
- continue_packet.Printf(";s:%4.4llx", *t_pos);
+ if (m_gdb_comm.GetVContSupported ('s'))
+ {
+ for (tid_collection::const_iterator t_pos = m_continue_s_tids.begin(), t_end = m_continue_s_tids.end(); t_pos != t_end; ++t_pos)
+ continue_packet.Printf(";s:%4.4" PRIx64, *t_pos);
+ }
+ else
+ continue_packet_error = true;
}
- else
- continue_packet_error = true;
- }
-
- if (!continue_packet_error && !m_continue_S_tids.empty())
- {
- if (m_gdb_comm.GetVContSupported ('S'))
+
+ if (!continue_packet_error && !m_continue_S_tids.empty())
{
- for (tid_sig_collection::const_iterator s_pos = m_continue_S_tids.begin(), s_end = m_continue_S_tids.end(); s_pos != s_end; ++s_pos)
- continue_packet.Printf(";S%2.2x:%4.4llx", s_pos->second, s_pos->first);
+ if (m_gdb_comm.GetVContSupported ('S'))
+ {
+ for (tid_sig_collection::const_iterator s_pos = m_continue_S_tids.begin(), s_end = m_continue_S_tids.end(); s_pos != s_end; ++s_pos)
+ continue_packet.Printf(";S%2.2x:%4.4" PRIx64, s_pos->second, s_pos->first);
+ }
+ else
+ continue_packet_error = true;
}
- else
- continue_packet_error = true;
+
+ if (continue_packet_error)
+ continue_packet.GetString().clear();
}
-
- if (continue_packet_error)
- continue_packet.GetString().clear();
}
else
continue_packet_error = true;
@@ -1046,7 +1100,6 @@ ProcessGDBRemote::DoResume ()
// Either no vCont support, or we tried to use part of the vCont
// packet that wasn't supported by the remote GDB server.
// We need to try and make a simple packet that can do our continue
- const size_t num_threads = GetThreadList().GetSize();
const size_t num_continue_c_tids = m_continue_c_tids.size();
const size_t num_continue_C_tids = m_continue_C_tids.size();
const size_t num_continue_s_tids = m_continue_s_tids.size();
@@ -1212,14 +1265,14 @@ ProcessGDBRemote::DoResume ()
void
ProcessGDBRemote::ClearThreadIDList ()
{
- Mutex::Locker locker(m_thread_list.GetMutex());
+ Mutex::Locker locker(m_thread_list_real.GetMutex());
m_thread_ids.clear();
}
bool
ProcessGDBRemote::UpdateThreadIDList ()
{
- Mutex::Locker locker(m_thread_list.GetMutex());
+ Mutex::Locker locker(m_thread_list_real.GetMutex());
bool sequence_mutex_unavailable = false;
m_gdb_comm.GetCurrentThreadIDs (m_thread_ids, sequence_mutex_unavailable);
if (sequence_mutex_unavailable)
@@ -1233,9 +1286,9 @@ bool
ProcessGDBRemote::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
{
// locker will keep a mutex locked until it goes out of scope
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_THREAD));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_THREAD));
if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
- log->Printf ("ProcessGDBRemote::%s (pid = %llu)", __FUNCTION__, GetID());
+ log->Printf ("ProcessGDBRemote::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID());
size_t num_thread_ids = m_thread_ids.size();
// The "m_thread_ids" thread ID list should always be updated after each stop
@@ -1247,18 +1300,32 @@ ProcessGDBRemote::UpdateThreadList (Thre
num_thread_ids = m_thread_ids.size();
}
+ ThreadList old_thread_list_copy(old_thread_list);
if (num_thread_ids > 0)
{
for (size_t i=0; i<num_thread_ids; ++i)
{
tid_t tid = m_thread_ids[i];
- ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
+ ThreadSP thread_sp (old_thread_list_copy.RemoveThreadByProtocolID(tid, false));
if (!thread_sp)
- thread_sp.reset (new ThreadGDBRemote (shared_from_this(), tid));
+ thread_sp.reset (new ThreadGDBRemote (*this, tid));
new_thread_list.AddThread(thread_sp);
}
}
-
+
+ // Whatever that is left in old_thread_list_copy are not
+ // present in new_thread_list. Remove non-existent threads from internal id table.
+ size_t old_num_thread_ids = old_thread_list_copy.GetSize(false);
+ for (size_t i=0; i<old_num_thread_ids; i++)
+ {
+ ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex (i, false));
+ if (old_thread_sp)
+ {
+ lldb::tid_t old_thread_id = old_thread_sp->GetProtocolID();
+ m_thread_id_to_index_id_map.erase(old_thread_id);
+ }
+ }
+
return true;
}
@@ -1273,7 +1340,13 @@ ProcessGDBRemote::SetThreadStopInfo (Str
case 'T':
case 'S':
{
- if (GetStopID() == 0)
+ // This is a bit of a hack, but is is required. If we did exec, we
+ // need to clear our thread lists and also know to rebuild our dynamic
+ // register info before we lookup and threads and populate the expedited
+ // register values so we need to know this right away so we can cleanup
+ // and update our registers.
+ const uint32_t stop_id = GetStopID();
+ if (stop_id == 0)
{
// Our first stop, make sure we have a process ID, and also make
// sure we know about our registers
@@ -1296,6 +1369,7 @@ ProcessGDBRemote::SetThreadStopInfo (Str
std::vector<addr_t> exc_data;
addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
ThreadSP thread_sp;
+ ThreadGDBRemote *gdb_thread = NULL;
while (stop_packet.GetNameColonValue(name, value))
{
@@ -1313,21 +1387,24 @@ ProcessGDBRemote::SetThreadStopInfo (Str
{
// thread in big endian hex
lldb::tid_t tid = Args::StringToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
- // m_thread_list does have its own mutex, but we need to
- // hold onto the mutex between the call to m_thread_list.FindThreadByID(...)
- // and the m_thread_list.AddThread(...) so it doesn't change on us
- Mutex::Locker locker (m_thread_list.GetMutex ());
- thread_sp = m_thread_list.FindThreadByID(tid, false);
+ // m_thread_list_real does have its own mutex, but we need to
+ // hold onto the mutex between the call to m_thread_list_real.FindThreadByID(...)
+ // and the m_thread_list_real.AddThread(...) so it doesn't change on us
+ Mutex::Locker locker (m_thread_list_real.GetMutex ());
+ thread_sp = m_thread_list_real.FindThreadByProtocolID(tid, false);
+
if (!thread_sp)
{
// Create the thread if we need to
- thread_sp.reset (new ThreadGDBRemote (shared_from_this(), tid));
- m_thread_list.AddThread(thread_sp);
+ thread_sp.reset (new ThreadGDBRemote (*this, tid));
+ m_thread_list_real.AddThread(thread_sp);
}
+ gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
+
}
else if (name.compare("threads") == 0)
{
- Mutex::Locker locker(m_thread_list.GetMutex());
+ Mutex::Locker locker(m_thread_list_real.GetMutex());
m_thread_ids.clear();
// A comma separated list of all threads in the current
// process that includes the thread for this stop reply
@@ -1382,7 +1459,7 @@ ProcessGDBRemote::SetThreadStopInfo (Str
// We have a register number that contains an expedited
// register value. Lets supply this register to our thread
// so it won't have to go and read it.
- if (thread_sp)
+ if (gdb_thread)
{
uint32_t reg = Args::StringToUInt32 (name.c_str(), UINT32_MAX, 16);
@@ -1391,7 +1468,7 @@ ProcessGDBRemote::SetThreadStopInfo (Str
StringExtractor reg_value_extractor;
// Swap "value" over into "reg_value_extractor"
reg_value_extractor.GetStringRef().swap(value);
- if (!static_cast<ThreadGDBRemote *> (thread_sp.get())->PrivateSetRegisterValue (reg, reg_value_extractor))
+ if (!gdb_thread->PrivateSetRegisterValue (reg, reg_value_extractor))
{
Host::SetCrashDescriptionWithFormat("Setting thread register '%s' (decoded to %u (0x%x)) with value '%s' for stop packet: '%s'",
name.c_str(),
@@ -1407,7 +1484,8 @@ ProcessGDBRemote::SetThreadStopInfo (Str
if (thread_sp)
{
- ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
+ // Clear the stop info just in case we don't set it to anything
+ thread_sp->SetStopInfo (StopInfoSP());
gdb_thread->SetThreadDispatchQAddr (thread_dispatch_qaddr);
gdb_thread->SetName (thread_name.empty() ? NULL : thread_name.c_str());
@@ -1415,41 +1493,42 @@ ProcessGDBRemote::SetThreadStopInfo (Str
{
const size_t exc_data_size = exc_data.size();
- gdb_thread->SetStopInfo (StopInfoMachException::CreateStopReasonWithMachException (*thread_sp,
- exc_type,
- exc_data_size,
- exc_data_size >= 1 ? exc_data[0] : 0,
- exc_data_size >= 2 ? exc_data[1] : 0,
- exc_data_size >= 3 ? exc_data[2] : 0));
+ thread_sp->SetStopInfo (StopInfoMachException::CreateStopReasonWithMachException (*thread_sp,
+ exc_type,
+ exc_data_size,
+ exc_data_size >= 1 ? exc_data[0] : 0,
+ exc_data_size >= 2 ? exc_data[1] : 0,
+ exc_data_size >= 3 ? exc_data[2] : 0));
}
else
{
bool handled = false;
+ bool did_exec = false;
if (!reason.empty())
{
if (reason.compare("trace") == 0)
{
- gdb_thread->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
handled = true;
}
else if (reason.compare("breakpoint") == 0)
{
- addr_t pc = gdb_thread->GetRegisterContext()->GetPC();
- lldb::BreakpointSiteSP bp_site_sp = gdb_thread->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
+ addr_t pc = thread_sp->GetRegisterContext()->GetPC();
+ lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
if (bp_site_sp)
{
// If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
// we can just report no reason. We don't need to worry about stepping over the breakpoint here, that
// will be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
handled = true;
- if (bp_site_sp->ValidForThisThread (gdb_thread))
+ if (bp_site_sp->ValidForThisThread (thread_sp.get()))
{
- gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID()));
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID()));
}
else
{
StopInfoSP invalid_stop_info_sp;
- gdb_thread->SetStopInfo (invalid_stop_info_sp);
+ thread_sp->SetStopInfo (invalid_stop_info_sp);
}
}
@@ -1462,67 +1541,72 @@ ProcessGDBRemote::SetThreadStopInfo (Str
{
break_id_t watch_id = LLDB_INVALID_WATCH_ID;
// TODO: locate the watchpoint somehow...
- gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID (*thread_sp, watch_id));
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID (*thread_sp, watch_id));
handled = true;
}
else if (reason.compare("exception") == 0)
{
- gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithException(*thread_sp, description.c_str()));
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithException(*thread_sp, description.c_str()));
+ handled = true;
+ }
+ else if (reason.compare("exec") == 0)
+ {
+ did_exec = true;
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithExec(*thread_sp));
handled = true;
}
}
- if (signo)
+ if (signo && did_exec == false)
{
if (signo == SIGTRAP)
{
// Currently we are going to assume SIGTRAP means we are either
// hitting a breakpoint or hardware single stepping.
handled = true;
- addr_t pc = gdb_thread->GetRegisterContext()->GetPC();
- lldb::BreakpointSiteSP bp_site_sp = gdb_thread->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
+ addr_t pc = thread_sp->GetRegisterContext()->GetPC();
+ lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
if (bp_site_sp)
{
// If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
// we can just report no reason. We don't need to worry about stepping over the breakpoint here, that
// will be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
- if (bp_site_sp->ValidForThisThread (gdb_thread))
+ if (bp_site_sp->ValidForThisThread (thread_sp.get()))
{
- gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID()));
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID()));
}
else
{
StopInfoSP invalid_stop_info_sp;
- gdb_thread->SetStopInfo (invalid_stop_info_sp);
+ thread_sp->SetStopInfo (invalid_stop_info_sp);
}
}
else
{
- // TODO: check for breakpoint or trap opcode in case there is a hard
- // coded software trap
- gdb_thread->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
+ // If we were stepping then assume the stop was the result of the trace. If we were
+ // not stepping then report the SIGTRAP.
+ // FIXME: We are still missing the case where we single step over a trap instruction.
+ if (thread_sp->GetTemporaryResumeState() == eStateStepping)
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
+ else
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithSignal(*thread_sp, signo));
}
}
if (!handled)
- gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithSignal (*thread_sp, signo));
- }
- else
- {
- StopInfoSP invalid_stop_info_sp;
- gdb_thread->SetStopInfo (invalid_stop_info_sp);
- }
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithSignal (*thread_sp, signo));
+ }
if (!description.empty())
{
- lldb::StopInfoSP stop_info_sp (gdb_thread->GetStopInfo ());
+ lldb::StopInfoSP stop_info_sp (thread_sp->GetStopInfo ());
if (stop_info_sp)
{
stop_info_sp->SetDescription (description.c_str());
}
else
{
- gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithException (*thread_sp, description.c_str()));
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithException (*thread_sp, description.c_str()));
}
}
}
@@ -1544,7 +1628,7 @@ ProcessGDBRemote::SetThreadStopInfo (Str
void
ProcessGDBRemote::RefreshStateAfterStop ()
{
- Mutex::Locker locker(m_thread_list.GetMutex());
+ Mutex::Locker locker(m_thread_list_real.GetMutex());
m_thread_ids.clear();
// Set the thread stop info. It might have a "threads" key whose value is
// a list of all thread IDs in the current process, so m_thread_ids might
@@ -1559,7 +1643,7 @@ ProcessGDBRemote::RefreshStateAfterStop
// Let all threads recover from stopping and do any clean up based
// on the previous thread state (if any).
- m_thread_list.RefreshStateAfterStop();
+ m_thread_list_real.RefreshStateAfterStop();
}
@@ -1593,118 +1677,29 @@ ProcessGDBRemote::DoHalt (bool &caused_s
}
Error
-ProcessGDBRemote::InterruptIfRunning
-(
- bool discard_thread_plans,
- bool catch_stop_event,
- EventSP &stop_event_sp
-)
+ProcessGDBRemote::DoDetach(bool keep_stopped)
{
Error error;
-
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
-
- bool paused_private_state_thread = false;
- const bool is_running = m_gdb_comm.IsRunning();
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
if (log)
- log->Printf ("ProcessGDBRemote::InterruptIfRunning(discard_thread_plans=%i, catch_stop_event=%i) is_running=%i",
- discard_thread_plans,
- catch_stop_event,
- is_running);
-
- if (discard_thread_plans)
- {
- if (log)
- log->Printf ("ProcessGDBRemote::InterruptIfRunning() discarding all thread plans");
- m_thread_list.DiscardThreadPlans();
- }
- if (is_running)
- {
- if (catch_stop_event)
- {
- if (log)
- log->Printf ("ProcessGDBRemote::InterruptIfRunning() pausing private state thread");
- PausePrivateStateThread();
- paused_private_state_thread = true;
- }
-
- bool timed_out = false;
- Mutex::Locker locker;
-
- if (!m_gdb_comm.SendInterrupt (locker, 1, timed_out))
- {
- if (timed_out)
- error.SetErrorString("timed out sending interrupt packet");
- else
- error.SetErrorString("unknown error sending interrupt packet");
- if (paused_private_state_thread)
- ResumePrivateStateThread();
- return error;
- }
-
- if (catch_stop_event)
- {
- // LISTEN HERE
- TimeValue timeout_time;
- timeout_time = TimeValue::Now();
- timeout_time.OffsetWithSeconds(5);
- StateType state = WaitForStateChangedEventsPrivate (&timeout_time, stop_event_sp);
-
- timed_out = state == eStateInvalid;
- if (log)
- log->Printf ("ProcessGDBRemote::InterruptIfRunning() catch stop event: state = %s, timed-out=%i", StateAsCString(state), timed_out);
-
- if (timed_out)
- error.SetErrorString("unable to verify target stopped");
- }
-
- if (paused_private_state_thread)
- {
- if (log)
- log->Printf ("ProcessGDBRemote::InterruptIfRunning() resuming private state thread");
- ResumePrivateStateThread();
- }
- }
- return error;
-}
-
-Error
-ProcessGDBRemote::WillDetach ()
-{
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessGDBRemote::WillDetach()");
-
- bool discard_thread_plans = true;
- bool catch_stop_event = true;
- EventSP event_sp;
-
- // FIXME: InterruptIfRunning should be done in the Process base class, or better still make Halt do what is
- // needed. This shouldn't be a feature of a particular plugin.
-
- return InterruptIfRunning (discard_thread_plans, catch_stop_event, event_sp);
-}
-
-Error
-ProcessGDBRemote::DoDetach()
-{
- Error error;
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessGDBRemote::DoDetach()");
-
+ log->Printf ("ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
+
DisableAllBreakpointSites ();
m_thread_list.DiscardThreadPlans();
- bool success = m_gdb_comm.Detach ();
+ error = m_gdb_comm.Detach (keep_stopped);
if (log)
{
- if (success)
+ if (error.Success())
log->PutCString ("ProcessGDBRemote::DoDetach() detach packet sent successfully");
else
- log->PutCString ("ProcessGDBRemote::DoDetach() detach packet send failed");
+ log->Printf ("ProcessGDBRemote::DoDetach() detach packet send failed: %s", error.AsCString() ? error.AsCString() : "<unknown error>");
}
+
+ if (!error.Success())
+ return error;
+
// Sleep for one second to let the process get all detached...
StopAsyncThread ();
@@ -1720,7 +1715,7 @@ Error
ProcessGDBRemote::DoDestroy ()
{
Error error;
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
if (log)
log->Printf ("ProcessGDBRemote::DoDestroy()");
@@ -1748,7 +1743,7 @@ ProcessGDBRemote::DoDestroy ()
// FIXME: These should be ConstStrings so we aren't doing strcmp'ing.
if (platform_sp
&& platform_sp->GetName()
- && strcmp (platform_sp->GetName(), PlatformRemoteiOS::GetShortPluginNameStatic()) == 0)
+ && platform_sp->GetName() == PlatformRemoteiOS::GetPluginNameStatic())
{
if (m_destroy_tried_resuming)
{
@@ -1766,13 +1761,13 @@ ProcessGDBRemote::DoDestroy ()
ThreadList &threads = GetThreadList();
{
- Mutex::Locker(threads.GetMutex());
+ Mutex::Locker locker(threads.GetMutex());
size_t num_threads = threads.GetSize();
for (size_t i = 0; i < num_threads; i++)
{
ThreadSP thread_sp = threads.GetThreadAtIndex(i);
- StopInfoSP stop_info_sp = thread_sp->GetPrivateStopReason();
+ StopInfoSP stop_info_sp = thread_sp->GetPrivateStopInfo();
StopReason reason = eStopReasonInvalid;
if (stop_info_sp)
reason = stop_info_sp->GetStopReason();
@@ -1780,8 +1775,8 @@ ProcessGDBRemote::DoDestroy ()
|| reason == eStopReasonException)
{
if (log)
- log->Printf ("ProcessGDBRemote::DoDestroy() - thread: %lld stopped with reason: %s.",
- thread_sp->GetID(),
+ log->Printf ("ProcessGDBRemote::DoDestroy() - thread: 0x%4.4" PRIx64 " stopped with reason: %s.",
+ thread_sp->GetProtocolID(),
stop_info_sp->GetDescription());
stop_looks_like_crash = true;
break;
@@ -1801,13 +1796,13 @@ ProcessGDBRemote::DoDestroy ()
// have to run the risk of letting those threads proceed a bit.
{
- Mutex::Locker(threads.GetMutex());
+ Mutex::Locker locker(threads.GetMutex());
size_t num_threads = threads.GetSize();
for (size_t i = 0; i < num_threads; i++)
{
ThreadSP thread_sp = threads.GetThreadAtIndex(i);
- StopInfoSP stop_info_sp = thread_sp->GetPrivateStopReason();
+ StopInfoSP stop_info_sp = thread_sp->GetPrivateStopInfo();
StopReason reason = eStopReasonInvalid;
if (stop_info_sp)
reason = stop_info_sp->GetStopReason();
@@ -1815,8 +1810,8 @@ ProcessGDBRemote::DoDestroy ()
&& reason != eStopReasonException)
{
if (log)
- log->Printf ("ProcessGDBRemote::DoDestroy() - Suspending thread: %lld before running.",
- thread_sp->GetID());
+ log->Printf ("ProcessGDBRemote::DoDestroy() - Suspending thread: 0x%4.4" PRIx64 " before running.",
+ thread_sp->GetProtocolID());
thread_sp->SetResumeState(eStateSuspended);
}
}
@@ -1839,6 +1834,8 @@ ProcessGDBRemote::DoDestroy ()
StringExtractorGDBRemote response;
bool send_async = true;
+ const uint32_t old_packet_timeout = m_gdb_comm.SetPacketTimeout (3);
+
if (m_gdb_comm.SendPacketAndWaitForResponse("k", 1, response, send_async))
{
char packet_cmd = response.GetChar(0);
@@ -1863,6 +1860,8 @@ ProcessGDBRemote::DoDestroy ()
log->Printf ("ProcessGDBRemote::DoDestroy - failed to send k packet");
exit_string.assign("failed to send the k packet");
}
+
+ m_gdb_comm.SetPacketTimeout(old_packet_timeout);
}
else
{
@@ -1885,6 +1884,26 @@ ProcessGDBRemote::DoDestroy ()
return error;
}
+void
+ProcessGDBRemote::SetLastStopPacket (const StringExtractorGDBRemote &response)
+{
+ lldb_private::Mutex::Locker locker (m_last_stop_packet_mutex);
+ const bool did_exec = response.GetStringRef().find(";reason:exec;") != std::string::npos;
+ if (did_exec)
+ {
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf ("ProcessGDBRemote::SetLastStopPacket () - detected exec");
+
+ m_thread_list_real.Clear();
+ m_thread_list.Clear();
+ BuildDynamicRegisterInfo (true);
+ m_gdb_comm.ResetDiscoverableSettings();
+ }
+ m_last_stop_packet = response;
+}
+
+
//------------------------------------------------------------------
// Process Queries
//------------------------------------------------------------------
@@ -1916,7 +1935,7 @@ ProcessGDBRemote::DoReadMemory (addr_t a
}
char packet[64];
- const int packet_len = ::snprintf (packet, sizeof(packet), "m%llx,%zx", (uint64_t)addr, size);
+ const int packet_len = ::snprintf (packet, sizeof(packet), "m%" PRIx64 ",%" PRIx64, (uint64_t)addr, (uint64_t)size);
assert (packet_len + 1 < sizeof(packet));
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true))
@@ -1927,15 +1946,15 @@ ProcessGDBRemote::DoReadMemory (addr_t a
return response.GetHexBytes(buf, size, '\xdd');
}
else if (response.IsErrorResponse())
- error.SetErrorStringWithFormat("gdb remote returned an error: %s", response.GetStringRef().c_str());
+ error.SetErrorStringWithFormat("memory read failed for 0x%" PRIx64, addr);
else if (response.IsUnsupportedResponse())
- error.SetErrorStringWithFormat("'%s' packet unsupported", packet);
+ error.SetErrorStringWithFormat("GDB server does not support reading memory");
else
- error.SetErrorStringWithFormat("unexpected response to '%s': '%s'", packet, response.GetStringRef().c_str());
+ error.SetErrorStringWithFormat("unexpected response to GDB server memory read packet '%s': '%s'", packet, response.GetStringRef().c_str());
}
else
{
- error.SetErrorStringWithFormat("failed to sent packet: '%s'", packet);
+ error.SetErrorStringWithFormat("failed to send packet: '%s'", packet);
}
return 0;
}
@@ -1952,7 +1971,7 @@ ProcessGDBRemote::DoWriteMemory (addr_t
}
StreamString packet;
- packet.Printf("M%llx,%zx:", addr, size);
+ packet.Printf("M%" PRIx64 ",%" PRIx64 ":", addr, (uint64_t)size);
packet.PutBytesAsRawHex8(buf, size, lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder());
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, true))
@@ -1963,15 +1982,15 @@ ProcessGDBRemote::DoWriteMemory (addr_t
return size;
}
else if (response.IsErrorResponse())
- error.SetErrorStringWithFormat("gdb remote returned an error: %s", response.GetStringRef().c_str());
+ error.SetErrorStringWithFormat("memory write failed for 0x%" PRIx64, addr);
else if (response.IsUnsupportedResponse())
- error.SetErrorStringWithFormat("'%s' packet unsupported", packet.GetString().c_str());
+ error.SetErrorStringWithFormat("GDB server does not support writing memory");
else
- error.SetErrorStringWithFormat("unexpected response to '%s': '%s'", packet.GetString().c_str(), response.GetStringRef().c_str());
+ error.SetErrorStringWithFormat("unexpected response to GDB server memory write packet '%s': '%s'", packet.GetString().c_str(), response.GetStringRef().c_str());
}
else
{
- error.SetErrorStringWithFormat("failed to sent packet: '%s'", packet.GetString().c_str());
+ error.SetErrorStringWithFormat("failed to send packet: '%s'", packet.GetString().c_str());
}
return 0;
}
@@ -2009,7 +2028,7 @@ ProcessGDBRemote::DoAllocateMemory (size
}
if (allocated_addr == LLDB_INVALID_ADDRESS)
- error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
+ error.SetErrorStringWithFormat("unable to allocate %" PRIu64 " bytes of memory with permissions %s", (uint64_t)size, GetPermissionsAsCString (permissions));
else
error.Clear();
return allocated_addr;
@@ -2055,7 +2074,7 @@ ProcessGDBRemote::DoDeallocateMemory (ll
case eLazyBoolYes:
if (!m_gdb_comm.DeallocateMemory (addr))
- error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr);
+ error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
break;
case eLazyBoolNo:
@@ -2066,7 +2085,7 @@ ProcessGDBRemote::DoDeallocateMemory (ll
InferiorCallMunmap(this, addr, pos->second))
m_addr_to_mmap_size.erase (pos);
else
- error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr);
+ error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
}
break;
}
@@ -2090,21 +2109,21 @@ ProcessGDBRemote::PutSTDIN (const char *
}
Error
-ProcessGDBRemote::EnableBreakpoint (BreakpointSite *bp_site)
+ProcessGDBRemote::EnableBreakpointSite (BreakpointSite *bp_site)
{
Error error;
assert (bp_site != NULL);
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
user_id_t site_id = bp_site->GetID();
const addr_t addr = bp_site->GetLoadAddress();
if (log)
- log->Printf ("ProcessGDBRemote::EnableBreakpoint (size_id = %llu) address = 0x%llx", site_id, (uint64_t)addr);
+ log->Printf ("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64 ") address = 0x%" PRIx64, site_id, (uint64_t)addr);
if (bp_site->IsEnabled())
{
if (log)
- log->Printf ("ProcessGDBRemote::EnableBreakpoint (size_id = %llu) address = 0x%llx -- SUCCESS (already enabled)", site_id, (uint64_t)addr);
+ log->Printf ("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64 ") address = 0x%" PRIx64 " -- SUCCESS (already enabled)", site_id, (uint64_t)addr);
return error;
}
else
@@ -2142,7 +2161,7 @@ ProcessGDBRemote::EnableBreakpoint (Brea
if (log)
{
const char *err_string = error.AsCString();
- log->Printf ("ProcessGDBRemote::EnableBreakpoint() error for breakpoint at 0x%8.8llx: %s",
+ log->Printf ("ProcessGDBRemote::EnableBreakpointSite () error for breakpoint at 0x%8.8" PRIx64 ": %s",
bp_site->GetLoadAddress(),
err_string ? err_string : "NULL");
}
@@ -2153,15 +2172,15 @@ ProcessGDBRemote::EnableBreakpoint (Brea
}
Error
-ProcessGDBRemote::DisableBreakpoint (BreakpointSite *bp_site)
+ProcessGDBRemote::DisableBreakpointSite (BreakpointSite *bp_site)
{
Error error;
assert (bp_site != NULL);
addr_t addr = bp_site->GetLoadAddress();
user_id_t site_id = bp_site->GetID();
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
if (log)
- log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %llu) addr = 0x%8.8llx", site_id, (uint64_t)addr);
+ log->Printf ("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64 ") addr = 0x%8.8" PRIx64, site_id, (uint64_t)addr);
if (bp_site->IsEnabled())
{
@@ -2190,7 +2209,7 @@ ProcessGDBRemote::DisableBreakpoint (Bre
else
{
if (log)
- log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %llu) addr = 0x%8.8llx -- SUCCESS (already disabled)", site_id, (uint64_t)addr);
+ log->Printf ("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64 ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)", site_id, (uint64_t)addr);
return error;
}
@@ -2218,20 +2237,20 @@ GetGDBStoppointType (Watchpoint *wp)
}
Error
-ProcessGDBRemote::EnableWatchpoint (Watchpoint *wp)
+ProcessGDBRemote::EnableWatchpoint (Watchpoint *wp, bool notify)
{
Error error;
if (wp)
{
user_id_t watchID = wp->GetID();
addr_t addr = wp->GetLoadAddress();
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
if (log)
- log->Printf ("ProcessGDBRemote::EnableWatchpoint(watchID = %llu)", watchID);
+ log->Printf ("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")", watchID);
if (wp->IsEnabled())
{
if (log)
- log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %llu) addr = 0x%8.8llx: watchpoint already enabled.", watchID, (uint64_t)addr);
+ log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.", watchID, (uint64_t)addr);
return error;
}
@@ -2241,7 +2260,7 @@ ProcessGDBRemote::EnableWatchpoint (Watc
{
if (m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr, wp->GetByteSize()) == 0)
{
- wp->SetEnabled(true);
+ wp->SetEnabled(true, notify);
return error;
}
else
@@ -2260,23 +2279,28 @@ ProcessGDBRemote::EnableWatchpoint (Watc
}
Error
-ProcessGDBRemote::DisableWatchpoint (Watchpoint *wp)
+ProcessGDBRemote::DisableWatchpoint (Watchpoint *wp, bool notify)
{
Error error;
if (wp)
{
user_id_t watchID = wp->GetID();
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
addr_t addr = wp->GetLoadAddress();
+
if (log)
- log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %llu) addr = 0x%8.8llx", watchID, (uint64_t)addr);
+ log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64 ") addr = 0x%8.8" PRIx64, watchID, (uint64_t)addr);
if (!wp->IsEnabled())
{
if (log)
- log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %llu) addr = 0x%8.8llx -- SUCCESS (already disabled)", watchID, (uint64_t)addr);
+ log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64 ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)", watchID, (uint64_t)addr);
+ // See also 'class WatchpointSentry' within StopInfo.cpp.
+ // This disabling attempt might come from the user-supplied actions, we'll route it in order for
+ // the watchpoint object to intelligently process this action.
+ wp->SetEnabled(false, notify);
return error;
}
@@ -2286,7 +2310,7 @@ ProcessGDBRemote::DisableWatchpoint (Wat
// Pass down an appropriate z/Z packet...
if (m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr, wp->GetByteSize()) == 0)
{
- wp->SetEnabled(false);
+ wp->SetEnabled(false, notify);
return error;
}
else
@@ -2307,6 +2331,7 @@ void
ProcessGDBRemote::Clear()
{
m_flags = 0;
+ m_thread_list_real.Clear();
m_thread_list.Clear();
}
@@ -2314,7 +2339,7 @@ Error
ProcessGDBRemote::DoSignal (int signo)
{
Error error;
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
if (log)
log->Printf ("ProcessGDBRemote::DoSignal (signal = %d)", signo);
@@ -2377,7 +2402,7 @@ ProcessGDBRemote::StartDebugserverProces
m_stdio_communication.Clear();
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Args &debugserver_args = debugserver_launch_info.GetArguments();
char arg_cstr[PATH_MAX];
@@ -2466,7 +2491,7 @@ ProcessGDBRemote::StartDebugserverProces
m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
if (error.Fail() || log)
- error.PutToLog(log.get(), "Host::LaunchProcess (launch_info) => pid=%llu, path='%s'", m_debugserver_pid, debugserver_path);
+ error.PutToLog(log, "Host::LaunchProcess (launch_info) => pid=%" PRIu64 ", path='%s'", m_debugserver_pid, debugserver_path);
}
else
{
@@ -2501,7 +2526,7 @@ ProcessGDBRemote::MonitorDebugserverProc
// "debugserver_pid" argument passed in is the process ID for
// debugserver that we are tracking...
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
ProcessGDBRemote *process = (ProcessGDBRemote *)callback_baton;
@@ -2511,7 +2536,7 @@ ProcessGDBRemote::MonitorDebugserverProc
TargetSP target_sp (Debugger::FindTargetWithProcess(process));
if (log)
- log->Printf ("ProcessGDBRemote::MonitorDebugserverProcess (baton=%p, pid=%llu, signo=%i (0x%x), exit_status=%i)", callback_baton, debugserver_pid, signo, signo, exit_status);
+ log->Printf ("ProcessGDBRemote::MonitorDebugserverProcess (baton=%p, pid=%" PRIu64 ", signo=%i (0x%x), exit_status=%i)", callback_baton, debugserver_pid, signo, signo, exit_status);
if (target_sp)
{
@@ -2602,34 +2627,65 @@ ProcessGDBRemote::Initialize()
bool
ProcessGDBRemote::StartAsyncThread ()
{
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
if (log)
log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
-
- // Create a thread that watches our internal state and controls which
- // events make it to clients (into the DCProcess event queue).
- m_async_thread = Host::ThreadCreate ("<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this, NULL);
- return IS_VALID_LLDB_HOST_THREAD(m_async_thread);
+
+ Mutex::Locker start_locker(m_async_thread_state_mutex);
+ if (m_async_thread_state == eAsyncThreadNotStarted)
+ {
+ // Create a thread that watches our internal state and controls which
+ // events make it to clients (into the DCProcess event queue).
+ m_async_thread = Host::ThreadCreate ("<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this, NULL);
+ if (IS_VALID_LLDB_HOST_THREAD(m_async_thread))
+ {
+ m_async_thread_state = eAsyncThreadRunning;
+ return true;
+ }
+ else
+ return false;
+ }
+ else
+ {
+ // Somebody tried to start the async thread while it was either being started or stopped. If the former, and
+ // it started up successfully, then say all's well. Otherwise it is an error, since we aren't going to restart it.
+ if (log)
+ log->Printf ("ProcessGDBRemote::%s () - Called when Async thread was in state: %d.", __FUNCTION__, m_async_thread_state);
+ if (m_async_thread_state == eAsyncThreadRunning)
+ return true;
+ else
+ return false;
+ }
}
void
ProcessGDBRemote::StopAsyncThread ()
{
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
if (log)
log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
- m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
-
- // This will shut down the async thread.
- m_gdb_comm.Disconnect(); // Disconnect from the debug server.
+ Mutex::Locker start_locker(m_async_thread_state_mutex);
+ if (m_async_thread_state == eAsyncThreadRunning)
+ {
+ m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
+
+ // This will shut down the async thread.
+ m_gdb_comm.Disconnect(); // Disconnect from the debug server.
- // Stop the stdio thread
- if (IS_VALID_LLDB_HOST_THREAD(m_async_thread))
+ // Stop the stdio thread
+ if (IS_VALID_LLDB_HOST_THREAD(m_async_thread))
+ {
+ Host::ThreadJoin (m_async_thread, NULL, NULL);
+ }
+ m_async_thread_state = eAsyncThreadDone;
+ }
+ else
{
- Host::ThreadJoin (m_async_thread, NULL, NULL);
+ if (log)
+ log->Printf ("ProcessGDBRemote::%s () - Called when Async thread was in state: %d.", __FUNCTION__, m_async_thread_state);
}
}
@@ -2639,9 +2695,9 @@ ProcessGDBRemote::AsyncThread (void *arg
{
ProcessGDBRemote *process = (ProcessGDBRemote*) arg;
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) thread starting...", __FUNCTION__, arg, process->GetID());
+ log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") thread starting...", __FUNCTION__, arg, process->GetID());
Listener listener ("ProcessGDBRemote::AsyncThread");
EventSP event_sp;
@@ -2656,14 +2712,14 @@ ProcessGDBRemote::AsyncThread (void *arg
while (!done)
{
if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID());
+ log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID());
if (listener.WaitForEvent (NULL, event_sp))
{
const uint32_t event_type = event_sp->GetType();
if (event_sp->BroadcasterIs (&process->m_async_broadcaster))
{
if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) Got an event of type: %d...", __FUNCTION__, arg, process->GetID(), event_type);
+ log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") Got an event of type: %d...", __FUNCTION__, arg, process->GetID(), event_type);
switch (event_type)
{
@@ -2676,7 +2732,7 @@ ProcessGDBRemote::AsyncThread (void *arg
const char *continue_cstr = (const char *)continue_packet->GetBytes ();
const size_t continue_cstr_len = continue_packet->GetByteSize ();
if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr);
+ log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr);
if (::strstr (continue_cstr, "vAttach") == NULL)
process->SetPrivateState(eStateRunning);
@@ -2720,13 +2776,13 @@ ProcessGDBRemote::AsyncThread (void *arg
case eBroadcastBitAsyncThreadShouldExit:
if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID());
+ log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID());
done = true;
break;
default:
if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
+ log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
done = true;
break;
}
@@ -2743,14 +2799,14 @@ ProcessGDBRemote::AsyncThread (void *arg
else
{
if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID());
+ log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID());
done = true;
}
}
}
if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) thread exiting...", __FUNCTION__, arg, process->GetID());
+ log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") thread exiting...", __FUNCTION__, arg, process->GetID());
process->m_async_thread = LLDB_INVALID_HOST_THREAD;
return NULL;
@@ -2801,26 +2857,43 @@ ProcessGDBRemote::GetDispatchQueueNameFo
struct dispatch_queue_offsets_s
{
uint16_t dqo_version;
- uint16_t dqo_label;
- uint16_t dqo_label_size;
+ uint16_t dqo_label; // in version 1-3, offset to string; in version 4+, offset to a pointer to a string
+ uint16_t dqo_label_size; // in version 1-3, length of string; in version 4+, size of a (void*) in this process
} dispatch_queue_offsets;
Error error;
if (ReadMemory (m_dispatch_queue_offsets_addr, memory_buffer, sizeof(dispatch_queue_offsets), error) == sizeof(dispatch_queue_offsets))
{
- uint32_t data_offset = 0;
+ lldb::offset_t data_offset = 0;
if (data.GetU16(&data_offset, &dispatch_queue_offsets.dqo_version, sizeof(dispatch_queue_offsets)/sizeof(uint16_t)))
{
if (ReadMemory (thread_dispatch_qaddr, &memory_buffer, data.GetAddressByteSize(), error) == data.GetAddressByteSize())
{
data_offset = 0;
lldb::addr_t queue_addr = data.GetAddress(&data_offset);
- lldb::addr_t label_addr = queue_addr + dispatch_queue_offsets.dqo_label;
- dispatch_queue_name.resize(dispatch_queue_offsets.dqo_label_size, '\0');
- size_t bytes_read = ReadMemory (label_addr, &dispatch_queue_name[0], dispatch_queue_offsets.dqo_label_size, error);
- if (bytes_read < dispatch_queue_offsets.dqo_label_size)
- dispatch_queue_name.erase (bytes_read);
+ if (dispatch_queue_offsets.dqo_version >= 4)
+ {
+ // libdispatch versions 4+, pointer to dispatch name is in the
+ // queue structure.
+ lldb::addr_t pointer_to_label_address = queue_addr + dispatch_queue_offsets.dqo_label;
+ if (ReadMemory (pointer_to_label_address, &memory_buffer, data.GetAddressByteSize(), error) == data.GetAddressByteSize())
+ {
+ data_offset = 0;
+ lldb::addr_t label_addr = data.GetAddress(&data_offset);
+ ReadCStringFromMemory (label_addr, dispatch_queue_name, error);
+ }
+ }
+ else
+ {
+ // libdispatch versions 1-3, dispatch name is a fixed width char array
+ // in the queue structure.
+ lldb::addr_t label_addr = queue_addr + dispatch_queue_offsets.dqo_label;
+ dispatch_queue_name.resize(dispatch_queue_offsets.dqo_label_size, '\0');
+ size_t bytes_read = ReadMemory (label_addr, &dispatch_queue_name[0], dispatch_queue_offsets.dqo_label_size, error);
+ if (bytes_read < dispatch_queue_offsets.dqo_label_size)
+ dispatch_queue_name.erase (bytes_read);
+ }
}
}
}
@@ -2855,7 +2928,7 @@ ProcessGDBRemote::NewThreadNotifyBreakpo
{
// I don't think I have to do anything here, just make sure I notice the new thread when it starts to
// run so I can stop it if that's what I want to do.
- LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (log)
log->Printf("Hit New Thread Notification breakpoint.");
return false;
@@ -2865,7 +2938,7 @@ ProcessGDBRemote::NewThreadNotifyBreakpo
bool
ProcessGDBRemote::StartNoticingNewThreads()
{
- LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (m_thread_create_bp_sp)
{
if (log && log->GetVerbose())
@@ -2897,7 +2970,7 @@ ProcessGDBRemote::StartNoticingNewThread
bool
ProcessGDBRemote::StopNoticingNewThreads()
{
- LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (log && log->GetVerbose())
log->Printf ("Disabling new thread notification breakpoint.");
@@ -2907,4 +2980,208 @@ ProcessGDBRemote::StopNoticingNewThreads
return true;
}
+lldb_private::DynamicLoader *
+ProcessGDBRemote::GetDynamicLoader ()
+{
+ if (m_dyld_ap.get() == NULL)
+ m_dyld_ap.reset (DynamicLoader::FindPlugin(this, NULL));
+ return m_dyld_ap.get();
+}
+
+
+class CommandObjectProcessGDBRemotePacketHistory : public CommandObjectParsed
+{
+private:
+
+public:
+ CommandObjectProcessGDBRemotePacketHistory(CommandInterpreter &interpreter) :
+ CommandObjectParsed (interpreter,
+ "process plugin packet history",
+ "Dumps the packet history buffer. ",
+ NULL)
+ {
+ }
+
+ ~CommandObjectProcessGDBRemotePacketHistory ()
+ {
+ }
+
+ bool
+ DoExecute (Args& command, CommandReturnObject &result)
+ {
+ const size_t argc = command.GetArgumentCount();
+ if (argc == 0)
+ {
+ ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
+ if (process)
+ {
+ process->GetGDBRemote().DumpHistory(result.GetOutputStream());
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ }
+ else
+ {
+ result.AppendErrorWithFormat ("'%s' takes no arguments", m_cmd_name.c_str());
+ }
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+};
+class CommandObjectProcessGDBRemotePacketSend : public CommandObjectParsed
+{
+private:
+
+public:
+ CommandObjectProcessGDBRemotePacketSend(CommandInterpreter &interpreter) :
+ CommandObjectParsed (interpreter,
+ "process plugin packet send",
+ "Send a custom packet through the GDB remote protocol and print the answer. "
+ "The packet header and footer will automatically be added to the packet prior to sending and stripped from the result.",
+ NULL)
+ {
+ }
+
+ ~CommandObjectProcessGDBRemotePacketSend ()
+ {
+ }
+
+ bool
+ DoExecute (Args& command, CommandReturnObject &result)
+ {
+ const size_t argc = command.GetArgumentCount();
+ if (argc == 0)
+ {
+ result.AppendErrorWithFormat ("'%s' takes a one or more packet content arguments", m_cmd_name.c_str());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
+ if (process)
+ {
+ for (size_t i=0; i<argc; ++ i)
+ {
+ const char *packet_cstr = command.GetArgumentAtIndex(0);
+ bool send_async = true;
+ StringExtractorGDBRemote response;
+ process->GetGDBRemote().SendPacketAndWaitForResponse(packet_cstr, response, send_async);
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ Stream &output_strm = result.GetOutputStream();
+ output_strm.Printf (" packet: %s\n", packet_cstr);
+ std::string &response_str = response.GetStringRef();
+
+ if (strcmp(packet_cstr, "qGetProfileData") == 0)
+ {
+ response_str = process->GetGDBRemote().HarmonizeThreadIdsForProfileData(process, response);
+ }
+
+ if (response_str.empty())
+ output_strm.PutCString ("response: \nerror: UNIMPLEMENTED\n");
+ else
+ output_strm.Printf ("response: %s\n", response.GetStringRef().c_str());
+ }
+ }
+ return true;
+ }
+};
+
+class CommandObjectProcessGDBRemotePacketMonitor : public CommandObjectRaw
+{
+private:
+
+public:
+ CommandObjectProcessGDBRemotePacketMonitor(CommandInterpreter &interpreter) :
+ CommandObjectRaw (interpreter,
+ "process plugin packet monitor",
+ "Send a qRcmd packet through the GDB remote protocol and print the response."
+ "The argument passed to this command will be hex encoded into a valid 'qRcmd' packet, sent and the response will be printed.",
+ NULL)
+ {
+ }
+
+ ~CommandObjectProcessGDBRemotePacketMonitor ()
+ {
+ }
+
+ bool
+ DoExecute (const char *command, CommandReturnObject &result)
+ {
+ if (command == NULL || command[0] == '\0')
+ {
+ result.AppendErrorWithFormat ("'%s' takes a command string argument", m_cmd_name.c_str());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
+ if (process)
+ {
+ StreamString packet;
+ packet.PutCString("qRcmd,");
+ packet.PutBytesAsRawHex8(command, strlen(command));
+ const char *packet_cstr = packet.GetString().c_str();
+
+ bool send_async = true;
+ StringExtractorGDBRemote response;
+ process->GetGDBRemote().SendPacketAndWaitForResponse(packet_cstr, response, send_async);
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ Stream &output_strm = result.GetOutputStream();
+ output_strm.Printf (" packet: %s\n", packet_cstr);
+ const std::string &response_str = response.GetStringRef();
+
+ if (response_str.empty())
+ output_strm.PutCString ("response: \nerror: UNIMPLEMENTED\n");
+ else
+ output_strm.Printf ("response: %s\n", response.GetStringRef().c_str());
+ }
+ return true;
+ }
+};
+
+class CommandObjectProcessGDBRemotePacket : public CommandObjectMultiword
+{
+private:
+
+public:
+ CommandObjectProcessGDBRemotePacket(CommandInterpreter &interpreter) :
+ CommandObjectMultiword (interpreter,
+ "process plugin packet",
+ "Commands that deal with GDB remote packets.",
+ NULL)
+ {
+ LoadSubCommand ("history", CommandObjectSP (new CommandObjectProcessGDBRemotePacketHistory (interpreter)));
+ LoadSubCommand ("send", CommandObjectSP (new CommandObjectProcessGDBRemotePacketSend (interpreter)));
+ LoadSubCommand ("monitor", CommandObjectSP (new CommandObjectProcessGDBRemotePacketMonitor (interpreter)));
+ }
+
+ ~CommandObjectProcessGDBRemotePacket ()
+ {
+ }
+};
+
+class CommandObjectMultiwordProcessGDBRemote : public CommandObjectMultiword
+{
+public:
+ CommandObjectMultiwordProcessGDBRemote (CommandInterpreter &interpreter) :
+ CommandObjectMultiword (interpreter,
+ "process plugin",
+ "A set of commands for operating on a ProcessGDBRemote process.",
+ "process plugin <subcommand> [<subcommand-options>]")
+ {
+ LoadSubCommand ("packet", CommandObjectSP (new CommandObjectProcessGDBRemotePacket (interpreter)));
+ }
+
+ ~CommandObjectMultiwordProcessGDBRemote ()
+ {
+ }
+};
+
+CommandObject *
+ProcessGDBRemote::GetPluginCommandObject()
+{
+ if (!m_command_sp)
+ m_command_sp.reset (new CommandObjectMultiwordProcessGDBRemote (GetTarget().GetDebugger().GetCommandInterpreter()));
+ return m_command_sp.get();
+}
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Thu Jun 6 19:06:43 2013
@@ -19,6 +19,7 @@
// Other libraries and framework includes
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Broadcaster.h"
+#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/InputReader.h"
#include "lldb/Core/StreamString.h"
@@ -50,7 +51,7 @@ public:
static void
Terminate();
- static const char *
+ static lldb_private::ConstString
GetPluginNameStatic();
static const char *
@@ -71,8 +72,8 @@ public:
CanDebug (lldb_private::Target &target,
bool plugin_specified_by_name);
-// virtual uint32_t
-// ListProcessesMatchingName (const char *name, lldb_private::StringList &matches, std::vector<lldb::pid_t> &pids);
+ virtual lldb_private::CommandObject *
+ GetPluginCommandObject();
//------------------------------------------------------------------
// Creating a new process, or attaching to an existing one
@@ -94,7 +95,7 @@ public:
WillAttachToProcessWithName (const char *process_name, bool wait_for_launch);
virtual lldb_private::Error
- DoConnectRemote (const char *remote_url);
+ DoConnectRemote (lldb_private::Stream *strm, const char *remote_url);
lldb_private::Error
WillLaunchOrAttach ();
@@ -116,12 +117,9 @@ public:
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
- virtual const char *
+ virtual lldb_private::ConstString
GetPluginName();
- virtual const char *
- GetShortPluginName();
-
virtual uint32_t
GetPluginVersion();
@@ -138,10 +136,10 @@ public:
DoHalt (bool &caused_stop);
virtual lldb_private::Error
- WillDetach ();
-
- virtual lldb_private::Error
- DoDetach ();
+ DoDetach (bool keep_stopped);
+
+ virtual bool
+ DetachRequiresHalt() { return true; }
virtual lldb_private::Error
DoSignal (int signal);
@@ -190,19 +188,19 @@ public:
// Process Breakpoints
//----------------------------------------------------------------------
virtual lldb_private::Error
- EnableBreakpoint (lldb_private::BreakpointSite *bp_site);
+ EnableBreakpointSite (lldb_private::BreakpointSite *bp_site);
virtual lldb_private::Error
- DisableBreakpoint (lldb_private::BreakpointSite *bp_site);
+ DisableBreakpointSite (lldb_private::BreakpointSite *bp_site);
//----------------------------------------------------------------------
// Process Watchpoints
//----------------------------------------------------------------------
virtual lldb_private::Error
- EnableWatchpoint (lldb_private::Watchpoint *wp);
+ EnableWatchpoint (lldb_private::Watchpoint *wp, bool notify = true);
virtual lldb_private::Error
- DisableWatchpoint (lldb_private::Watchpoint *wp);
+ DisableWatchpoint (lldb_private::Watchpoint *wp, bool notify = true);
virtual lldb_private::Error
GetWatchpointSupportInfo (uint32_t &num);
@@ -288,11 +286,8 @@ protected:
BuildDynamicRegisterInfo (bool force);
void
- SetLastStopPacket (const StringExtractorGDBRemote &response)
- {
- lldb_private::Mutex::Locker locker (m_last_stop_packet_mutex);
- m_last_stop_packet = response;
- }
+ SetLastStopPacket (const StringExtractorGDBRemote &response);
+
//------------------------------------------------------------------
/// Broadcaster event bits definitions.
//------------------------------------------------------------------
@@ -303,6 +298,13 @@ protected:
eBroadcastBitAsyncThreadDidExit = (1 << 2)
};
+ typedef enum AsyncThreadState
+ {
+ eAsyncThreadNotStarted,
+ eAsyncThreadRunning,
+ eAsyncThreadDone
+ } AsyncThreadState;
+
lldb_private::Flags m_flags; // Process specific flags (see eFlags enums)
GDBRemoteCommunicationClient m_gdb_comm;
lldb::pid_t m_debugserver_pid;
@@ -311,6 +313,8 @@ protected:
GDBRemoteDynamicRegisterInfo m_register_info;
lldb_private::Broadcaster m_async_broadcaster;
lldb::thread_t m_async_thread;
+ AsyncThreadState m_async_thread_state;
+ lldb_private::Mutex m_async_thread_state_mutex;
typedef std::vector<lldb::tid_t> tid_collection;
typedef std::vector< std::pair<lldb::tid_t,int> > tid_sig_collection;
typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
@@ -325,6 +329,7 @@ protected:
lldb::BreakpointSP m_thread_create_bp_sp;
bool m_waiting_for_attach;
bool m_destroy_tried_resuming;
+ lldb::CommandObjectSP m_command_sp;
bool
StartAsyncThread ();
@@ -368,10 +373,8 @@ protected:
const char *bytes,
size_t bytes_len);
- lldb_private::Error
- InterruptIfRunning (bool discard_thread_plans,
- bool catch_stop_event,
- lldb::EventSP &stop_event_sp);
+ lldb_private::DynamicLoader *
+ GetDynamicLoader ();
private:
//------------------------------------------------------------------
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp Thu Jun 6 19:06:43 2013
@@ -22,39 +22,43 @@ using namespace lldb_private;
// control access to our static g_log_sp by hiding it in a singleton function
// that will construct the static g_lob_sp the first time this function is
// called.
-static LogSP &
+static bool g_log_enabled = false;
+static Log * g_log = NULL;
+static Log *
GetLog ()
{
- static LogSP g_log_sp;
- return g_log_sp;
+ if (!g_log_enabled)
+ return NULL;
+ return g_log;
}
-LogSP
+
+Log *
ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (uint32_t mask)
{
- LogSP log(GetLog ());
+ Log *log(GetLog ());
if (log && mask)
{
uint32_t log_mask = log->GetMask().Get();
if ((log_mask & mask) != mask)
- return LogSP();
+ return NULL;
}
return log;
}
-LogSP
+Log *
ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (uint32_t mask)
{
- LogSP log(GetLog ());
+ Log *log(GetLog ());
if (log && log->GetMask().Get() & mask)
return log;
- return LogSP();
+ return NULL;
}
void
ProcessGDBRemoteLog::DisableLog (const char **categories, Stream *feedback_strm)
{
- LogSP log (GetLog ());
+ Log *log (GetLog ());
if (log)
{
uint32_t flag_bits = 0;
@@ -91,7 +95,7 @@ ProcessGDBRemoteLog::DisableLog (const c
}
if (flag_bits == 0)
- GetLog ().reset();
+ g_log_enabled = false;
else
log->GetMask().Reset (flag_bits);
}
@@ -99,24 +103,25 @@ ProcessGDBRemoteLog::DisableLog (const c
return;
}
-LogSP
+Log *
ProcessGDBRemoteLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **categories, Stream *feedback_strm)
{
// Try see if there already is a log - that way we can reuse its settings.
// We could reuse the log in toto, but we don't know that the stream is the same.
uint32_t flag_bits = 0;
- LogSP log(GetLog ());
- if (log)
- flag_bits = log->GetMask().Get();
+ if (g_log)
+ flag_bits = g_log->GetMask().Get();
// Now make a new log with this stream if one was provided
if (log_stream_sp)
{
- log.reset (new Log(log_stream_sp));
- GetLog () = log;
+ if (g_log)
+ g_log->SetStream(log_stream_sp);
+ else
+ g_log = new Log(log_stream_sp);
}
- if (log)
+ if (g_log)
{
bool got_unknown_category = false;
for (size_t i=0; categories[i] != NULL; ++i)
@@ -149,10 +154,11 @@ ProcessGDBRemoteLog::EnableLog (StreamSP
}
if (flag_bits == 0)
flag_bits = GDBR_LOG_DEFAULT;
- log->GetMask().Reset(flag_bits);
- log->GetOptions().Reset(log_options);
+ g_log->GetMask().Reset(flag_bits);
+ g_log->GetOptions().Reset(log_options);
}
- return log;
+ g_log_enabled = true;
+ return g_log;
}
void
@@ -172,14 +178,14 @@ ProcessGDBRemoteLog::ListLogCategories (
" thread - log thread events and activities\n"
" step - log step related activities\n"
" verbose - enable verbose logging\n"
- " watch - log watchpoint related activities\n", ProcessGDBRemote::GetPluginNameStatic());
+ " watch - log watchpoint related activities\n", ProcessGDBRemote::GetPluginNameStatic().GetCString());
}
void
ProcessGDBRemoteLog::LogIf (uint32_t mask, const char *format, ...)
{
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (mask));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (mask));
if (log)
{
va_list args;
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h Thu Jun 6 19:06:43 2013
@@ -35,16 +35,16 @@
class ProcessGDBRemoteLog
{
public:
- static lldb::LogSP
+ static lldb_private::Log *
GetLogIfAllCategoriesSet(uint32_t mask = 0);
- static lldb::LogSP
+ static lldb_private::Log *
GetLogIfAnyCategoryIsSet (uint32_t mask);
static void
DisableLog (const char **categories, lldb_private::Stream *feedback_strm);
- static lldb::LogSP
+ static lldb_private::Log *
EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options, const char **categories, lldb_private::Stream *feedback_strm);
static void
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp Thu Jun 6 19:06:43 2013
@@ -32,15 +32,15 @@ using namespace lldb_private;
// Thread Registers
//----------------------------------------------------------------------
-ThreadGDBRemote::ThreadGDBRemote (const ProcessSP &process_sp, lldb::tid_t tid) :
- Thread(process_sp, tid),
+ThreadGDBRemote::ThreadGDBRemote (Process &process, lldb::tid_t tid) :
+ Thread(process, tid),
m_thread_name (),
m_dispatch_queue_name (),
m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS)
{
ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)",
this,
- process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID,
+ process.GetID(),
GetID());
}
@@ -80,19 +80,14 @@ ThreadGDBRemote::GetQueueName ()
return NULL;
}
-bool
+void
ThreadGDBRemote::WillResume (StateType resume_state)
{
- ClearStackFrames();
- // Call the Thread::WillResume first. If we stop at a signal, the stop info
- // class for signal will set the resume signal that we need below. The signal
- // stuff obeys the Process::UnixSignal defaults.
- Thread::WillResume(resume_state);
-
int signo = GetResumeSignal();
- lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (GDBR_LOG_THREAD));
+ const lldb::user_id_t tid = GetProtocolID();
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (GDBR_LOG_THREAD));
if (log)
- log->Printf ("Resuming thread: %4.4llx with state: %s.", GetID(), StateAsCString(resume_state));
+ log->Printf ("Resuming thread: %4.4" PRIx64 " with state: %s.", tid, StateAsCString(resume_state));
ProcessSP process_sp (GetProcess());
if (process_sp)
@@ -107,24 +102,22 @@ ThreadGDBRemote::WillResume (StateType r
case eStateRunning:
if (gdb_process->GetUnixSignals().SignalIsValid (signo))
- gdb_process->m_continue_C_tids.push_back(std::make_pair(GetID(), signo));
+ gdb_process->m_continue_C_tids.push_back(std::make_pair(tid, signo));
else
- gdb_process->m_continue_c_tids.push_back(GetID());
+ gdb_process->m_continue_c_tids.push_back(tid);
break;
case eStateStepping:
if (gdb_process->GetUnixSignals().SignalIsValid (signo))
- gdb_process->m_continue_S_tids.push_back(std::make_pair(GetID(), signo));
+ gdb_process->m_continue_S_tids.push_back(std::make_pair(tid, signo));
else
- gdb_process->m_continue_s_tids.push_back(GetID());
+ gdb_process->m_continue_s_tids.push_back(tid);
break;
default:
break;
}
- return true;
}
- return false;
}
void
@@ -142,16 +135,6 @@ ThreadGDBRemote::RefreshStateAfterStop()
GetRegisterContext()->InvalidateIfNeeded (force);
}
-void
-ThreadGDBRemote::ClearStackFrames ()
-{
- Unwind *unwinder = GetUnwinder ();
- if (unwinder)
- unwinder->Clear();
- Thread::ClearStackFrames();
-}
-
-
bool
ThreadGDBRemote::ThreadIDIsValid (lldb::tid_t thread)
{
@@ -197,8 +180,12 @@ ThreadGDBRemote::CreateRegisterContextFo
reg_ctx_sp.reset (new GDBRemoteRegisterContext (*this, concrete_frame_idx, gdb_process->m_register_info, read_all_registers_at_once));
}
}
- else if (m_unwinder_ap.get())
- reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
+ else
+ {
+ Unwind *unwinder = GetUnwinder ();
+ if (unwinder)
+ reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
+ }
return reg_ctx_sp;
}
@@ -210,34 +197,18 @@ ThreadGDBRemote::PrivateSetRegisterValue
return gdb_reg_ctx->PrivateSetRegisterValue (reg, response);
}
-lldb::StopInfoSP
-ThreadGDBRemote::GetPrivateStopReason ()
+bool
+ThreadGDBRemote::CalculateStopInfo ()
{
ProcessSP process_sp (GetProcess());
if (process_sp)
{
- const uint32_t process_stop_id = process_sp->GetStopID();
- if (m_thread_stop_reason_stop_id != process_stop_id ||
- (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
- {
- // If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason
- // for this thread, then m_actual_stop_info_sp will not ever contain
- // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
- // check will never be able to tell us if we have the correct stop info
- // for this thread and we will continually send qThreadStopInfo packets
- // down to the remote GDB server, so we need to keep our own notion
- // of the stop ID that m_actual_stop_info_sp is valid for (even if it
- // contains nothing). We use m_thread_stop_reason_stop_id for this below.
- m_thread_stop_reason_stop_id = process_stop_id;
- m_actual_stop_info_sp.reset();
-
- StringExtractorGDBRemote stop_packet;
- ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
- if (gdb_process->GetGDBRemote().GetThreadStopInfo(GetID(), stop_packet))
- gdb_process->SetThreadStopInfo (stop_packet);
- }
+ StringExtractorGDBRemote stop_packet;
+ ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
+ if (gdb_process->GetGDBRemote().GetThreadStopInfo(GetProtocolID(), stop_packet))
+ return gdb_process->SetThreadStopInfo (stop_packet) == eStateStopped;
}
- return m_actual_stop_info_sp;
+ return false;
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h Thu Jun 6 19:06:43 2013
@@ -21,12 +21,12 @@ class ProcessGDBRemote;
class ThreadGDBRemote : public lldb_private::Thread
{
public:
- ThreadGDBRemote (const lldb::ProcessSP &process_sp, lldb::tid_t tid);
+ ThreadGDBRemote (lldb_private::Process &process, lldb::tid_t tid);
virtual
~ThreadGDBRemote ();
- virtual bool
+ virtual void
WillResume (lldb::StateType resume_state);
virtual void
@@ -44,9 +44,6 @@ public:
virtual lldb::RegisterContextSP
CreateRegisterContextForFrame (lldb_private::StackFrame *frame);
- virtual void
- ClearStackFrames ();
-
void
Dump (lldb_private::Log *log, uint32_t index);
@@ -101,8 +98,8 @@ protected:
void
SetStopInfoFromPacket (StringExtractor &stop_packet, uint32_t stop_id);
- virtual lldb::StopInfoSP
- GetPrivateStopReason ();
+ virtual bool
+ CalculateStopInfo ();
};
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/mach-core/ProcessMachCore.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/mach-core/ProcessMachCore.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/mach-core/ProcessMachCore.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/mach-core/ProcessMachCore.cpp Thu Jun 6 19:06:43 2013
@@ -18,8 +18,12 @@
// Other libraries and framework includes
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/Section.h"
#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
+#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
@@ -28,16 +32,18 @@
#include "ThreadMachCore.h"
#include "StopInfoMachException.h"
+// Needed for the plug-in names for the dynamic loaders.
#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
using namespace lldb;
using namespace lldb_private;
-const char *
+ConstString
ProcessMachCore::GetPluginNameStatic()
{
- return "mach-o-core";
+ static ConstString g_name("mach-o-core");
+ return g_name;
}
const char *
@@ -121,15 +127,9 @@ ProcessMachCore::~ProcessMachCore()
//----------------------------------------------------------------------
// PluginInterface
//----------------------------------------------------------------------
-const char *
+ConstString
ProcessMachCore::GetPluginName()
{
- return "Process debugging plug-in that loads mach-o core files.";
-}
-
-const char *
-ProcessMachCore::GetShortPluginName()
-{
return GetPluginNameStatic();
}
@@ -159,7 +159,7 @@ ProcessMachCore::GetDynamicLoaderAddress
}
// TODO: swap header if needed...
- //printf("0x%16.16llx: magic = 0x%8.8x, file_type= %u\n", vaddr, header.magic, header.filetype);
+ //printf("0x%16.16" PRIx64 ": magic = 0x%8.8x, file_type= %u\n", vaddr, header.magic, header.filetype);
if (header.magic == llvm::MachO::HeaderMagic32 ||
header.magic == llvm::MachO::HeaderMagic64)
{
@@ -171,14 +171,14 @@ ProcessMachCore::GetDynamicLoaderAddress
switch (header.filetype)
{
case llvm::MachO::HeaderFileTypeDynamicLinkEditor:
- //printf("0x%16.16llx: file_type = MH_DYLINKER\n", vaddr);
+ //printf("0x%16.16" PRIx64 ": file_type = MH_DYLINKER\n", vaddr);
// Address of dyld "struct mach_header" in the core file
m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
m_dyld_addr = addr;
return true;
case llvm::MachO::HeaderFileTypeExecutable:
- //printf("0x%16.16llx: file_type = MH_EXECUTE\n", vaddr);
+ //printf("0x%16.16" PRIx64 ": file_type = MH_EXECUTE\n", vaddr);
// Check MH_EXECUTABLE file types to see if the dynamic link object flag
// is NOT set. If it isn't, then we have a mach_kernel.
if ((header.flags & llvm::MachO::HeaderFlagBitIsDynamicLinkObject) == 0)
@@ -213,6 +213,13 @@ ProcessMachCore::DoLoadCore ()
error.SetErrorString ("invalid core object file");
return error;
}
+
+ if (core_objfile->GetNumThreadContexts() == 0)
+ {
+ error.SetErrorString ("core file doesn't contain any LC_THREAD load commands, or the LC_THREAD architecture is not supported in this lldb");
+ return error;
+ }
+
SectionList *section_list = core_objfile->GetSectionList();
if (section_list == NULL)
{
@@ -227,6 +234,8 @@ ProcessMachCore::DoLoadCore ()
return error;
}
+ SetCanJIT(false);
+
llvm::MachO::mach_header header;
DataExtractor data (&header,
sizeof(header),
@@ -250,7 +259,7 @@ ProcessMachCore::DoLoadCore ()
ranges_are_sorted = false;
vm_addr = section->GetFileAddress();
VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
-// printf ("LC_SEGMENT[%u] arange=[0x%16.16llx - 0x%16.16llx), frange=[0x%8.8x - 0x%8.8x)\n",
+// printf ("LC_SEGMENT[%u] arange=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), frange=[0x%8.8x - 0x%8.8x)\n",
// i,
// range_entry.GetRangeBase(),
// range_entry.GetRangeEnd(),
@@ -295,36 +304,28 @@ ProcessMachCore::DoLoadCore ()
if (m_dyld_addr == LLDB_INVALID_ADDRESS)
{
- // Check the magic kernel address for the mach image header address in case
- // it is there.
- if (arch.GetAddressByteSize() == 8)
+ // We need to locate the main executable in the memory ranges
+ // we have in the core file. We already checked the first address
+ // in each memory zone above, so we just need to check each page
+ // except the first page in each range and stop once we have found
+ // our main executable
+ const size_t num_core_aranges = m_core_aranges.GetSize();
+ for (size_t i=0; i<num_core_aranges && m_dyld_addr == LLDB_INVALID_ADDRESS; ++i)
{
- Error header_addr_error;
- addr_t header_addr = ReadPointerFromMemory (0xffffff8000002010ull, header_addr_error);
- if (header_addr != LLDB_INVALID_ADDRESS)
- GetDynamicLoaderAddress (header_addr);
+ const VMRangeToFileOffset::Entry *entry = m_core_aranges.GetEntryAtIndex(i);
+ lldb::addr_t section_vm_addr_start = entry->GetRangeBase();
+ lldb::addr_t section_vm_addr_end = entry->GetRangeEnd();
+ for (lldb::addr_t section_vm_addr = section_vm_addr_start + 0x1000;
+ section_vm_addr < section_vm_addr_end;
+ section_vm_addr += 0x1000)
+ {
+ if (GetDynamicLoaderAddress (section_vm_addr))
+ {
+ break;
+ }
+ }
}
-
-// if (m_dyld_addr == LLDB_INVALID_ADDRESS)
-// {
-// // We haven't found our dyld or mach_kernel yet,
-// // so we need to exhaustively look
-// const size_t num_core_aranges = m_core_aranges.GetSize();
-// bool done = false;
-// for (size_t i=0; !done && i<num_core_aranges; ++i)
-// {
-// const addr_t start_vaddr = m_core_aranges.GetEntryRef(i).GetRangeBase();
-// const addr_t end_vaddr = m_core_aranges.GetEntryRef(i).GetRangeEnd();
-// // printf("core_arange[%u] [0x%16.16llx - 0x%16.16llx)\n", (uint32_t)i, start_vaddr, end_vaddr);
-//
-// for (addr_t vaddr = start_vaddr; !done && start_vaddr < end_vaddr; vaddr += 0x1000)
-// {
-// done = GetDynamicLoaderAddress (vaddr);
-// }
-// }
-// }
}
-
return error;
}
@@ -332,7 +333,7 @@ lldb_private::DynamicLoader *
ProcessMachCore::GetDynamicLoader ()
{
if (m_dyld_ap.get() == NULL)
- m_dyld_ap.reset (DynamicLoader::FindPlugin(this, m_dyld_plugin_name.empty() ? NULL : m_dyld_plugin_name.c_str()));
+ m_dyld_ap.reset (DynamicLoader::FindPlugin(this, m_dyld_plugin_name.IsEmpty() ? NULL : m_dyld_plugin_name.GetCString()));
return m_dyld_ap.get();
}
@@ -350,7 +351,7 @@ ProcessMachCore::UpdateThreadList (Threa
const uint32_t num_threads = core_objfile->GetNumThreadContexts ();
for (lldb::tid_t tid = 0; tid < num_threads; ++tid)
{
- ThreadSP thread_sp(new ThreadMachCore (shared_from_this(), tid));
+ ThreadSP thread_sp(new ThreadMachCore (*this, tid));
new_thread_list.AddThread (thread_sp);
}
}
@@ -389,6 +390,12 @@ ProcessMachCore::IsAlive ()
return true;
}
+bool
+ProcessMachCore::WarnBeforeDetach () const
+{
+ return false;
+}
+
//------------------------------------------------------------------
// Process Memory
//------------------------------------------------------------------
@@ -419,7 +426,7 @@ ProcessMachCore::DoReadMemory (addr_t ad
}
else
{
- error.SetErrorStringWithFormat ("core file does not contain 0x%llx", addr);
+ error.SetErrorStringWithFormat ("core file does not contain 0x%" PRIx64, addr);
}
}
return 0;
@@ -452,3 +459,8 @@ ProcessMachCore::GetImageInfoAddress()
}
+lldb_private::ObjectFile *
+ProcessMachCore::GetCoreObjectFile ()
+{
+ return m_core_module_sp->GetObjectFile();
+}
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/mach-core/ProcessMachCore.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/mach-core/ProcessMachCore.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/mach-core/ProcessMachCore.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/mach-core/ProcessMachCore.h Thu Jun 6 19:06:43 2013
@@ -17,6 +17,7 @@
#include <vector>
// Other libraries and framework includes
+#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
#include "lldb/Target/Process.h"
@@ -39,7 +40,7 @@ public:
static void
Terminate();
- static const char *
+ static lldb_private::ConstString
GetPluginNameStatic();
static const char *
@@ -74,12 +75,9 @@ public:
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
- virtual const char *
+ virtual lldb_private::ConstString
GetPluginName();
- virtual const char *
- GetShortPluginName();
-
virtual uint32_t
GetPluginVersion();
@@ -97,7 +95,10 @@ public:
//------------------------------------------------------------------
virtual bool
IsAlive ();
-
+
+ virtual bool
+ WarnBeforeDetach () const;
+
//------------------------------------------------------------------
// Process Memory
//------------------------------------------------------------------
@@ -121,10 +122,7 @@ protected:
lldb_private::ThreadList &new_thread_list);
lldb_private::ObjectFile *
- GetCoreObjectFile ()
- {
- return m_core_module_sp->GetObjectFile();
- }
+ GetCoreObjectFile ();
private:
bool
GetDynamicLoaderAddress (lldb::addr_t addr);
@@ -132,14 +130,14 @@ private:
//------------------------------------------------------------------
// For ProcessMachCore only
//------------------------------------------------------------------
- typedef lldb_private::Range<uint32_t, uint32_t> FileRange;
- typedef lldb_private::RangeDataArray<lldb::addr_t, lldb::addr_t, FileRange, 1> VMRangeToFileOffset;
+ typedef lldb_private::Range<lldb::addr_t, lldb::addr_t> FileRange;
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, FileRange> VMRangeToFileOffset;
VMRangeToFileOffset m_core_aranges;
lldb::ModuleSP m_core_module_sp;
lldb_private::FileSpec m_core_file;
lldb::addr_t m_dyld_addr;
- std::string m_dyld_plugin_name;
+ lldb_private::ConstString m_dyld_plugin_name;
DISALLOW_COPY_AND_ASSIGN (ProcessMachCore);
};
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/mach-core/ThreadMachCore.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/mach-core/ThreadMachCore.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/mach-core/ThreadMachCore.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/mach-core/ThreadMachCore.cpp Thu Jun 6 19:06:43 2013
@@ -16,6 +16,7 @@
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/State.h"
+#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
@@ -35,8 +36,8 @@ using namespace lldb_private;
// Thread Registers
//----------------------------------------------------------------------
-ThreadMachCore::ThreadMachCore (const lldb::ProcessSP &process_sp, lldb::tid_t tid) :
- Thread(process_sp, tid),
+ThreadMachCore::ThreadMachCore (Process &process, lldb::tid_t tid) :
+ Thread(process, tid),
m_thread_name (),
m_dispatch_queue_name (),
m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS),
@@ -72,16 +73,6 @@ ThreadMachCore::RefreshStateAfterStop()
GetRegisterContext()->InvalidateIfNeeded (force);
}
-void
-ThreadMachCore::ClearStackFrames ()
-{
- Unwind *unwinder = GetUnwinder ();
- if (unwinder)
- unwinder->Clear();
- Thread::ClearStackFrames();
-}
-
-
bool
ThreadMachCore::ThreadIDIsValid (lldb::tid_t thread)
{
@@ -117,43 +108,25 @@ ThreadMachCore::CreateRegisterContextFor
}
reg_ctx_sp = m_thread_reg_ctx_sp;
}
- else if (m_unwinder_ap.get())
+ else
{
- reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
+ Unwind *unwinder = GetUnwinder ();
+ if (unwinder)
+ reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
}
return reg_ctx_sp;
}
-lldb::StopInfoSP
-ThreadMachCore::GetPrivateStopReason ()
+bool
+ThreadMachCore::CalculateStopInfo ()
{
ProcessSP process_sp (GetProcess());
-
if (process_sp)
{
- const uint32_t process_stop_id = process_sp->GetStopID();
- if (m_thread_stop_reason_stop_id != process_stop_id ||
- (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
- {
- // TODO: can we query the initial state of the thread here?
- // For now I am just going to pretend that a SIGSTOP happened.
-
- SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP));
-
- // If GetKDPProcess().SetThreadStopInfo() doesn't find a stop reason
- // for this thread, then m_actual_stop_info_sp will not ever contain
- // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
- // check will never be able to tell us if we have the correct stop info
- // for this thread and we will continually send qThreadStopInfo packets
- // down to the remote KDP server, so we need to keep our own notion
- // of the stop ID that m_actual_stop_info_sp is valid for (even if it
- // contains nothing). We use m_thread_stop_reason_stop_id for this below.
- // m_thread_stop_reason_stop_id = process_stop_id;
- // m_actual_stop_info_sp.reset();
-
- }
+ SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP));
+ return true;
}
- return m_actual_stop_info_sp;
+ return false;
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/mach-core/ThreadMachCore.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/mach-core/ThreadMachCore.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/mach-core/ThreadMachCore.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/mach-core/ThreadMachCore.h Thu Jun 6 19:06:43 2013
@@ -19,7 +19,7 @@ class ProcessMachCore;
class ThreadMachCore : public lldb_private::Thread
{
public:
- ThreadMachCore (const lldb::ProcessSP &process_sp,
+ ThreadMachCore (lldb_private::Process &process,
lldb::tid_t tid);
virtual
@@ -37,9 +37,6 @@ public:
virtual lldb::RegisterContextSP
CreateRegisterContextForFrame (lldb_private::StackFrame *frame);
- virtual void
- ClearStackFrames ();
-
static bool
ThreadIDIsValid (lldb::tid_t thread);
@@ -82,11 +79,10 @@ protected:
lldb::addr_t m_thread_dispatch_qaddr;
lldb::RegisterContextSP m_thread_reg_ctx_sp;
//------------------------------------------------------------------
- // Member variables.
+ // Protected member functions.
//------------------------------------------------------------------
-
- virtual lldb::StopInfoSP
- GetPrivateStopReason ();
+ virtual bool
+ CalculateStopInfo ();
};
#endif // liblldb_ThreadMachCore_h_
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp Thu Jun 6 19:06:43 2013
@@ -32,13 +32,13 @@ DWARFAbbreviationDeclaration::DWARFAbbre
}
bool
-DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, uint32_t* offset_ptr)
+DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, lldb::offset_t* offset_ptr)
{
return Extract(data, offset_ptr, data.GetULEB128(offset_ptr));
}
bool
-DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, uint32_t* offset_ptr, dw_uleb128_t code)
+DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, lldb::offset_t *offset_ptr, dw_uleb128_t code)
{
m_code = code;
m_attributes.clear();
@@ -155,7 +155,7 @@ DWARFAbbreviationDeclaration::CopyChangi
dw_attr_t attr;
dw_form_t form;
uint32_t i;
- dw_offset_t offset = debug_info_offset;
+ lldb::offset_t offset = debug_info_offset;
for (i = 0; i < num_abbr_decl_attributes; ++i)
{
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h Thu Jun 6 19:06:43 2013
@@ -32,7 +32,7 @@ public:
void SetCode(dw_uleb128_t code) { m_code = code; }
dw_tag_t Tag() const { return m_tag; }
bool HasChildren() const { return m_has_children; }
- uint32_t NumAttributes() const { return m_attributes.size(); }
+ size_t NumAttributes() const { return m_attributes.size(); }
dw_attr_t GetAttrByIndex(uint32_t idx) const { return m_attributes.size() > idx ? m_attributes[idx].get_attr() : 0; }
dw_form_t GetFormByIndex(uint32_t idx) const { return m_attributes.size() > idx ? m_attributes[idx].get_form() : 0; }
bool GetAttrAndFormByIndex(uint32_t idx, dw_attr_t& attr, dw_form_t& form) const
@@ -63,8 +63,8 @@ public:
const DWARFCompileUnit* cu,
const uint32_t strp_min_len);
uint32_t FindAttributeIndex(dw_attr_t attr) const;
- bool Extract(const lldb_private::DataExtractor& data, uint32_t* offset_ptr);
- bool Extract(const lldb_private::DataExtractor& data, uint32_t* offset_ptr, dw_uleb128_t code);
+ bool Extract(const lldb_private::DataExtractor& data, lldb::offset_t *offset_ptr);
+ bool Extract(const lldb_private::DataExtractor& data, lldb::offset_t *offset_ptr, dw_uleb128_t code);
// void Append(BinaryStreamBuf& out_buff) const;
bool IsValid();
void Dump(lldb_private::Stream *s) const;
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h Thu Jun 6 19:06:43 2013
@@ -25,12 +25,12 @@ public:
void set_attr(dw_attr_t attr) { m_attr_form = (m_attr_form & 0x0000ffffu) | (attr << 16); }
void set_form(dw_form_t form) { m_attr_form = (m_attr_form & 0xffff0000u) | form; }
dw_attr_t get_attr() const { return m_attr_form >> 16; }
- dw_form_t get_form() const { return m_attr_form; }
+ dw_form_t get_form() const { return (dw_form_t)m_attr_form; }
void get(dw_attr_t& attr, dw_form_t& form) const
{
register uint32_t attr_form = m_attr_form;
attr = attr_form >> 16;
- form = attr_form;
+ form = (dw_form_t)attr_form;
}
bool operator == (const DWARFAttribute& rhs) const { return m_attr_form == rhs.m_attr_form; }
typedef std::vector<DWARFAttribute> collection;
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp Thu Jun 6 19:06:43 2013
@@ -13,6 +13,8 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/Timer.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
@@ -43,7 +45,10 @@ DWARFCompileUnit::DWARFCompileUnit(Symbo
m_length (0),
m_version (0),
m_addr_size (DWARFCompileUnit::GetDefaultAddressSize()),
- m_producer (eProducerInvalid)
+ m_producer (eProducerInvalid),
+ m_producer_version_major (0),
+ m_producer_version_minor (0),
+ m_producer_version_update (0)
{
}
@@ -63,7 +68,7 @@ DWARFCompileUnit::Clear()
}
bool
-DWARFCompileUnit::Extract(const DataExtractor &debug_info, uint32_t* offset_ptr)
+DWARFCompileUnit::Extract(const DataExtractor &debug_info, lldb::offset_t *offset_ptr)
{
Clear();
@@ -98,7 +103,7 @@ DWARFCompileUnit::Extract(const DataExtr
dw_offset_t
-DWARFCompileUnit::Extract(dw_offset_t offset, const DataExtractor& debug_info_data, const DWARFAbbreviationDeclarationSet* abbrevs)
+DWARFCompileUnit::Extract(lldb::offset_t offset, const DataExtractor& debug_info_data, const DWARFAbbreviationDeclarationSet* abbrevs)
{
Clear();
@@ -162,17 +167,17 @@ DWARFCompileUnit::ExtractDIEsIfNeeded (b
// Set the offset to that of the first DIE and calculate the start of the
// next compilation unit header.
- uint32_t offset = GetFirstDIEOffset();
- uint32_t next_cu_offset = GetNextCompileUnitOffset();
+ lldb::offset_t offset = GetFirstDIEOffset();
+ lldb::offset_t next_cu_offset = GetNextCompileUnitOffset();
DWARFDebugInfoEntry die;
// Keep a flat array of the DIE for binary lookup by DIE offset
if (!cu_die_only)
{
- LogSP log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_LOOKUPS));
+ Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_LOOKUPS));
if (log)
{
- m_dwarf2Data->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log.get(),
+ m_dwarf2Data->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log,
"DWARFCompileUnit::ExtractDIEsIfNeeded () for compile unit at .debug_info[0x%8.8x]",
GetOffset());
}
@@ -268,7 +273,7 @@ DWARFCompileUnit::ExtractDIEsIfNeeded (b
// unit header).
if (offset > next_cu_offset)
{
- m_dwarf2Data->GetObjectFile()->GetModule()->ReportWarning ("DWARF compile unit extends beyond its bounds cu 0x%8.8x at 0x%8.8x\n",
+ m_dwarf2Data->GetObjectFile()->GetModule()->ReportWarning ("DWARF compile unit extends beyond its bounds cu 0x%8.8x at 0x%8.8" PRIx64 "\n",
GetOffset(),
offset);
}
@@ -283,7 +288,7 @@ DWARFCompileUnit::ExtractDIEsIfNeeded (b
DWARFDebugInfoEntry::collection exact_size_die_array (m_die_array.begin(), m_die_array.end());
exact_size_die_array.swap (m_die_array);
}
- LogSP log (LogChannelDWARF::GetLogIfAll (DWARF_LOG_DEBUG_INFO | DWARF_LOG_VERBOSE));
+ Log *log (LogChannelDWARF::GetLogIfAll (DWARF_LOG_DEBUG_INFO | DWARF_LOG_VERBOSE));
if (log)
{
StreamString strm;
@@ -386,7 +391,34 @@ DWARFCompileUnit::BuildAddressRangeTable
// down.
const bool clear_dies = ExtractDIEsIfNeeded (false) > 1;
- DIE()->BuildAddressRangeTable(dwarf2Data, this, debug_aranges);
+ const DWARFDebugInfoEntry* die = DIE();
+ if (die)
+ die->BuildAddressRangeTable(dwarf2Data, this, debug_aranges);
+
+ if (debug_aranges->IsEmpty())
+ {
+ // We got nothing from the functions, maybe we have a line tables only
+ // situation. Check the line tables and build the arange table from this.
+ SymbolContext sc;
+ sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this);
+ if (sc.comp_unit)
+ {
+ LineTable *line_table = sc.comp_unit->GetLineTable();
+
+ if (line_table)
+ {
+ LineTable::FileAddressRanges file_ranges;
+ const bool append = true;
+ const size_t num_ranges = line_table->GetContiguousFileAddressRanges (file_ranges, append);
+ for (uint32_t idx=0; idx<num_ranges; ++idx)
+ {
+ const LineTable::FileAddressRanges::Entry &range = file_ranges.GetEntryRef(idx);
+ debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(), range.GetRangeEnd());
+ printf ("0x%8.8x: [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", GetOffset(), range.GetRangeBase(), range.GetRangeEnd());
+ }
+ }
+ }
+ }
// Keep memory down by clearing DIEs if this generate function
// caused them to be parsed
@@ -402,15 +434,17 @@ DWARFCompileUnit::GetFunctionAranges ()
if (m_func_aranges_ap.get() == NULL)
{
m_func_aranges_ap.reset (new DWARFDebugAranges());
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
if (log)
{
- m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage (log.get(),
+ m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage (log,
"DWARFCompileUnit::GetFunctionAranges() for compile unit at .debug_info[0x%8.8x]",
GetOffset());
}
- DIE()->BuildFunctionAddressRangeTable (m_dwarf2Data, this, m_func_aranges_ap.get());
+ const DWARFDebugInfoEntry* die = DIE();
+ if (die)
+ die->BuildFunctionAddressRangeTable (m_dwarf2Data, this, m_func_aranges_ap.get());
const bool minimize = false;
m_func_aranges_ap->Sort(minimize);
}
@@ -575,11 +609,11 @@ DWARFCompileUnit::Index (const uint32_t
const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize());
- LogSP log (LogChannelDWARF::GetLogIfAll (DWARF_LOG_LOOKUPS));
+ Log *log (LogChannelDWARF::GetLogIfAll (DWARF_LOG_LOOKUPS));
if (log)
{
- m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage (log.get(),
+ m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage (log,
"DWARFCompileUnit::Index() for compile unit at .debug_info[0x%8.8x]",
GetOffset());
}
@@ -650,6 +684,7 @@ DWARFCompileUnit::Index (const uint32_t
// break;
case DW_AT_MIPS_linkage_name:
+ case DW_AT_linkage_name:
if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value))
mangled_cstr = form_value.AsCString(debug_str);
break;
@@ -729,28 +764,22 @@ DWARFCompileUnit::Index (const uint32_t
{
// Note, this check is also done in ParseMethodName, but since this is a hot loop, we do the
// simple inlined check outside the call.
- if (ObjCLanguageRuntime::IsPossibleObjCMethodName(name))
+ ObjCLanguageRuntime::MethodName objc_method(name, true);
+ if (objc_method.IsValid(true))
{
- ConstString objc_class_name;
- ConstString objc_selector_name;
- ConstString objc_fullname_no_category_name;
- ConstString objc_class_name_no_category;
- if (ObjCLanguageRuntime::ParseMethodName (name,
- &objc_class_name,
- &objc_selector_name,
- &objc_fullname_no_category_name,
- &objc_class_name_no_category))
- {
- func_fullnames.Insert (ConstString(name), die.GetOffset());
- if (objc_class_name)
- objc_class_selectors.Insert(objc_class_name, die.GetOffset());
- if (objc_class_name_no_category)
- objc_class_selectors.Insert(objc_class_name_no_category, die.GetOffset());
- if (objc_selector_name)
- func_selectors.Insert (objc_selector_name, die.GetOffset());
- if (objc_fullname_no_category_name)
- func_fullnames.Insert (objc_fullname_no_category_name, die.GetOffset());
- }
+ ConstString objc_class_name_with_category (objc_method.GetClassNameWithCategory());
+ ConstString objc_selector_name (objc_method.GetSelector());
+ ConstString objc_fullname_no_category_name (objc_method.GetFullNameWithoutCategory(true));
+ ConstString objc_class_name_no_category (objc_method.GetClassName());
+ func_fullnames.Insert (ConstString(name), die.GetOffset());
+ if (objc_class_name_with_category)
+ objc_class_selectors.Insert(objc_class_name_with_category, die.GetOffset());
+ if (objc_class_name_no_category && objc_class_name_no_category != objc_class_name_with_category)
+ objc_class_selectors.Insert(objc_class_name_no_category, die.GetOffset());
+ if (objc_selector_name)
+ func_selectors.Insert (objc_selector_name, die.GetOffset());
+ if (objc_fullname_no_category_name)
+ func_fullnames.Insert (objc_fullname_no_category_name, die.GetOffset());
}
// If we have a mangled name, then the DW_AT_name attribute
// is usually the method name without the class or any parameters
@@ -788,6 +817,9 @@ DWARFCompileUnit::Index (const uint32_t
func_methods.Insert (ConstString(name), die.GetOffset());
else
func_basenames.Insert (ConstString(name), die.GetOffset());
+
+ if (!is_method && !mangled_cstr && !objc_method.IsValid(true))
+ func_fullnames.Insert (ConstString(name), die.GetOffset());
}
if (mangled_cstr)
{
@@ -825,6 +857,8 @@ DWARFCompileUnit::Index (const uint32_t
func_fullnames.Insert (mangled.GetDemangledName(), die.GetOffset());
}
}
+ else
+ func_fullnames.Insert (ConstString(name), die.GetOffset());
}
break;
@@ -879,9 +913,23 @@ DWARFCompileUnit::Index (const uint32_t
}
bool
+DWARFCompileUnit::Supports_unnamed_objc_bitfields ()
+{
+ if (GetProducer() == eProducerClang)
+ {
+ const uint32_t major_version = GetProducerVersionMajor();
+ if (major_version > 425 || (major_version == 425 && GetProducerVersionUpdate() >= 13))
+ return true;
+ else
+ return false;
+ }
+ return true; // Assume all other compilers didn't have incorrect ObjC bitfield info
+}
+
+bool
DWARFCompileUnit::Supports_DW_AT_APPLE_objc_complete_type ()
{
- if (GetProducer() == eProcucerLLVMGCC)
+ if (GetProducer() == eProducerLLVMGCC)
return false;
return true;
}
@@ -891,34 +939,82 @@ DWARFCompileUnit::DW_AT_decl_file_attrib
{
// llvm-gcc makes completely invalid decl file attributes and won't ever
// be fixed, so we need to know to ignore these.
- return GetProducer() == eProcucerLLVMGCC;
+ return GetProducer() == eProducerLLVMGCC;
}
-DWARFCompileUnit::Producer
-DWARFCompileUnit::GetProducer ()
+void
+DWARFCompileUnit::ParseProducerInfo ()
{
- if (m_producer == eProducerInvalid)
+ m_producer_version_major = UINT32_MAX;
+ m_producer_version_minor = UINT32_MAX;
+ m_producer_version_update = UINT32_MAX;
+
+ const DWARFDebugInfoEntry *die = GetCompileUnitDIEOnly();
+ if (die)
{
- const DWARFDebugInfoEntry *die = GetCompileUnitDIEOnly();
- if (die)
+
+ const char *producer_cstr = die->GetAttributeValueAsString(m_dwarf2Data, this, DW_AT_producer, NULL);
+ if (producer_cstr)
{
- const char *producer_cstr = die->GetAttributeValueAsString(m_dwarf2Data, this, DW_AT_producer, NULL);
- if (producer_cstr)
+ RegularExpression llvm_gcc_regex("^4\\.[012]\\.[01] \\(Based on Apple Inc\\. build [0-9]+\\) \\(LLVM build [\\.0-9]+\\)$");
+ if (llvm_gcc_regex.Execute (producer_cstr))
{
- RegularExpression g_llvm_gcc_regex("^4\\.[012]\\.[01] \\(Based on Apple Inc\\. build [0-9]+\\) \\(LLVM build [\\.0-9]+\\)$");
- if (g_llvm_gcc_regex.Execute (producer_cstr))
- m_producer = eProcucerLLVMGCC;
- else if (strstr(producer_cstr, "clang"))
- m_producer = eProducerClang;
- else if (strstr(producer_cstr, "GNU"))
- m_producer = eProducerGCC;
+ m_producer = eProducerLLVMGCC;
}
+ else if (strstr(producer_cstr, "clang"))
+ {
+ static RegularExpression g_clang_version_regex("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)");
+ RegularExpression::Match regex_match(3);
+ if (g_clang_version_regex.Execute (producer_cstr, ®ex_match))
+ {
+ std::string str;
+ if (regex_match.GetMatchAtIndex (producer_cstr, 1, str))
+ m_producer_version_major = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10);
+ if (regex_match.GetMatchAtIndex (producer_cstr, 2, str))
+ m_producer_version_minor = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10);
+ if (regex_match.GetMatchAtIndex (producer_cstr, 3, str))
+ m_producer_version_update = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10);
+ }
+ m_producer = eProducerClang;
+ }
+ else if (strstr(producer_cstr, "GNU"))
+ m_producer = eProducerGCC;
}
- if (m_producer == eProducerInvalid)
- m_producer = eProcucerOther;
}
+ if (m_producer == eProducerInvalid)
+ m_producer = eProcucerOther;
+}
+
+DWARFCompileUnit::Producer
+DWARFCompileUnit::GetProducer ()
+{
+ if (m_producer == eProducerInvalid)
+ ParseProducerInfo ();
return m_producer;
}
+uint32_t
+DWARFCompileUnit::GetProducerVersionMajor()
+{
+ if (m_producer_version_major == 0)
+ ParseProducerInfo ();
+ return m_producer_version_major;
+}
+
+uint32_t
+DWARFCompileUnit::GetProducerVersionMinor()
+{
+ if (m_producer_version_minor == 0)
+ ParseProducerInfo ();
+ return m_producer_version_minor;
+}
+
+uint32_t
+DWARFCompileUnit::GetProducerVersionUpdate()
+{
+ if (m_producer_version_update == 0)
+ ParseProducerInfo ();
+ return m_producer_version_update;
+}
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h Thu Jun 6 19:06:43 2013
@@ -23,14 +23,14 @@ public:
eProducerInvalid = 0,
eProducerClang,
eProducerGCC,
- eProcucerLLVMGCC,
+ eProducerLLVMGCC,
eProcucerOther
};
DWARFCompileUnit(SymbolFileDWARF* dwarf2Data);
- bool Extract(const lldb_private::DataExtractor &debug_info, uint32_t* offset_ptr);
- dw_offset_t Extract(dw_offset_t offset, const lldb_private::DataExtractor& debug_info_data, const DWARFAbbreviationDeclarationSet* abbrevs);
+ bool Extract(const lldb_private::DataExtractor &debug_info, lldb::offset_t *offset_ptr);
+ dw_offset_t Extract(lldb::offset_t offset, const lldb_private::DataExtractor& debug_info_data, const DWARFAbbreviationDeclarationSet* abbrevs);
size_t ExtractDIEsIfNeeded (bool cu_die_only);
bool LookupAddress(
const dw_addr_t address,
@@ -144,6 +144,9 @@ public:
bool
DW_AT_decl_file_attributes_are_invalid();
+ bool
+ Supports_unnamed_objc_bitfields ();
+
// void
// AddGlobalDIEByIndex (uint32_t die_idx);
//
@@ -173,19 +176,33 @@ public:
Producer
GetProducer ();
+ uint32_t
+ GetProducerVersionMajor();
+
+ uint32_t
+ GetProducerVersionMinor();
+
+ uint32_t
+ GetProducerVersionUpdate();
protected:
SymbolFileDWARF* m_dwarf2Data;
const DWARFAbbreviationDeclarationSet *m_abbrevs;
void * m_user_data;
DWARFDebugInfoEntry::collection m_die_array; // The compile unit debug information entry item
- std::auto_ptr<DWARFDebugAranges> m_func_aranges_ap; // A table similar to the .debug_aranges table, but this one points to the exact DW_TAG_subprogram DIEs
+ std::unique_ptr<DWARFDebugAranges> m_func_aranges_ap; // A table similar to the .debug_aranges table, but this one points to the exact DW_TAG_subprogram DIEs
dw_addr_t m_base_addr;
dw_offset_t m_offset;
uint32_t m_length;
uint16_t m_version;
uint8_t m_addr_size;
Producer m_producer;
+ uint32_t m_producer_version_major;
+ uint32_t m_producer_version_minor;
+ uint32_t m_producer_version_update;
+
+ void
+ ParseProducerInfo ();
private:
DISALLOW_COPY_AND_ASSIGN (DWARFCompileUnit);
};
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp Thu Jun 6 19:06:43 2013
@@ -30,9 +30,9 @@ DWARFAbbreviationDeclarationSet::Clear()
// DWARFAbbreviationDeclarationSet::Extract()
//----------------------------------------------------------------------
bool
-DWARFAbbreviationDeclarationSet::Extract(const DataExtractor& data, uint32_t* offset_ptr)
+DWARFAbbreviationDeclarationSet::Extract(const DataExtractor& data, lldb::offset_t *offset_ptr)
{
- const uint32_t begin_offset = *offset_ptr;
+ const lldb::offset_t begin_offset = *offset_ptr;
m_offset = begin_offset;
Clear();
DWARFAbbreviationDeclaration abbrevDeclaration;
@@ -144,7 +144,7 @@ DWARFDebugAbbrev::DWARFDebugAbbrev() :
void
DWARFDebugAbbrev::Parse(const DataExtractor& data)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
while (data.ValidOffset(offset))
{
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h Thu Jun 6 19:06:43 2013
@@ -43,7 +43,7 @@ public:
void Clear();
dw_offset_t GetOffset() const { return m_offset; }
void Dump(lldb_private::Stream *s) const;
- bool Extract(const lldb_private::DataExtractor& data, uint32_t* offset_ptr);
+ bool Extract(const lldb_private::DataExtractor& data, lldb::offset_t *offset_ptr);
//void Encode(BinaryStreamBuf& debug_abbrev_buf) const;
dw_uleb128_t AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration& abbrevDecl);
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp Thu Jun 6 19:06:43 2013
@@ -162,7 +162,7 @@ DWARFDebugArangeSet::AddDescriptor(const
}
bool
-DWARFDebugArangeSet::Extract(const DataExtractor &data, uint32_t* offset_ptr)
+DWARFDebugArangeSet::Extract(const DataExtractor &data, lldb::offset_t *offset_ptr)
{
if (data.ValidOffset(*offset_ptr))
{
@@ -243,7 +243,7 @@ DWARFDebugArangeSet::Dump(Stream *s) con
DescriptorConstIter pos;
DescriptorConstIter end = m_arange_descriptors.end();
for (pos = m_arange_descriptors.begin(); pos != end; ++pos)
- s->Printf("[0x%*.*llx - 0x%*.*llx)\n",
+ s->Printf("[0x%*.*" PRIx64 " - 0x%*.*" PRIx64 ")\n",
hex_width, hex_width, pos->address,
hex_width, hex_width, pos->end_address());
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h Thu Jun 6 19:06:43 2013
@@ -41,12 +41,12 @@ public:
void SetHeader(uint16_t version, uint32_t cu_offset, uint8_t addr_size, uint8_t seg_size);
void AddDescriptor(const DWARFDebugArangeSet::Descriptor& range);
void Compact();
- bool Extract(const lldb_private::DataExtractor &data, uint32_t* offset_ptr);
+ bool Extract(const lldb_private::DataExtractor &data, lldb::offset_t *offset_ptr);
void Dump(lldb_private::Stream *s) const;
dw_offset_t GetCompileUnitDIEOffset() const { return m_header.cu_offset; }
dw_offset_t GetOffsetOfNextEntry() const;
dw_offset_t FindAddress(dw_addr_t address) const;
- uint32_t NumDescriptors() const { return m_arange_descriptors.size(); }
+ size_t NumDescriptors() const { return m_arange_descriptors.size(); }
const Header& GetHeader() const { return m_header; }
const Descriptor* GetDescriptor(uint32_t i) const
{
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp Thu Jun 6 19:06:43 2013
@@ -60,7 +60,7 @@ DWARFDebugAranges::Extract(const DataExt
{
if (debug_aranges_data.ValidOffset(0))
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
DWARFDebugArangeSet set;
Range range;
@@ -117,10 +117,11 @@ DWARFDebugAranges::Dump (Log *log) const
for (size_t i=0; i<num_entries; ++i)
{
const RangeToDIE::Entry *entry = m_aranges.GetEntryAtIndex(i);
- log->Printf ("0x%8.8x: [0x%llx - 0x%llx)",
- entry->data,
- entry->GetRangeBase(),
- entry->GetRangeEnd());
+ if (entry)
+ log->Printf ("0x%8.8x: [0x%" PRIx64 " - 0x%" PRIx64 ")",
+ entry->data,
+ entry->GetRangeBase(),
+ entry->GetRangeEnd());
}
}
@@ -137,12 +138,12 @@ DWARFDebugAranges::Sort (bool minimize)
Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
__PRETTY_FUNCTION__, this);
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
size_t orig_arange_size = 0;
if (log)
{
orig_arange_size = m_aranges.GetSize();
- log->Printf ("DWARFDebugAranges::Sort(minimize = %u) with %zu entries", minimize, orig_arange_size);
+ log->Printf ("DWARFDebugAranges::Sort(minimize = %u) with %" PRIu64 " entries", minimize, (uint64_t)orig_arange_size);
}
m_aranges.Sort();
@@ -154,10 +155,12 @@ DWARFDebugAranges::Sort (bool minimize)
{
const size_t new_arange_size = m_aranges.GetSize();
const size_t delta = orig_arange_size - new_arange_size;
- log->Printf ("DWARFDebugAranges::Sort() %zu entries after minimizing (%zu entries combined for %zu bytes saved)",
- new_arange_size, delta, delta * sizeof(Range));
+ log->Printf ("DWARFDebugAranges::Sort() %" PRIu64 " entries after minimizing (%" PRIu64 " entries combined for %" PRIu64 " bytes saved)",
+ (uint64_t)new_arange_size,
+ (uint64_t)delta,
+ (uint64_t)delta * sizeof(Range));
}
- Dump (log.get());
+ Dump (log);
}
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h Thu Jun 6 19:06:43 2013
@@ -66,7 +66,7 @@ public:
{
return m_aranges.IsEmpty();
}
- uint32_t
+ size_t
GetNumRanges() const
{
return m_aranges.GetSize();
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp Thu Jun 6 19:06:43 2013
@@ -54,29 +54,26 @@ DWARFDebugInfo::GetCompileUnitAranges ()
{
if (m_cu_aranges_ap.get() == NULL && m_dwarf2Data)
{
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
m_cu_aranges_ap.reset (new DWARFDebugAranges());
const DataExtractor &debug_aranges_data = m_dwarf2Data->get_debug_aranges_data();
if (debug_aranges_data.GetByteSize() > 0)
{
if (log)
- log->Printf ("DWARFDebugInfo::GetCompileUnitAranges() for \"%s/%s\" from .debug_aranges",
- m_dwarf2Data->GetObjectFile()->GetFileSpec().GetDirectory().GetCString(),
- m_dwarf2Data->GetObjectFile()->GetFileSpec().GetFilename().GetCString());
+ log->Printf ("DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" from .debug_aranges",
+ m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str());
m_cu_aranges_ap->Extract (debug_aranges_data);
}
else
{
if (log)
- log->Printf ("DWARFDebugInfo::GetCompileUnitAranges() for \"%s/%s\" by parsing",
- m_dwarf2Data->GetObjectFile()->GetFileSpec().GetDirectory().GetCString(),
- m_dwarf2Data->GetObjectFile()->GetFileSpec().GetFilename().GetCString());
- const uint32_t num_compile_units = GetNumCompileUnits();
- uint32_t idx;
+ log->Printf ("DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" by parsing",
+ m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str());
+ const size_t num_compile_units = GetNumCompileUnits();
const bool clear_dies_if_already_not_parsed = true;
- for (idx = 0; idx < num_compile_units; ++idx)
+ for (size_t idx = 0; idx < num_compile_units; ++idx)
{
DWARFCompileUnit* cu = GetCompileUnitAtIndex(idx);
if (cu)
@@ -148,7 +145,7 @@ DWARFDebugInfo::ParseCompileUnitHeadersI
{
if (m_dwarf2Data != NULL)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
const DataExtractor &debug_info_data = m_dwarf2Data->get_debug_info_data();
while (debug_info_data.ValidOffset(offset))
{
@@ -168,7 +165,7 @@ DWARFDebugInfo::ParseCompileUnitHeadersI
}
}
-uint32_t
+size_t
DWARFDebugInfo::GetNumCompileUnits()
{
ParseCompileUnitHeadersIfNeeded();
@@ -395,7 +392,7 @@ DWARFDebugInfo::Parse(SymbolFileDWARF* d
{
if (dwarf2Data)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
uint32_t depth = 0;
DWARFCompileUnitSP cu(new DWARFCompileUnit(dwarf2Data));
if (cu.get() == NULL)
@@ -701,7 +698,10 @@ DWARFDebugInfo::Dump (Stream *s, const u
{
const DWARFCompileUnitSP& cu_sp = *pos;
DumpCallback(m_dwarf2Data, (DWARFCompileUnitSP&)cu_sp, NULL, 0, curr_depth, &dumpInfo);
- cu_sp->DIE()->Dump(m_dwarf2Data, cu_sp.get(), *s, recurse_depth);
+
+ const DWARFDebugInfoEntry* die = cu_sp->DIE();
+ if (die)
+ die->Dump(m_dwarf2Data, cu_sp.get(), *s, recurse_depth);
}
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h Thu Jun 6 19:06:43 2013
@@ -21,7 +21,7 @@ typedef std::multimap<const char*, dw_of
typedef CStringToDIEMap::iterator CStringToDIEMapIter;
typedef CStringToDIEMap::const_iterator CStringToDIEMapConstIter;
-typedef STD_SHARED_PTR(DWARFCompileUnit) DWARFCompileUnitSP;
+typedef std::shared_ptr<DWARFCompileUnit> DWARFCompileUnitSP;
class DWARFDebugInfo
{
@@ -45,7 +45,7 @@ public:
DWARFDebugInfoEntry** block_die);
void AddCompileUnit(DWARFCompileUnitSP& cu);
- uint32_t GetNumCompileUnits();
+ size_t GetNumCompileUnits();
bool ContainsCompileUnit (const DWARFCompileUnit *cu) const;
DWARFCompileUnit* GetCompileUnitAtIndex(uint32_t idx);
DWARFCompileUnitSP GetCompileUnit(dw_offset_t cu_offset, uint32_t* idx_ptr = NULL);
@@ -77,7 +77,7 @@ protected:
SymbolFileDWARF* m_dwarf2Data;
typedef std::vector<DWARFCompileUnitSP> CompileUnitColl;
CompileUnitColl m_compile_units;
- std::auto_ptr<DWARFDebugAranges> m_cu_aranges_ap; // A quick address to compile unit table
+ std::unique_ptr<DWARFDebugAranges> m_cu_aranges_ap; // A quick address to compile unit table
private:
// All parsing needs to be done partially any managed by this class as accessors are called.
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp Thu Jun 6 19:06:43 2013
@@ -89,7 +89,7 @@ bool
DWARFDebugInfoEntry::Attributes::ExtractFormValueAtIndex (SymbolFileDWARF* dwarf2Data, uint32_t i, DWARFFormValue &form_value) const
{
form_value.SetForm(FormAtIndex(i));
- dw_offset_t offset = DIEOffsetAtIndex(i);
+ lldb::offset_t offset = DIEOffsetAtIndex(i);
return form_value.ExtractValue(dwarf2Data->get_debug_info_data(), &offset, CompileUnitAtIndex(i));
}
@@ -119,7 +119,7 @@ DWARFDebugInfoEntry::FastExtract
const DataExtractor& debug_info_data,
const DWARFCompileUnit* cu,
const uint8_t *fixed_form_sizes,
- uint32_t* offset_ptr
+ lldb::offset_t *offset_ptr
)
{
m_offset = *offset_ptr;
@@ -134,7 +134,7 @@ DWARFDebugInfoEntry::FastExtract
if (m_abbr_idx)
{
- uint32_t offset = *offset_ptr;
+ lldb::offset_t offset = *offset_ptr;
const DWARFAbbreviationDeclaration *abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx);
@@ -171,60 +171,79 @@ DWARFDebugInfoEntry::FastExtract
{
// Blocks if inlined data that have a length field and the data bytes
// inlined in the .debug_info
- case DW_FORM_block : form_size = debug_info_data.GetULEB128 (&offset); break;
- case DW_FORM_block1 : form_size = debug_info_data.GetU8_unchecked (&offset); break;
- case DW_FORM_block2 : form_size = debug_info_data.GetU16_unchecked (&offset);break;
- case DW_FORM_block4 : form_size = debug_info_data.GetU32_unchecked (&offset);break;
+ case DW_FORM_exprloc :
+ case DW_FORM_block : form_size = debug_info_data.GetULEB128 (&offset); break;
+ case DW_FORM_block1 : form_size = debug_info_data.GetU8_unchecked (&offset); break;
+ case DW_FORM_block2 : form_size = debug_info_data.GetU16_unchecked (&offset);break;
+ case DW_FORM_block4 : form_size = debug_info_data.GetU32_unchecked (&offset);break;
// Inlined NULL terminated C-strings
- case DW_FORM_string :
+ case DW_FORM_string :
debug_info_data.GetCStr (&offset);
break;
// Compile unit address sized values
- case DW_FORM_addr :
- case DW_FORM_ref_addr :
+ case DW_FORM_addr :
form_size = cu->GetAddressByteSize();
break;
+ case DW_FORM_ref_addr :
+ if (cu->GetVersion() <= 2)
+ form_size = cu->GetAddressByteSize();
+ else
+ form_size = 4; // 4 bytes for DWARF 32, 8 bytes for DWARF 64, but we don't support DWARF64 yet
+ break;
+
+ // 0 sized form
+ case DW_FORM_flag_present:
+ form_size = 0;
+ break;
// 1 byte values
- case DW_FORM_data1 :
- case DW_FORM_flag :
- case DW_FORM_ref1 :
+ case DW_FORM_data1 :
+ case DW_FORM_flag :
+ case DW_FORM_ref1 :
form_size = 1;
break;
// 2 byte values
- case DW_FORM_data2 :
- case DW_FORM_ref2 :
+ case DW_FORM_data2 :
+ case DW_FORM_ref2 :
form_size = 2;
break;
// 4 byte values
- case DW_FORM_strp :
- case DW_FORM_data4 :
- case DW_FORM_ref4 :
+ case DW_FORM_strp :
+ case DW_FORM_data4 :
+ case DW_FORM_ref4 :
form_size = 4;
break;
// 8 byte values
- case DW_FORM_data8 :
- case DW_FORM_ref8 :
+ case DW_FORM_data8 :
+ case DW_FORM_ref8 :
+ case DW_FORM_ref_sig8 :
form_size = 8;
break;
// signed or unsigned LEB 128 values
- case DW_FORM_sdata :
- case DW_FORM_udata :
- case DW_FORM_ref_udata :
+ case DW_FORM_sdata :
+ case DW_FORM_udata :
+ case DW_FORM_ref_udata :
debug_info_data.Skip_LEB128 (&offset);
break;
- case DW_FORM_indirect :
+ case DW_FORM_indirect :
form_is_indirect = true;
form = debug_info_data.GetULEB128 (&offset);
break;
+ case DW_FORM_sec_offset :
+ if (cu->GetAddressByteSize () == 4)
+ debug_info_data.GetU32 (offset_ptr);
+ else
+ debug_info_data.GetU64 (offset_ptr);
+ break;
+
default:
*offset_ptr = m_offset;
return false;
@@ -259,14 +278,14 @@ DWARFDebugInfoEntry::Extract
(
SymbolFileDWARF* dwarf2Data,
const DWARFCompileUnit* cu,
- uint32_t* offset_ptr
+ lldb::offset_t *offset_ptr
)
{
const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
// const DataExtractor& debug_str_data = dwarf2Data->get_debug_str_data();
const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset();
const uint8_t cu_addr_size = cu->GetAddressByteSize();
- uint32_t offset = *offset_ptr;
+ lldb::offset_t offset = *offset_ptr;
// if (offset >= cu_end_offset)
// Log::Error("DIE at offset 0x%8.8x is beyond the end of the current compile unit (0x%8.8x)", m_offset, cu_end_offset);
if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset))
@@ -318,61 +337,80 @@ DWARFDebugInfoEntry::Extract
{
// Blocks if inlined data that have a length field and the data bytes
// inlined in the .debug_info
- case DW_FORM_block : form_size = debug_info_data.GetULEB128(&offset); break;
- case DW_FORM_block1 : form_size = debug_info_data.GetU8(&offset); break;
- case DW_FORM_block2 : form_size = debug_info_data.GetU16(&offset); break;
- case DW_FORM_block4 : form_size = debug_info_data.GetU32(&offset); break;
+ case DW_FORM_exprloc :
+ case DW_FORM_block : form_size = debug_info_data.GetULEB128(&offset); break;
+ case DW_FORM_block1 : form_size = debug_info_data.GetU8(&offset); break;
+ case DW_FORM_block2 : form_size = debug_info_data.GetU16(&offset); break;
+ case DW_FORM_block4 : form_size = debug_info_data.GetU32(&offset); break;
// Inlined NULL terminated C-strings
- case DW_FORM_string : debug_info_data.GetCStr(&offset); break;
+ case DW_FORM_string : debug_info_data.GetCStr(&offset); break;
// Compile unit address sized values
- case DW_FORM_addr :
- case DW_FORM_ref_addr :
+ case DW_FORM_addr :
form_size = cu_addr_size;
break;
+ case DW_FORM_ref_addr :
+ if (cu->GetVersion() <= 2)
+ form_size = cu_addr_size;
+ else
+ form_size = 4; // 4 bytes for DWARF 32, 8 bytes for DWARF 64, but we don't support DWARF64 yet
+ break;
+
+ // 0 sized form
+ case DW_FORM_flag_present:
+ form_size = 0;
+ break;
// 1 byte values
- case DW_FORM_data1 :
- case DW_FORM_flag :
- case DW_FORM_ref1 :
+ case DW_FORM_data1 :
+ case DW_FORM_flag :
+ case DW_FORM_ref1 :
form_size = 1;
break;
// 2 byte values
- case DW_FORM_data2 :
- case DW_FORM_ref2 :
+ case DW_FORM_data2 :
+ case DW_FORM_ref2 :
form_size = 2;
break;
// 4 byte values
- case DW_FORM_strp :
+ case DW_FORM_strp :
form_size = 4;
break;
- case DW_FORM_data4 :
- case DW_FORM_ref4 :
+ case DW_FORM_data4 :
+ case DW_FORM_ref4 :
form_size = 4;
break;
// 8 byte values
- case DW_FORM_data8 :
- case DW_FORM_ref8 :
+ case DW_FORM_data8 :
+ case DW_FORM_ref8 :
+ case DW_FORM_ref_sig8 :
form_size = 8;
break;
// signed or unsigned LEB 128 values
- case DW_FORM_sdata :
- case DW_FORM_udata :
- case DW_FORM_ref_udata :
+ case DW_FORM_sdata :
+ case DW_FORM_udata :
+ case DW_FORM_ref_udata :
debug_info_data.Skip_LEB128(&offset);
break;
- case DW_FORM_indirect :
+ case DW_FORM_indirect :
form = debug_info_data.GetULEB128(&offset);
form_is_indirect = true;
break;
+ case DW_FORM_sec_offset :
+ if (cu->GetAddressByteSize () == 4)
+ debug_info_data.GetU32 (offset_ptr);
+ else
+ debug_info_data.GetU64 (offset_ptr);
+ break;
+
default:
*offset_ptr = offset;
return false;
@@ -717,12 +755,12 @@ DWARFDebugInfoEntry::GetDIENamesAndRange
if (dwarf2Data == NULL)
return false;
- dw_addr_t lo_pc = DW_INVALID_ADDRESS;
- dw_addr_t hi_pc = DW_INVALID_ADDRESS;
+ dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
+ dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
std::vector<dw_offset_t> die_offsets;
bool set_frame_base_loclist_addr = false;
- dw_offset_t offset;
+ lldb::offset_t offset;
const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
if (abbrevDecl)
@@ -770,6 +808,7 @@ DWARFDebugInfoEntry::GetDIENamesAndRange
break;
case DW_AT_MIPS_linkage_name:
+ case DW_AT_linkage_name:
if (mangled == NULL)
mangled = form_value.AsCString(&dwarf2Data->get_debug_str_data());
break;
@@ -830,7 +869,7 @@ DWARFDebugInfoEntry::GetDIENamesAndRange
if (loc_list_length > 0)
{
frame_base->SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
- if (lo_pc != DW_INVALID_ADDRESS)
+ if (lo_pc != LLDB_INVALID_ADDRESS)
{
assert (lo_pc >= cu->GetBaseAddress());
frame_base->SetLocationListSlide(lo_pc - cu->GetBaseAddress());
@@ -853,9 +892,9 @@ DWARFDebugInfoEntry::GetDIENamesAndRange
if (ranges.IsEmpty())
{
- if (lo_pc != DW_INVALID_ADDRESS)
+ if (lo_pc != LLDB_INVALID_ADDRESS)
{
- if (hi_pc != DW_INVALID_ADDRESS && hi_pc > lo_pc)
+ if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc)
ranges.Append(DWARFDebugRanges::Range (lo_pc, hi_pc - lo_pc));
else
ranges.Append(DWARFDebugRanges::Range (lo_pc, 0));
@@ -905,7 +944,7 @@ DWARFDebugInfoEntry::Dump
) const
{
const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
- uint32_t offset = m_offset;
+ lldb::offset_t offset = m_offset;
if (debug_info_data.ValidOffset(offset))
{
@@ -999,7 +1038,7 @@ DWARFDebugInfoEntry::DumpAttribute
SymbolFileDWARF* dwarf2Data,
const DWARFCompileUnit* cu,
const DataExtractor& debug_info_data,
- uint32_t* offset_ptr,
+ lldb::offset_t *offset_ptr,
Stream &s,
dw_attr_t attr,
dw_form_t form
@@ -1007,6 +1046,7 @@ DWARFDebugInfoEntry::DumpAttribute
{
bool verbose = s.GetVerbose();
bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);
+
const DataExtractor* debug_str_data = dwarf2Data ? &dwarf2Data->get_debug_str_data() : NULL;
if (verbose)
s.Offset (*offset_ptr);
@@ -1048,7 +1088,7 @@ DWARFDebugInfoEntry::DumpAttribute
{
case DW_AT_stmt_list:
if ( verbose ) s.PutCString(" ( ");
- s.Printf( "0x%8.8llx", form_value.Unsigned());
+ s.Printf( "0x%8.8" PRIx64, form_value.Unsigned());
if ( verbose ) s.PutCString(" )");
break;
@@ -1128,9 +1168,10 @@ DWARFDebugInfoEntry::DumpAttribute
{
if ( !verbose )
form_value.Dump(s, debug_str_data, cu);
- uint32_t ranges_offset = form_value.Unsigned();
+ lldb::offset_t ranges_offset = form_value.Unsigned();
dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
- DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), &ranges_offset, base_addr);
+ if (dwarf2Data)
+ DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), &ranges_offset, base_addr);
}
break;
@@ -1159,7 +1200,7 @@ DWARFDebugInfoEntry::GetAttributes
uint32_t curr_depth
) const
{
- uint32_t offset;
+ lldb::offset_t offset;
const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
if (abbrevDecl)
@@ -1256,7 +1297,7 @@ DWARFDebugInfoEntry::GetAttributeValue
dw_offset_t* end_attr_offset_ptr
) const
{
- uint32_t offset;
+ lldb::offset_t offset;
const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
if (abbrevDecl)
@@ -1407,7 +1448,7 @@ DWARFDebugInfoEntry::GetAttributeValueAs
// We have a location list offset as the value that is
// the offset into the .debug_loc section that describes
// the value over it's lifetime
- dw_offset_t debug_loc_offset = form_value.Unsigned();
+ lldb::offset_t debug_loc_offset = form_value.Unsigned();
if (dwarf2Data)
{
assert(dwarf2Data->get_debug_loc_data().GetAddressByteSize() == cu->GetAddressByteSize());
@@ -1458,6 +1499,9 @@ DWARFDebugInfoEntry::GetMangledName
if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value))
name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
+ if (GetAttributeValue(dwarf2Data, cu, DW_AT_linkage_name, form_value))
+ name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
+
if (substitute_name_allowed && name == NULL)
{
if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
@@ -1481,10 +1525,15 @@ DWARFDebugInfoEntry::GetPubname
) const
{
const char* name = NULL;
+ if (!dwarf2Data)
+ return name;
+
DWARFFormValue form_value;
if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value))
name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
+ else if (GetAttributeValue(dwarf2Data, cu, DW_AT_linkage_name, form_value))
+ name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
else if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
else if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value))
@@ -1514,12 +1563,18 @@ DWARFDebugInfoEntry::GetName
(
SymbolFileDWARF* dwarf2Data,
const DWARFCompileUnit* cu,
- const uint32_t die_offset,
+ const dw_offset_t die_offset,
Stream &s
)
{
+ if (dwarf2Data == NULL)
+ {
+ s.PutCString("NULL");
+ return false;
+ }
+
DWARFDebugInfoEntry die;
- uint32_t offset = die_offset;
+ lldb::offset_t offset = die_offset;
if (die.Extract(dwarf2Data, cu, &offset))
{
if (die.IsNULL())
@@ -1557,12 +1612,18 @@ DWARFDebugInfoEntry::AppendTypeName
(
SymbolFileDWARF* dwarf2Data,
const DWARFCompileUnit* cu,
- const uint32_t die_offset,
+ const dw_offset_t die_offset,
Stream &s
)
{
+ if (dwarf2Data == NULL)
+ {
+ s.PutCString("NULL");
+ return false;
+ }
+
DWARFDebugInfoEntry die;
- uint32_t offset = die_offset;
+ lldb::offset_t offset = die_offset;
if (die.Extract(dwarf2Data, cu, &offset))
{
if (die.IsNULL())
@@ -1581,6 +1642,9 @@ DWARFDebugInfoEntry::AppendTypeName
{
bool result = true;
const DWARFAbbreviationDeclaration* abbrevDecl = die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
+
+ if (abbrevDecl == NULL)
+ return false;
switch (abbrevDecl->Tag())
{
@@ -1666,11 +1730,11 @@ DWARFDebugInfoEntry::BuildAddressRangeTa
{
if (m_tag == DW_TAG_subprogram)
{
- dw_addr_t hi_pc = DW_INVALID_ADDRESS;
- dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
- if (lo_pc != DW_INVALID_ADDRESS)
- hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS);
- if (hi_pc != DW_INVALID_ADDRESS)
+ dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
+ dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
+ if (lo_pc != LLDB_INVALID_ADDRESS)
+ hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, LLDB_INVALID_ADDRESS);
+ if (hi_pc != LLDB_INVALID_ADDRESS)
{
/// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x - 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc);
debug_aranges->AppendRange (cu->GetOffset(), lo_pc, hi_pc);
@@ -1707,13 +1771,13 @@ DWARFDebugInfoEntry::BuildFunctionAddres
{
if (m_tag == DW_TAG_subprogram)
{
- dw_addr_t hi_pc = DW_INVALID_ADDRESS;
- dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
- if (lo_pc != DW_INVALID_ADDRESS)
- hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS);
- if (hi_pc != DW_INVALID_ADDRESS)
+ dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
+ dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
+ if (lo_pc != LLDB_INVALID_ADDRESS)
+ hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, LLDB_INVALID_ADDRESS);
+ if (hi_pc != LLDB_INVALID_ADDRESS)
{
- // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16llx - 0x%16.16llx)\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
+ // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
debug_aranges->AppendRange (GetOffset(), lo_pc, hi_pc);
}
}
@@ -1998,11 +2062,11 @@ DWARFDebugInfoEntry::LookupAddress
if (match_addr_range)
{
- dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
- if (lo_pc != DW_INVALID_ADDRESS)
+ dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
+ if (lo_pc != LLDB_INVALID_ADDRESS)
{
- dw_addr_t hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS);
- if (hi_pc != DW_INVALID_ADDRESS)
+ dw_addr_t hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, LLDB_INVALID_ADDRESS);
+ if (hi_pc != LLDB_INVALID_ADDRESS)
{
// printf("\n0x%8.8x: %30s: address = 0x%8.8x [0x%8.8x - 0x%8.8x) ", m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc);
if ((lo_pc <= address) && (address < hi_pc))
@@ -2112,25 +2176,28 @@ DWARFDebugInfoEntry::LookupAddress
const DWARFAbbreviationDeclaration*
DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data,
const DWARFCompileUnit *cu,
- dw_offset_t &offset) const
+ lldb::offset_t &offset) const
{
- offset = GetOffset();
-
- const DWARFAbbreviationDeclaration* abbrev_decl = cu->GetAbbreviations()->GetAbbreviationDeclaration (m_abbr_idx);
- if (abbrev_decl)
+ if (dwarf2Data)
{
- // Make sure the abbreviation code still matches. If it doesn't and
- // the DWARF data was mmap'ed, the backing file might have been modified
- // which is bad news.
- const uint64_t abbrev_code = dwarf2Data->get_debug_info_data().GetULEB128 (&offset);
-
- if (abbrev_decl->Code() == abbrev_code)
- return abbrev_decl;
+ offset = GetOffset();
- dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("0x%8.8x: the DWARF debug information has been modified (abbrev code was %u, and is now %u)",
- GetOffset(),
- (uint32_t)abbrev_decl->Code(),
- (uint32_t)abbrev_code);
+ const DWARFAbbreviationDeclaration* abbrev_decl = cu->GetAbbreviations()->GetAbbreviationDeclaration (m_abbr_idx);
+ if (abbrev_decl)
+ {
+ // Make sure the abbreviation code still matches. If it doesn't and
+ // the DWARF data was mmap'ed, the backing file might have been modified
+ // which is bad news.
+ const uint64_t abbrev_code = dwarf2Data->get_debug_info_data().GetULEB128 (&offset);
+
+ if (abbrev_decl->Code() == abbrev_code)
+ return abbrev_decl;
+
+ dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("0x%8.8x: the DWARF debug information has been modified (abbrev code was %u, and is now %u)",
+ GetOffset(),
+ (uint32_t)abbrev_decl->Code(),
+ (uint32_t)abbrev_code);
+ }
}
offset = DW_INVALID_OFFSET;
return NULL;
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h Thu Jun 6 19:06:43 2013
@@ -75,7 +75,7 @@ public:
bool ContainsAttribute(dw_attr_t attr) const;
bool RemoveAttribute(dw_attr_t attr);
void Clear() { m_infos.clear(); }
- uint32_t Size() const { return m_infos.size(); }
+ size_t Size() const { return m_infos.size(); }
protected:
struct Info
@@ -145,12 +145,12 @@ public:
const lldb_private::DataExtractor& debug_info_data,
const DWARFCompileUnit* cu,
const uint8_t *fixed_form_sizes,
- dw_offset_t* offset_ptr);
+ lldb::offset_t* offset_ptr);
bool Extract(
SymbolFileDWARF* dwarf2Data,
const DWARFCompileUnit* cu,
- dw_offset_t* offset_ptr);
+ lldb::offset_t* offset_ptr);
bool LookupAddress(
const dw_addr_t address,
@@ -277,7 +277,7 @@ public:
SymbolFileDWARF* dwarf2Data,
const DWARFCompileUnit* cu,
const lldb_private::DataExtractor& debug_info_data,
- uint32_t* offset_ptr,
+ lldb::offset_t *offset_ptr,
lldb_private::Stream &s,
dw_attr_t attr,
dw_form_t form);
@@ -304,7 +304,7 @@ public:
const DWARFAbbreviationDeclaration*
GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data,
const DWARFCompileUnit *cu,
- dw_offset_t &offset) const;
+ lldb::offset_t &offset) const;
dw_tag_t
Tag () const
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp Thu Jun 6 19:06:43 2013
@@ -35,11 +35,11 @@ void
DWARFDebugLine::Parse(const DataExtractor& debug_line_data)
{
m_lineTableMap.clear();
- dw_offset_t offset = 0;
+ lldb::offset_t offset = 0;
LineTable::shared_ptr line_table_sp(new LineTable);
while (debug_line_data.ValidOffset(offset))
{
- const uint32_t debug_line_offset = offset;
+ const lldb::offset_t debug_line_offset = offset;
if (line_table_sp.get() == NULL)
break;
@@ -100,7 +100,7 @@ DumpStateToFile (dw_offset_t offset, con
}
else
{
- log->Printf( "0x%16.16llx %6u %6u %6u%s\n", state.address, state.line, state.column, state.file, state.end_sequence ? " END" : "");
+ log->Printf( "0x%16.16" PRIx64 " %6u %6u %6u%s\n", state.address, state.line, state.column, state.file, state.end_sequence ? " END" : "");
}
}
@@ -135,7 +135,7 @@ DWARFDebugLine::DumpStatementTable(Log *
{
if (debug_line_data.ValidOffset(debug_line_offset))
{
- uint32_t offset = debug_line_offset;
+ lldb::offset_t offset = debug_line_offset;
log->Printf( "----------------------------------------------------------------------\n"
"debug_line[0x%8.8x]\n"
"----------------------------------------------------------------------\n", debug_line_offset);
@@ -185,7 +185,7 @@ DWARFDebugLine::DumpOpcodes(Log *log, Sy
dw_offset_t
DWARFDebugLine::DumpStatementOpcodes(Log *log, const DataExtractor& debug_line_data, const dw_offset_t debug_line_offset, uint32_t flags)
{
- uint32_t offset = debug_line_offset;
+ lldb::offset_t offset = debug_line_offset;
if (debug_line_data.ValidOffset(offset))
{
Prologue prologue;
@@ -200,7 +200,7 @@ DWARFDebugLine::DumpStatementOpcodes(Log
else
{
offset = debug_line_offset;
- log->Printf( "0x%8.8x: skipping pad byte %2.2x", offset, debug_line_data.GetU8(&offset));
+ log->Printf( "0x%8.8" PRIx64 ": skipping pad byte %2.2x", offset, debug_line_data.GetU8(&offset));
return offset;
}
@@ -236,7 +236,7 @@ DWARFDebugLine::DumpStatementOpcodes(Log
case DW_LNE_set_address :
{
row.address = debug_line_data.GetMaxU64(&offset, arg_size);
- log->Printf( "0x%8.8x: DW_LNE_set_address (0x%llx)", op_offset, row.address);
+ log->Printf( "0x%8.8x: DW_LNE_set_address (0x%" PRIx64 ")", op_offset, row.address);
}
break;
@@ -314,7 +314,7 @@ DWARFDebugLine::DumpStatementOpcodes(Log
{
uint8_t adjust_opcode = 255 - prologue.opcode_base;
dw_addr_t addr_offset = (adjust_opcode / prologue.line_range) * prologue.min_inst_length;
- log->Printf( "0x%8.8x: DW_LNS_const_add_pc (0x%8.8llx)", op_offset, addr_offset);
+ log->Printf( "0x%8.8x: DW_LNS_const_add_pc (0x%8.8" PRIx64 ")", op_offset, addr_offset);
row.address += addr_offset;
}
break;
@@ -362,7 +362,7 @@ DWARFDebugLine::DumpStatementOpcodes(Log
uint8_t adjust_opcode = opcode - prologue.opcode_base;
dw_addr_t addr_offset = (adjust_opcode / prologue.line_range) * prologue.min_inst_length;
int32_t line_offset = prologue.line_base + (adjust_opcode % prologue.line_range);
- log->Printf("0x%8.8x: address += 0x%llx, line += %i\n", op_offset, (uint64_t)addr_offset, line_offset);
+ log->Printf("0x%8.8x: address += 0x%" PRIx64 ", line += %i\n", op_offset, (uint64_t)addr_offset, line_offset);
row.address += addr_offset;
row.line += line_offset;
row.Dump (log);
@@ -388,7 +388,7 @@ DWARFDebugLine::DumpStatementOpcodes(Log
void
DWARFDebugLine::Parse(const DataExtractor& debug_line_data, DWARFDebugLine::State::Callback callback, void* userData)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
if (debug_line_data.ValidOffset(offset))
{
if (!ParseStatementTable(debug_line_data, &offset, callback, userData))
@@ -401,9 +401,9 @@ DWARFDebugLine::Parse(const DataExtracto
// DWARFDebugLine::ParsePrologue
//----------------------------------------------------------------------
bool
-DWARFDebugLine::ParsePrologue(const DataExtractor& debug_line_data, dw_offset_t* offset_ptr, Prologue* prologue)
+DWARFDebugLine::ParsePrologue(const DataExtractor& debug_line_data, lldb::offset_t* offset_ptr, Prologue* prologue)
{
- const uint32_t prologue_offset = *offset_ptr;
+ const lldb::offset_t prologue_offset = *offset_ptr;
//DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr);
@@ -416,7 +416,7 @@ DWARFDebugLine::ParsePrologue(const Data
return false;
prologue->prologue_length = debug_line_data.GetU32(offset_ptr);
- const dw_offset_t end_prologue_offset = prologue->prologue_length + *offset_ptr;
+ const lldb::offset_t end_prologue_offset = prologue->prologue_length + *offset_ptr;
prologue->min_inst_length = debug_line_data.GetU8(offset_ptr);
prologue->default_is_stmt = debug_line_data.GetU8(offset_ptr);
prologue->line_base = debug_line_data.GetU8(offset_ptr);
@@ -459,8 +459,8 @@ DWARFDebugLine::ParsePrologue(const Data
if (*offset_ptr != end_prologue_offset)
{
Host::SystemLog (Host::eSystemLogWarning,
- "warning: parsing line table prologue at 0x%8.8x should have ended at 0x%8.8x but it ended ad 0x%8.8x\n",
- prologue_offset,
+ "warning: parsing line table prologue at 0x%8.8" PRIx64 " should have ended at 0x%8.8" PRIx64 " but it ended ad 0x%8.8" PRIx64 "\n",
+ prologue_offset,
end_prologue_offset,
*offset_ptr);
}
@@ -474,7 +474,7 @@ DWARFDebugLine::ParseSupportFiles (const
dw_offset_t stmt_list,
FileSpecList &support_files)
{
- uint32_t offset = stmt_list + 4; // Skip the total length
+ lldb::offset_t offset = stmt_list + 4; // Skip the total length
const char * s;
uint32_t version = debug_line_data.GetU16(&offset);
if (version != 2)
@@ -554,7 +554,7 @@ DWARFDebugLine::ParseSupportFiles (const
if (offset != end_prologue_offset)
{
Host::SystemLog (Host::eSystemLogError,
- "warning: parsing line table prologue at 0x%8.8x should have ended at 0x%8.8x but it ended ad 0x%8.8x\n",
+ "warning: parsing line table prologue at 0x%8.8x should have ended at 0x%8.8x but it ended ad 0x%8.8" PRIx64 "\n",
stmt_list,
end_prologue_offset,
offset);
@@ -573,12 +573,12 @@ bool
DWARFDebugLine::ParseStatementTable
(
const DataExtractor& debug_line_data,
- dw_offset_t* offset_ptr,
+ lldb::offset_t* offset_ptr,
DWARFDebugLine::State::Callback callback,
void* userData
)
{
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE));
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE));
Prologue::shared_ptr prologue(new Prologue());
@@ -598,11 +598,11 @@ DWARFDebugLine::ParseStatementTable
}
if (log)
- prologue->Dump (log.get());
+ prologue->Dump (log);
const dw_offset_t end_offset = debug_line_offset + prologue->total_length + sizeof(prologue->total_length);
- State state(prologue, log.get(), callback, userData);
+ State state(prologue, log, callback, userData);
while (*offset_ptr < end_offset)
{
@@ -613,7 +613,7 @@ DWARFDebugLine::ParseStatementTable
{
// Extended Opcodes always start with a zero opcode followed by
// a uleb128 length so you can skip ones you don't know about
- dw_offset_t ext_offset = *offset_ptr;
+ lldb::offset_t ext_offset = *offset_ptr;
dw_uleb128_t len = debug_line_data.GetULEB128(offset_ptr);
dw_offset_t arg_size = len - (*offset_ptr - ext_offset);
@@ -804,8 +804,8 @@ DWARFDebugLine::ParseStatementTable
// field in the header, plus the value of the line_range field,
// minus 1 (line base + line range - 1). If the desired line
// increment is greater than the maximum line increment, a standard
- // opcode must be used instead of a special opcode. The âaddress
- // advanceâ is calculated by dividing the desired address increment
+ // opcode must be used instead of a special opcode. The "address
+ // advance" is calculated by dividing the desired address increment
// by the minimum_instruction_length field from the header. The
// special opcode is then calculated using the following formula:
//
@@ -873,7 +873,7 @@ ParseStatementTableCallback(dw_offset_t
// the prologue and all rows.
//----------------------------------------------------------------------
bool
-DWARFDebugLine::ParseStatementTable(const DataExtractor& debug_line_data, uint32_t* offset_ptr, LineTable* line_table)
+DWARFDebugLine::ParseStatementTable(const DataExtractor& debug_line_data, lldb::offset_t *offset_ptr, LineTable* line_table)
{
return ParseStatementTable(debug_line_data, offset_ptr, ParseStatementTableCallback, line_table);
}
@@ -1122,7 +1122,7 @@ DWARFDebugLine::Row::Reset(bool default_
void
DWARFDebugLine::Row::Dump(Log *log) const
{
- log->Printf( "0x%16.16llx %6u %6u %6u %3u %s%s%s%s%s",
+ log->Printf( "0x%16.16" PRIx64 " %6u %6u %6u %3u %s%s%s%s%s",
address,
line,
column,
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h Thu Jun 6 19:06:43 2013
@@ -68,7 +68,7 @@ public:
{
}
- typedef STD_SHARED_PTR(Prologue) shared_ptr;
+ typedef std::shared_ptr<Prologue> shared_ptr;
uint32_t total_length; // The size in bytes of the statement information for this compilation unit (not including the total_length field itself).
uint16_t version; // Version identifier for the statement information format.
@@ -135,7 +135,7 @@ public:
//------------------------------------------------------------------
struct LineTable
{
- typedef STD_SHARED_PTR(LineTable) shared_ptr;
+ typedef std::shared_ptr<LineTable> shared_ptr;
LineTable() :
prologue(),
@@ -197,11 +197,11 @@ public:
static bool DumpOpcodes(lldb_private::Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t line_offset = DW_INVALID_OFFSET, uint32_t dump_flags = 0); // If line_offset is invalid, dump everything
static bool DumpLineTableRows(lldb_private::Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t line_offset = DW_INVALID_OFFSET); // If line_offset is invalid, dump everything
static bool ParseSupportFiles(const lldb::ModuleSP &module_sp, const lldb_private::DataExtractor& debug_line_data, const char *cu_comp_dir, dw_offset_t stmt_list, lldb_private::FileSpecList &support_files);
- static bool ParsePrologue(const lldb_private::DataExtractor& debug_line_data, dw_offset_t* offset_ptr, Prologue* prologue);
- static bool ParseStatementTable(const lldb_private::DataExtractor& debug_line_data, dw_offset_t* offset_ptr, State::Callback callback, void* userData);
+ static bool ParsePrologue(const lldb_private::DataExtractor& debug_line_data, lldb::offset_t* offset_ptr, Prologue* prologue);
+ static bool ParseStatementTable(const lldb_private::DataExtractor& debug_line_data, lldb::offset_t* offset_ptr, State::Callback callback, void* userData);
static dw_offset_t DumpStatementTable(lldb_private::Log *log, const lldb_private::DataExtractor& debug_line_data, const dw_offset_t line_offset);
static dw_offset_t DumpStatementOpcodes(lldb_private::Log *log, const lldb_private::DataExtractor& debug_line_data, const dw_offset_t line_offset, uint32_t flags);
- static bool ParseStatementTable(const lldb_private::DataExtractor& debug_line_data, uint32_t* offset_ptr, LineTable* line_table);
+ static bool ParseStatementTable(const lldb_private::DataExtractor& debug_line_data, lldb::offset_t *offset_ptr, LineTable* line_table);
static void Parse(const lldb_private::DataExtractor& debug_line_data, DWARFDebugLine::State::Callback callback, void* userData);
// static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue, const DWARFDebugLine::Row::collection& state_coll, const uint32_t addr_size, BinaryStreamBuf &debug_line_data);
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp Thu Jun 6 19:06:43 2013
@@ -26,7 +26,7 @@ DWARFDebugMacinfo::~DWARFDebugMacinfo()
}
void
-DWARFDebugMacinfo::Dump(Stream *s, const DataExtractor& macinfo_data, dw_offset_t offset)
+DWARFDebugMacinfo::Dump(Stream *s, const DataExtractor& macinfo_data, lldb::offset_t offset)
{
DWARFDebugMacinfoEntry maninfo_entry;
if (macinfo_data.GetByteSize() == 0)
@@ -34,7 +34,7 @@ DWARFDebugMacinfo::Dump(Stream *s, const
s->PutCString("< EMPTY >\n");
return;
}
- if (offset == DW_INVALID_OFFSET)
+ if (offset == LLDB_INVALID_OFFSET)
{
offset = 0;
while (maninfo_entry.Extract(macinfo_data, &offset))
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h Thu Jun 6 19:06:43 2013
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFDebugLine_h_
-#define SymbolFileDWARF_DWARFDebugLine_h_
+#ifndef SymbolFileDWARF_DWARFDebugMacinfo_h_
+#define SymbolFileDWARF_DWARFDebugMacinfo_h_
#include "SymbolFileDWARF.h"
@@ -22,8 +22,8 @@ public:
static void
Dump (lldb_private::Stream *s,
const lldb_private::DataExtractor& macinfo_data,
- dw_offset_t offset = DW_INVALID_OFFSET);
+ lldb::offset_t offset = LLDB_INVALID_OFFSET);
};
-#endif // SymbolFileDWARF_DWARFDebugLine_h_
+#endif // SymbolFileDWARF_DWARFDebugMacinfo_h_
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp Thu Jun 6 19:06:43 2013
@@ -80,7 +80,7 @@ DWARFDebugMacinfoEntry::Dump(Stream *s)
bool
-DWARFDebugMacinfoEntry::Extract(const DataExtractor& mac_info_data, dw_offset_t* offset_ptr)
+DWARFDebugMacinfoEntry::Extract(const DataExtractor& mac_info_data, lldb::offset_t* offset_ptr)
{
if (mac_info_data.ValidOffset(*offset_ptr))
{
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h Thu Jun 6 19:06:43 2013
@@ -39,7 +39,7 @@ public:
bool
Extract(const lldb_private::DataExtractor& mac_info_data,
- dw_offset_t* offset_ptr);
+ lldb::offset_t* offset_ptr);
protected:
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp Thu Jun 6 19:06:43 2013
@@ -32,15 +32,15 @@ bool
DWARFDebugPubnames::Extract(const DataExtractor& data)
{
Timer scoped_timer (__PRETTY_FUNCTION__,
- "DWARFDebugPubnames::Extract (byte_size = %zu)",
- data.GetByteSize());
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES));
+ "DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")",
+ (uint64_t)data.GetByteSize());
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES));
if (log)
- log->Printf("DWARFDebugPubnames::Extract (byte_size = %zu)", data.GetByteSize());
+ log->Printf("DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")", (uint64_t)data.GetByteSize());
if (data.ValidOffset(0))
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
DWARFDebugPubnamesSet set;
while (data.ValidOffset(offset))
@@ -54,7 +54,7 @@ DWARFDebugPubnames::Extract(const DataEx
break;
}
if (log)
- Dump (log.get());
+ Dump (log);
return true;
}
return false;
@@ -68,7 +68,7 @@ DWARFDebugPubnames::GeneratePubnames(Sym
"DWARFDebugPubnames::GeneratePubnames (data = %p)",
dwarf2Data);
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES));
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES));
if (log)
log->Printf("DWARFDebugPubnames::GeneratePubnames (data = %p)", dwarf2Data);
@@ -124,6 +124,7 @@ DWARFDebugPubnames::GeneratePubnames(Sym
break;
case DW_AT_MIPS_linkage_name:
+ case DW_AT_linkage_name:
if (attributes.ExtractFormValueAtIndex(dwarf2Data, i, form_value))
mangled = form_value.AsCString(debug_str);
break;
@@ -205,7 +206,7 @@ DWARFDebugPubnames::GeneratePubnames(Sym
if (m_sets.empty())
return false;
if (log)
- Dump (log.get());
+ Dump (log);
return true;
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp Thu Jun 6 19:06:43 2013
@@ -78,7 +78,7 @@ DWARFDebugPubnamesSet::InitNameIndexes()
bool
-DWARFDebugPubnamesSet::Extract(const DataExtractor& data, uint32_t* offset_ptr)
+DWARFDebugPubnamesSet::Extract(const DataExtractor& data, lldb::offset_t *offset_ptr)
{
if (data.ValidOffset(*offset_ptr))
{
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h Thu Jun 6 19:06:43 2013
@@ -70,7 +70,7 @@ public:
uint32_t NumDescriptors() const { return m_descriptors.size(); }
void AddDescriptor(dw_offset_t cu_rel_offset, const char* name);
void Clear();
- bool Extract(const lldb_private::DataExtractor& debug_pubnames_data, uint32_t* offset_ptr);
+ bool Extract(const lldb_private::DataExtractor& debug_pubnames_data, lldb::offset_t *offset_ptr);
void Dump(lldb_private::Log *s) const;
void InitNameIndexes() const;
void Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const;
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp Thu Jun 6 19:06:43 2013
@@ -28,7 +28,7 @@ void
DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data)
{
RangeList range_list;
- dw_offset_t offset = 0;
+ lldb::offset_t offset = 0;
dw_offset_t debug_ranges_offset = offset;
while (Extract(dwarf2Data, &offset, range_list))
{
@@ -82,11 +82,11 @@ DWARFDebugRanges::Extract(SymbolFileDWAR
//}
bool
-DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data, uint32_t* offset_ptr, RangeList &range_list)
+DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data, lldb::offset_t *offset_ptr, RangeList &range_list)
{
range_list.Clear();
- uint32_t range_offset = *offset_ptr;
+ lldb::offset_t range_offset = *offset_ptr;
const DataExtractor& debug_ranges_data = dwarf2Data->get_debug_ranges_data();
uint32_t addr_size = debug_ranges_data.GetAddressByteSize();
@@ -105,12 +105,12 @@ DWARFDebugRanges::Extract(SymbolFileDWAR
{
case 2:
if (begin == 0xFFFFull)
- begin = DW_INVALID_ADDRESS;
+ begin = LLDB_INVALID_ADDRESS;
break;
case 4:
if (begin == 0xFFFFFFFFull)
- begin = DW_INVALID_ADDRESS;
+ begin = LLDB_INVALID_ADDRESS;
break;
case 8:
@@ -130,60 +130,9 @@ DWARFDebugRanges::Extract(SymbolFileDWAR
return range_offset != *offset_ptr;
}
-//
-//dw_addr_t
-//DWARFDebugRanges::RangeList::LowestAddress(const dw_addr_t cu_base_addr) const
-//{
-// dw_addr_t addr = DW_INVALID_ADDRESS;
-// dw_addr_t curr_base_addr = cu_base_addr;
-// if (!ranges.empty())
-// {
-// Range::const_iterator pos = ranges.begin();
-// Range::const_iterator end_pos = ranges.end();
-// for (pos = ranges.begin(); pos != end_pos; ++pos)
-// {
-// if (pos->begin_offset == DW_INVALID_ADDRESS)
-// curr_base_addr = pos->end_offset;
-// else if (curr_base_addr != DW_INVALID_ADDRESS)
-// {
-// dw_addr_t curr_addr = curr_base_addr + pos->begin_offset;
-// if (addr > curr_addr)
-// addr = curr_addr;
-// }
-// }
-// }
-// return addr;
-//}
-//
-//dw_addr_t
-//DWARFDebugRanges::RangeList::HighestAddress(const dw_addr_t cu_base_addr) const
-//{
-// dw_addr_t addr = 0;
-// dw_addr_t curr_base_addr = cu_base_addr;
-// if (!ranges.empty())
-// {
-// Range::const_iterator pos = ranges.begin();
-// Range::const_iterator end_pos = ranges.end();
-// for (pos = ranges.begin(); pos != end_pos; ++pos)
-// {
-// if (pos->begin_offset == DW_INVALID_ADDRESS)
-// curr_base_addr = pos->end_offset;
-// else if (curr_base_addr != DW_INVALID_ADDRESS)
-// {
-// dw_addr_t curr_addr = curr_base_addr + pos->end_offset;
-// if (addr < curr_addr)
-// addr = curr_addr;
-// }
-// }
-// }
-// if (addr != 0)
-// return addr;
-// return DW_INVALID_ADDRESS;
-//}
-//
void
-DWARFDebugRanges::Dump(Stream &s, const DataExtractor& debug_ranges_data, uint32_t* offset_ptr, dw_addr_t cu_base_addr)
+DWARFDebugRanges::Dump(Stream &s, const DataExtractor& debug_ranges_data, lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr)
{
uint32_t addr_size = s.GetAddressByteSize();
bool verbose = s.GetVerbose();
@@ -196,7 +145,7 @@ DWARFDebugRanges::Dump(Stream &s, const
// Extend 4 byte addresses that consits of 32 bits of 1's to be 64 bits
// of ones
if (begin == 0xFFFFFFFFull && addr_size == 4)
- begin = DW_INVALID_ADDRESS;
+ begin = LLDB_INVALID_ADDRESS;
s.Indent();
if (verbose)
@@ -210,7 +159,7 @@ DWARFDebugRanges::Dump(Stream &s, const
s.PutCString(" End");
break;
}
- else if (begin == DW_INVALID_ADDRESS)
+ else if (begin == LLDB_INVALID_ADDRESS)
{
// A base address selection entry
base_addr = end;
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h Thu Jun 6 19:06:43 2013
@@ -26,14 +26,14 @@ public:
DWARFDebugRanges();
~DWARFDebugRanges();
void Extract(SymbolFileDWARF* dwarf2Data);
- static void Dump(lldb_private::Stream &s, const lldb_private::DataExtractor& debug_ranges_data, uint32_t* offset_ptr, dw_addr_t cu_base_addr);
+ static void Dump(lldb_private::Stream &s, const lldb_private::DataExtractor& debug_ranges_data, lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr);
bool FindRanges(dw_offset_t debug_ranges_offset, DWARFDebugRanges::RangeList& range_list) const;
protected:
bool
Extract (SymbolFileDWARF* dwarf2Data,
- uint32_t* offset_ptr,
+ lldb::offset_t *offset_ptr,
RangeList &range_list);
typedef std::map<dw_offset_t, RangeList> range_map;
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp Thu Jun 6 19:06:43 2013
@@ -39,7 +39,21 @@ DWARFDeclContext::GetQualifiedName () co
{
if (pos != begin)
m_qualified_name.append("::");
- m_qualified_name.append(pos->name);
+ if (pos->name == NULL)
+ {
+ if (pos->tag == DW_TAG_namespace)
+ m_qualified_name.append ("(anonymous namespace)");
+ else if (pos->tag == DW_TAG_class_type)
+ m_qualified_name.append ("(anonymous class)");
+ else if (pos->tag == DW_TAG_structure_type)
+ m_qualified_name.append ("(anonymous struct)");
+ else if (pos->tag == DW_TAG_union_type)
+ m_qualified_name.append ("(anonymous union)");
+ else
+ m_qualified_name.append ("(anonymous)");
+ }
+ else
+ m_qualified_name.append(pos->name);
}
}
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp Thu Jun 6 19:06:43 2013
@@ -38,7 +38,7 @@ static uint8_t g_form_sizes_addr4[] =
0, // 0x0d DW_FORM_sdata
4, // 0x0e DW_FORM_strp
0, // 0x0f DW_FORM_udata
- 4, // 0x10 DW_FORM_ref_addr
+ 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
1, // 0x11 DW_FORM_ref1
2, // 0x12 DW_FORM_ref2
4, // 0x13 DW_FORM_ref4
@@ -77,7 +77,7 @@ g_form_sizes_addr8[] =
0, // 0x0d DW_FORM_sdata
4, // 0x0e DW_FORM_strp
0, // 0x0f DW_FORM_udata
- 8, // 0x10 DW_FORM_ref_addr
+ 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
1, // 0x11 DW_FORM_ref1
2, // 0x12 DW_FORM_ref2
4, // 0x13 DW_FORM_ref4
@@ -114,7 +114,7 @@ DWARFFormValue::DWARFFormValue(dw_form_t
}
bool
-DWARFFormValue::ExtractValue(const DataExtractor& data, uint32_t* offset_ptr, const DWARFCompileUnit* cu)
+DWARFFormValue::ExtractValue(const DataExtractor& data, lldb::offset_t* offset_ptr, const DWARFCompileUnit* cu)
{
bool indirect = false;
bool is_block = false;
@@ -145,7 +145,12 @@ DWARFFormValue::ExtractValue(const DataE
case DW_FORM_strp: m_value.value.uval = data.GetU32(offset_ptr); break;
// case DW_FORM_APPLE_db_str:
case DW_FORM_udata: m_value.value.uval = data.GetULEB128(offset_ptr); break;
- case DW_FORM_ref_addr: m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu)); break;
+ case DW_FORM_ref_addr:
+ if (cu->GetVersion() <= 2)
+ m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu));
+ else
+ m_value.value.uval = data.GetU32(offset_ptr); // 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet
+ break;
case DW_FORM_ref1: m_value.value.uval = data.GetU8(offset_ptr); break;
case DW_FORM_ref2: m_value.value.uval = data.GetU16(offset_ptr); break;
case DW_FORM_ref4: m_value.value.uval = data.GetU32(offset_ptr); break;
@@ -178,13 +183,13 @@ DWARFFormValue::ExtractValue(const DataE
}
bool
-DWARFFormValue::SkipValue(const DataExtractor& debug_info_data, uint32_t* offset_ptr, const DWARFCompileUnit* cu) const
+DWARFFormValue::SkipValue(const DataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu) const
{
return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, cu);
}
bool
-DWARFFormValue::SkipValue(dw_form_t form, const DataExtractor& debug_info_data, uint32_t* offset_ptr, const DWARFCompileUnit* cu)
+DWARFFormValue::SkipValue(dw_form_t form, const DataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu)
{
switch (form)
{
@@ -203,10 +208,16 @@ DWARFFormValue::SkipValue(dw_form_t form
// Compile unit address sized values
case DW_FORM_addr:
- case DW_FORM_ref_addr:
*offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu);
return true;
+ case DW_FORM_ref_addr:
+ if (cu->GetVersion() <= 2)
+ *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu);
+ else
+ *offset_ptr += 4;// 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet
+ return true;
+
// 0 bytes values (implied from DW_FORM)
case DW_FORM_flag_present:
return true;
@@ -295,7 +306,7 @@ DWARFFormValue::Dump(Stream &s, const Da
switch (m_form)
{
case DW_FORM_exprloc:
- case DW_FORM_block: s.Printf("<0x%llx> ", uvalue); break;
+ case DW_FORM_block: s.Printf("<0x%" PRIx64 "> ", uvalue); break;
case DW_FORM_block1: s.Printf("<0x%2.2x> ", (uint8_t)uvalue); break;
case DW_FORM_block2: s.Printf("<0x%4.4x> ", (uint16_t)uvalue); break;
case DW_FORM_block4: s.Printf("<0x%8.8x> ", (uint32_t)uvalue); break;
@@ -337,14 +348,17 @@ DWARFFormValue::Dump(Stream &s, const Da
case DW_FORM_ref_addr:
{
- s.Address(uvalue, sizeof (uint64_t) * 2);
+ if (cu->GetVersion() <= 2)
+ s.Address(uvalue, sizeof (uint64_t) * 2);
+ else
+ s.Address(uvalue, 4 * 2);// 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet
break;
}
case DW_FORM_ref1: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%2.2x", (uint8_t)uvalue); break;
case DW_FORM_ref2: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%4.4x", (uint16_t)uvalue); break;
case DW_FORM_ref4: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%4.4x", (uint32_t)uvalue); break;
- case DW_FORM_ref8: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%8.8llx", uvalue); break;
- case DW_FORM_ref_udata: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%llx", uvalue); break;
+ case DW_FORM_ref8: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%8.8" PRIx64, uvalue); break;
+ case DW_FORM_ref_udata: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%" PRIx64, uvalue); break;
// All DW_FORM_indirect attributes should be resolved prior to calling this function
case DW_FORM_indirect: s.PutCString("DW_FORM_indirect"); break;
@@ -359,7 +373,7 @@ DWARFFormValue::Dump(Stream &s, const Da
if (verbose)
s.PutCString(" => ");
- s.Printf("{0x%8.8llx}", (uvalue + (cu ? cu->GetOffset() : 0)));
+ s.Printf("{0x%8.8" PRIx64 "}", (uvalue + (cu ? cu->GetOffset() : 0)));
}
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h Thu Jun 6 19:06:43 2013
@@ -49,20 +49,23 @@ public:
void SetForm(dw_form_t form) { m_form = form; }
const ValueType& Value() const { return m_value; }
void Dump(lldb_private::Stream &s, const lldb_private::DataExtractor* debug_str_data, const DWARFCompileUnit* cu) const;
- bool ExtractValue(const lldb_private::DataExtractor& data, uint32_t* offset_ptr, const DWARFCompileUnit* cu);
+ bool ExtractValue(const lldb_private::DataExtractor& data,
+ lldb::offset_t* offset_ptr,
+ const DWARFCompileUnit* cu);
bool IsInlinedCStr() const { return (m_value.data != NULL) && m_value.data == (uint8_t*)m_value.value.cstr; }
const uint8_t* BlockData() const;
uint64_t Reference(const DWARFCompileUnit* cu) const;
uint64_t Reference (dw_offset_t offset) const;
bool ResolveCompileUnitReferences(const DWARFCompileUnit* cu);
+ bool Boolean() const { return m_value.value.uval != 0; }
uint64_t Unsigned() const { return m_value.value.uval; }
void SetUnsigned(uint64_t uval) { m_value.value.uval = uval; }
int64_t Signed() const { return m_value.value.sval; }
void SetSigned(int64_t sval) { m_value.value.sval = sval; }
const char* AsCString(const lldb_private::DataExtractor* debug_str_data_ptr) const;
- bool SkipValue(const lldb_private::DataExtractor& debug_info_data, uint32_t* offset_ptr, const DWARFCompileUnit* cu) const;
- static bool SkipValue(const dw_form_t form, const lldb_private::DataExtractor& debug_info_data, uint32_t* offset_ptr, const DWARFCompileUnit* cu);
-// static bool TransferValue(dw_form_t form, const lldb_private::DataExtractor& debug_info_data, uint32_t* offset_ptr, const DWARFCompileUnit* cu, BinaryStreamBuf& out_buff);
+ bool SkipValue(const lldb_private::DataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu) const;
+ static bool SkipValue(const dw_form_t form, const lldb_private::DataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu);
+// static bool TransferValue(dw_form_t form, const lldb_private::DataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu, BinaryStreamBuf& out_buff);
// static bool TransferValue(const DWARFFormValue& formValue, const DWARFCompileUnit* cu, BinaryStreamBuf& out_buff);
// static bool PutUnsigned(dw_form_t form, dw_offset_t offset, uint64_t value, BinaryStreamBuf& out_buff, const DWARFCompileUnit* cu, bool fixup_cu_relative_refs);
static bool IsBlockForm(const dw_form_t form);
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp Thu Jun 6 19:06:43 2013
@@ -15,7 +15,7 @@
using namespace lldb_private;
-static int print_dwarf_exp_op (Stream &s, const DataExtractor& data, uint32_t* offset_ptr, int address_size, int dwarf_ref_size);
+static int print_dwarf_exp_op (Stream &s, const DataExtractor& data, lldb::offset_t *offset_ptr, int address_size, int dwarf_ref_size);
int
print_dwarf_expression (Stream &s,
@@ -25,7 +25,7 @@ print_dwarf_expression (Stream &s,
bool location_expression)
{
int op_count = 0;
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
while (data.ValidOffset(offset))
{
if (location_expression && op_count > 0)
@@ -48,7 +48,7 @@ print_dwarf_expression (Stream &s,
static int
print_dwarf_exp_op (Stream &s,
const DataExtractor& data,
- uint32_t* offset_ptr,
+ lldb::offset_t *offset_ptr,
int address_size,
int dwarf_ref_size)
{
@@ -71,7 +71,7 @@ print_dwarf_exp_op (Stream &s,
{
uint = data.GetULEB128(offset_ptr);
sint = data.GetSLEB128(offset_ptr);
- s.Printf("%llu %lli", uint, sint);
+ s.Printf("%" PRIu64 " %" PRIi64, uint, sint);
return 0;
}
if (opcode_class != DRC_ONEOPERAND)
@@ -156,16 +156,16 @@ print_dwarf_exp_op (Stream &s,
switch (size)
{
- case -1: sint = (int8_t) data.GetU8(offset_ptr); s.Printf("%+lli", sint); break;
- case -2: sint = (int16_t) data.GetU16(offset_ptr); s.Printf("%+lli", sint); break;
- case -4: sint = (int32_t) data.GetU32(offset_ptr); s.Printf("%+lli", sint); break;
- case -8: sint = (int64_t) data.GetU64(offset_ptr); s.Printf("%+lli", sint); break;
- case -128: sint = data.GetSLEB128(offset_ptr); s.Printf("%+lli", sint); break;
- case 1: uint = data.GetU8(offset_ptr); s.Printf("0x%2.2llx", uint); break;
- case 2: uint = data.GetU16(offset_ptr); s.Printf("0x%4.4llx", uint); break;
- case 4: uint = data.GetU32(offset_ptr); s.Printf("0x%8.8llx", uint); break;
- case 8: uint = data.GetU64(offset_ptr); s.Printf("0x%16.16llx", uint); break;
- case 128: uint = data.GetULEB128(offset_ptr); s.Printf("0x%llx", uint); break;
+ case -1: sint = (int8_t) data.GetU8(offset_ptr); s.Printf("%+" PRIi64, sint); break;
+ case -2: sint = (int16_t) data.GetU16(offset_ptr); s.Printf("%+" PRIi64, sint); break;
+ case -4: sint = (int32_t) data.GetU32(offset_ptr); s.Printf("%+" PRIi64, sint); break;
+ case -8: sint = (int64_t) data.GetU64(offset_ptr); s.Printf("%+" PRIi64, sint); break;
+ case -128: sint = data.GetSLEB128(offset_ptr); s.Printf("%+" PRIi64, sint); break;
+ case 1: uint = data.GetU8(offset_ptr); s.Printf("0x%2.2" PRIx64, uint); break;
+ case 2: uint = data.GetU16(offset_ptr); s.Printf("0x%4.4" PRIx64, uint); break;
+ case 4: uint = data.GetU32(offset_ptr); s.Printf("0x%8.8" PRIx64, uint); break;
+ case 8: uint = data.GetU64(offset_ptr); s.Printf("0x%16.16" PRIx64, uint); break;
+ case 128: uint = data.GetULEB128(offset_ptr); s.Printf("0x%" PRIx64, uint); break;
}
return 0;
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFLocationList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFLocationList.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFLocationList.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFLocationList.cpp Thu Jun 6 19:06:43 2013
@@ -18,7 +18,7 @@
using namespace lldb_private;
dw_offset_t
-DWARFLocationList::Dump(Stream &s, const DWARFCompileUnit* cu, const DataExtractor& debug_loc_data, dw_offset_t offset)
+DWARFLocationList::Dump(Stream &s, const DWARFCompileUnit* cu, const DataExtractor& debug_loc_data, lldb::offset_t offset)
{
uint64_t start_addr, end_addr;
uint32_t addr_size = DWARFCompileUnit::GetAddressByteSize(cu);
@@ -34,11 +34,12 @@ DWARFLocationList::Dump(Stream &s, const
s.PutCString("\n ");
s.Indent();
- s.AddressRange (start_addr + base_addr,
- end_addr + base_addr,
- cu->GetAddressByteSize(),
- NULL,
- ": ");
+ if (cu)
+ s.AddressRange (start_addr + base_addr,
+ end_addr + base_addr,
+ cu->GetAddressByteSize(),
+ NULL,
+ ": ");
uint32_t loc_length = debug_loc_data.GetU16(&offset);
DataExtractor locationData(debug_loc_data, offset, loc_length);
@@ -51,7 +52,7 @@ DWARFLocationList::Dump(Stream &s, const
}
bool
-DWARFLocationList::Extract(const DataExtractor& debug_loc_data, dw_offset_t* offset_ptr, DataExtractor& location_list_data)
+DWARFLocationList::Extract(const DataExtractor& debug_loc_data, lldb::offset_t* offset_ptr, DataExtractor& location_list_data)
{
// Initialize with no data just in case we don't find anything
location_list_data.Clear();
@@ -68,7 +69,7 @@ DWARFLocationList::Extract(const DataExt
}
size_t
-DWARFLocationList::Size(const DataExtractor& debug_loc_data, dw_offset_t offset)
+DWARFLocationList::Size(const DataExtractor& debug_loc_data, lldb::offset_t offset)
{
const dw_offset_t debug_loc_offset = offset;
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFLocationList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFLocationList.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFLocationList.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFLocationList.h Thu Jun 6 19:06:43 2013
@@ -19,16 +19,16 @@ public:
Dump (lldb_private::Stream &s,
const DWARFCompileUnit* cu,
const lldb_private::DataExtractor& debug_loc_data,
- dw_offset_t offset);
+ lldb::offset_t offset);
static bool
Extract (const lldb_private::DataExtractor& debug_loc_data,
- dw_offset_t* offset_ptr,
+ lldb::offset_t* offset_ptr,
lldb_private::DataExtractor& location_list_data);
static size_t
Size (const lldb_private::DataExtractor& debug_loc_data,
- dw_offset_t offset);
+ lldb::offset_t offset);
};
#endif // SymbolFileDWARF_DWARFLocationList_h_
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h Thu Jun 6 19:06:43 2013
@@ -32,18 +32,21 @@ struct DWARFMappedHash
dw_offset_t offset; // The DIE offset
dw_tag_t tag;
uint32_t type_flags; // Any flags for this DIEInfo
+ uint32_t qualified_name_hash; // A 32 bit hash of the fully qualified name
DIEInfo () :
offset (DW_INVALID_OFFSET),
tag (0),
- type_flags (0)
+ type_flags (0),
+ qualified_name_hash (0)
{
}
- DIEInfo (dw_offset_t o, dw_tag_t t, uint32_t f) :
+ DIEInfo (dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h) :
offset(o),
tag (t),
- type_flags (f)
+ type_flags (f),
+ qualified_name_hash (h)
{
}
@@ -53,6 +56,7 @@ struct DWARFMappedHash
offset = DW_INVALID_OFFSET;
tag = 0;
type_flags = 0;
+ qualified_name_hash = 0;
}
};
@@ -96,6 +100,37 @@ struct DWARFMappedHash
}
}
}
+
+ static void
+ ExtractDIEArray (const DIEInfoArray &die_info_array,
+ const dw_tag_t tag,
+ const uint32_t qualified_name_hash,
+ DIEArray &die_offsets)
+ {
+ if (tag == 0)
+ {
+ ExtractDIEArray (die_info_array, die_offsets);
+ }
+ else
+ {
+ const size_t count = die_info_array.size();
+ for (size_t i=0; i<count; ++i)
+ {
+ if (qualified_name_hash != die_info_array[i].qualified_name_hash)
+ continue;
+ const dw_tag_t die_tag = die_info_array[i].tag;
+ bool tag_matches = die_tag == 0 || tag == die_tag;
+ if (!tag_matches)
+ {
+ if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
+ tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
+ }
+ if (tag_matches)
+ die_offsets.push_back (die_info_array[i].offset);
+ }
+ }
+ }
+
enum AtomType
{
eAtomTypeNULL = 0u,
@@ -103,7 +138,11 @@ struct DWARFMappedHash
eAtomTypeCUOffset = 2u, // DIE offset of the compiler unit header that contains the item in question
eAtomTypeTag = 3u, // DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed 255) or DW_FORM_data2
eAtomTypeNameFlags = 4u, // Flags from enum NameFlags
- eAtomTypeTypeFlags = 5u // Flags from enum TypeFlags
+ eAtomTypeTypeFlags = 5u, // Flags from enum TypeFlags,
+ eAtomTypeQualNameHash = 6u // A 32 bit hash of the full qualified name (since all hash entries are basename only)
+ // For example a type like "std::vector<int>::iterator" would have a name of "iterator"
+ // and a 32 bit hash for "std::vector<int>::iterator" to allow us to not have to pull
+ // in debug info for a type when we know the fully qualified name.
};
// Bit definitions for the eAtomTypeTypeFlags flags
@@ -196,6 +235,7 @@ struct DWARFMappedHash
case eAtomTypeTag: return "die-tag";
case eAtomTypeNameFlags: return "name-flags";
case eAtomTypeTypeFlags: return "type-flags";
+ case eAtomTypeQualNameHash: return "qualified-name-hash";
}
return "<invalid>";
}
@@ -306,8 +346,9 @@ struct DWARFMappedHash
// void
// Dump (std::ostream* ostrm_ptr);
- uint32_t
- Read (const lldb_private::DataExtractor &data, uint32_t offset)
+ lldb::offset_t
+ Read (const lldb_private::DataExtractor &data,
+ lldb::offset_t offset)
{
ClearAtoms ();
@@ -379,8 +420,8 @@ struct DWARFMappedHash
// virtual void
// Dump (std::ostream* ostrm_ptr);
//
- virtual uint32_t
- Read (lldb_private::DataExtractor &data, uint32_t offset)
+ virtual lldb::offset_t
+ Read (lldb_private::DataExtractor &data, lldb::offset_t offset)
{
offset = MappedHash::Header<Prologue>::Read (data, offset);
if (offset != UINT32_MAX)
@@ -392,7 +433,7 @@ struct DWARFMappedHash
bool
Read (const lldb_private::DataExtractor &data,
- uint32_t *offset_ptr,
+ lldb::offset_t *offset_ptr,
DIEInfo &hash_data) const
{
const size_t num_atoms = header_data.atoms.size();
@@ -409,17 +450,22 @@ struct DWARFMappedHash
switch (header_data.atoms[i].type)
{
case eAtomTypeDIEOffset: // DIE offset, check form for encoding
- hash_data.offset = form_value.Reference (header_data.die_base_offset);
+ hash_data.offset = (dw_offset_t)form_value.Reference (header_data.die_base_offset);
break;
case eAtomTypeTag: // DW_TAG value for the DIE
- hash_data.tag = form_value.Unsigned ();
+ hash_data.tag = (dw_tag_t)form_value.Unsigned ();
case eAtomTypeTypeFlags: // Flags from enum TypeFlags
- hash_data.type_flags = form_value.Unsigned ();
+ hash_data.type_flags = (uint32_t)form_value.Unsigned ();
+ break;
+
+ case eAtomTypeQualNameHash: // Flags from enum TypeFlags
+ hash_data.qualified_name_hash = form_value.Unsigned ();
break;
+
default:
- return false;
+ // We can always skip atomes we don't know about
break;
}
}
@@ -462,7 +508,11 @@ struct DWARFMappedHash
strm.PutCString (" )");
}
break;
-
+
+ case eAtomTypeQualNameHash: // Flags from enum TypeFlags
+ strm.Printf ("0x%8.8x", hash_data.qualified_name_hash);
+ break;
+
default:
strm.Printf ("AtomType(0x%x)", header_data.atoms[i].type);
break;
@@ -559,7 +609,7 @@ struct DWARFMappedHash
virtual Result
GetHashDataForName (const char *name,
- uint32_t* hash_data_offset_ptr,
+ lldb::offset_t* hash_data_offset_ptr,
Pair &pair) const
{
pair.key = m_data.GetU32 (hash_data_offset_ptr);
@@ -580,7 +630,7 @@ struct DWARFMappedHash
}
const uint32_t count = m_data.GetU32 (hash_data_offset_ptr);
- const uint32_t min_total_hash_data_size = count * m_header.header_data.GetMinumumHashDataByteSize();
+ const size_t min_total_hash_data_size = count * m_header.header_data.GetMinumumHashDataByteSize();
if (count > 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size))
{
// We have at least one HashData entry, and we have enough
@@ -637,7 +687,7 @@ struct DWARFMappedHash
virtual Result
AppendHashDataForRegularExpression (const lldb_private::RegularExpression& regex,
- uint32_t* hash_data_offset_ptr,
+ lldb::offset_t* hash_data_offset_ptr,
Pair &pair) const
{
pair.key = m_data.GetU32 (hash_data_offset_ptr);
@@ -653,7 +703,7 @@ struct DWARFMappedHash
return eResultError;
const uint32_t count = m_data.GetU32 (hash_data_offset_ptr);
- const uint32_t min_total_hash_data_size = count * m_header.header_data.GetMinumumHashDataByteSize();
+ const size_t min_total_hash_data_size = count * m_header.header_data.GetMinumumHashDataByteSize();
if (count > 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size))
{
const bool match = regex.Execute(strp_cstr);
@@ -712,10 +762,10 @@ struct DWARFMappedHash
Pair pair;
for (uint32_t offset_idx=0; offset_idx<hash_count; ++offset_idx)
{
- uint32_t hash_data_offset = GetHashDataOffset (offset_idx);
+ lldb::offset_t hash_data_offset = GetHashDataOffset (offset_idx);
while (hash_data_offset != UINT32_MAX)
{
- const uint32_t prev_hash_data_offset = hash_data_offset;
+ const lldb::offset_t prev_hash_data_offset = hash_data_offset;
Result hash_result = AppendHashDataForRegularExpression (regex, &hash_data_offset, pair);
if (prev_hash_data_offset == hash_data_offset)
break;
@@ -749,7 +799,7 @@ struct DWARFMappedHash
for (uint32_t offset_idx=0; offset_idx<hash_count; ++offset_idx)
{
bool done = false;
- uint32_t hash_data_offset = GetHashDataOffset (offset_idx);
+ lldb::offset_t hash_data_offset = GetHashDataOffset (offset_idx);
while (!done && hash_data_offset != UINT32_MAX)
{
KeyType key = m_data.GetU32 (&hash_data_offset);
@@ -795,6 +845,18 @@ struct DWARFMappedHash
return die_info_array.size();
}
+ size_t
+ FindByNameAndTagAndQualifiedNameHash (const char *name,
+ const dw_tag_t tag,
+ const uint32_t qualified_name_hash,
+ DIEArray &die_offsets)
+ {
+ DIEInfoArray die_info_array;
+ if (FindByName(name, die_info_array))
+ DWARFMappedHash::ExtractDIEArray (die_info_array, tag, qualified_name_hash, die_offsets);
+ return die_info_array.size();
+ }
+
size_t
FindCompleteObjCClassByName (const char *name, DIEArray &die_offsets, bool must_be_implementation)
{
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp Thu Jun 6 19:06:43 2013
@@ -51,7 +51,7 @@ LogChannelDWARF::CreateInstance ()
return new LogChannelDWARF ();
}
-const char *
+lldb_private::ConstString
LogChannelDWARF::GetPluginNameStatic()
{
return SymbolFileDWARF::GetPluginNameStatic();
@@ -63,15 +63,9 @@ LogChannelDWARF::GetPluginDescriptionSta
return "DWARF log channel for debugging plug-in issues.";
}
-const char *
+lldb_private::ConstString
LogChannelDWARF::GetPluginName()
{
- return GetPluginDescriptionStatic();
-}
-
-const char *
-LogChannelDWARF::GetShortPluginName()
-{
return GetPluginNameStatic();
}
@@ -86,18 +80,16 @@ void
LogChannelDWARF::Delete ()
{
g_log_channel = NULL;
- m_log_sp.reset();
}
void
LogChannelDWARF::Disable (const char **categories, Stream *feedback_strm)
{
- if (!m_log_sp)
+ if (m_log_ap.get() == NULL)
return;
- g_log_channel = this;
- uint32_t flag_bits = m_log_sp->GetMask().Get();
+ uint32_t flag_bits = m_log_ap->GetMask().Get();
for (size_t i = 0; categories[i] != NULL; ++i)
{
const char *arg = categories[i];
@@ -122,7 +114,7 @@ LogChannelDWARF::Disable (const char **c
if (flag_bits == 0)
Delete ();
else
- m_log_sp->GetMask().Reset (flag_bits);
+ m_log_ap->GetMask().Reset (flag_bits);
return;
}
@@ -138,7 +130,11 @@ LogChannelDWARF::Enable
{
Delete ();
- m_log_sp.reset(new Log (log_stream_sp));
+ if (m_log_ap)
+ m_log_ap->SetStream(log_stream_sp);
+ else
+ m_log_ap.reset(new Log (log_stream_sp));
+
g_log_channel = this;
uint32_t flag_bits = 0;
bool got_unknown_category = false;
@@ -168,9 +164,9 @@ LogChannelDWARF::Enable
}
if (flag_bits == 0)
flag_bits = DWARF_LOG_DEFAULT;
- m_log_sp->GetMask().Reset(flag_bits);
- m_log_sp->GetOptions().Reset(log_options);
- return m_log_sp.get() != NULL;
+ m_log_ap->GetMask().Reset(flag_bits);
+ m_log_ap->GetOptions().Reset(log_options);
+ return m_log_ap.get() != NULL;
}
void
@@ -182,41 +178,41 @@ LogChannelDWARF::ListCategories (Stream
" line - log the parsing if .debug_line\n"
" pubnames - log the parsing if .debug_pubnames\n"
" pubtypes - log the parsing if .debug_pubtypes\n"
- " lookups - log any lookups that happen by name, regex, or address\n\n"
- " completion - log struct/unions/class type completions\n\n"
- " map - log insertions of object files into DWARF debug maps\n\n",
- SymbolFileDWARF::GetPluginNameStatic());
+ " lookups - log any lookups that happen by name, regex, or address\n"
+ " completion - log struct/unions/class type completions\n"
+ " map - log insertions of object files into DWARF debug maps\n",
+ SymbolFileDWARF::GetPluginNameStatic().GetCString());
}
-LogSP
+Log *
LogChannelDWARF::GetLog ()
{
if (g_log_channel)
- return g_log_channel->m_log_sp;
+ return g_log_channel->m_log_ap.get();
- return LogSP();
+ return NULL;
}
-LogSP
+Log *
LogChannelDWARF::GetLogIfAll (uint32_t mask)
{
- if (g_log_channel && g_log_channel->m_log_sp)
+ if (g_log_channel && g_log_channel->m_log_ap.get())
{
- if (g_log_channel->m_log_sp->GetMask().AllSet(mask))
- return g_log_channel->m_log_sp;
+ if (g_log_channel->m_log_ap->GetMask().AllSet(mask))
+ return g_log_channel->m_log_ap.get();
}
- return LogSP();
+ return NULL;
}
-LogSP
+Log *
LogChannelDWARF::GetLogIfAny (uint32_t mask)
{
- if (g_log_channel && g_log_channel->m_log_sp)
+ if (g_log_channel && g_log_channel->m_log_ap.get())
{
- if (g_log_channel->m_log_sp->GetMask().AnySet(mask))
- return g_log_channel->m_log_sp;
+ if (g_log_channel->m_log_ap->GetMask().AnySet(mask))
+ return g_log_channel->m_log_ap.get();
}
- return LogSP();
+ return NULL;
}
void
@@ -224,10 +220,13 @@ LogChannelDWARF::LogIf (uint32_t mask, c
{
if (g_log_channel)
{
- LogSP log_sp(g_log_channel->m_log_sp);
- va_list args;
- va_start (args, format);
- log_sp->VAPrintf (format, args);
- va_end (args);
+ Log *log = g_log_channel->m_log_ap.get();
+ if (log && log->GetMask().AnySet(mask))
+ {
+ va_list args;
+ va_start (args, format);
+ log->VAPrintf (format, args);
+ va_end (args);
+ }
}
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h Thu Jun 6 19:06:43 2013
@@ -43,7 +43,7 @@ public:
static void
Terminate();
- static const char *
+ static lldb_private::ConstString
GetPluginNameStatic();
static const char *
@@ -52,12 +52,9 @@ public:
static lldb_private::LogChannel *
CreateInstance ();
- virtual const char *
+ virtual lldb_private::ConstString
GetPluginName();
- virtual const char *
- GetShortPluginName();
-
virtual uint32_t
GetPluginVersion();
@@ -76,13 +73,13 @@ public:
virtual void
ListCategories (lldb_private::Stream *strm);
- static lldb::LogSP
+ static lldb_private::Log *
GetLog ();
- static lldb::LogSP
+ static lldb_private::Log *
GetLogIfAll (uint32_t mask);
- static lldb::LogSP
+ static lldb_private::Log *
GetLogIfAny (uint32_t mask);
static void
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Thu Jun 6 19:06:43 2013
@@ -126,15 +126,15 @@ public:
{
StreamString log_strm;
const size_t n = m_dies.size();
- log_strm.Printf("DIEStack[%zu]:\n", n);
+ log_strm.Printf("DIEStack[%" PRIu64 "]:\n", (uint64_t)n);
for (size_t i=0; i<n; i++)
{
DWARFCompileUnit *cu = m_dies[i].cu;
const DWARFDebugInfoEntry *die = m_dies[i].die;
std::string qualified_name;
die->GetQualifiedName(dwarf, cu, qualified_name);
- log_strm.Printf ("[%zu] 0x%8.8x: %s name='%s'\n",
- i,
+ log_strm.Printf ("[%" PRIu64 "] 0x%8.8x: %s name='%s'\n",
+ (uint64_t)i,
die->GetOffset(),
DW_TAG_value_to_name(die->Tag()),
qualified_name.c_str());
@@ -207,10 +207,11 @@ SymbolFileDWARF::Terminate()
}
-const char *
+lldb_private::ConstString
SymbolFileDWARF::GetPluginNameStatic()
{
- return "dwarf";
+ static ConstString g_name("dwarf");
+ return g_name;
}
const char *
@@ -229,7 +230,7 @@ SymbolFileDWARF::CreateInstance (ObjectF
TypeList *
SymbolFileDWARF::GetTypeList ()
{
- if (m_debug_map_symfile)
+ if (GetDebugMapSymfile ())
return m_debug_map_symfile->GetTypeList();
return m_obj_file->GetModule()->GetTypeList();
@@ -263,6 +264,7 @@ GetParentSymbolContextDIE(const DWARFDeb
SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
SymbolFile (objfile),
UserID (0), // Used by SymbolFileDWARFDebugMap to when this class parses .o files to contain the .o file index/ID
+ m_debug_map_module_wp (),
m_debug_map_symfile (NULL),
m_clang_tu_decl (NULL),
m_flags(),
@@ -321,7 +323,7 @@ GetDWARFMachOSegmentName ()
UniqueDWARFASTTypeMap &
SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
{
- if (m_debug_map_symfile)
+ if (GetDebugMapSymfile ())
return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
return m_unique_ast_type_map;
}
@@ -329,7 +331,7 @@ SymbolFileDWARF::GetUniqueDWARFASTTypeMa
ClangASTContext &
SymbolFileDWARF::GetClangASTContext ()
{
- if (m_debug_map_symfile)
+ if (GetDebugMapSymfile ())
return m_debug_map_symfile->GetClangASTContext ();
ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
@@ -406,7 +408,7 @@ SymbolFileDWARF::InitializeObject()
bool
SymbolFileDWARF::SupportedVersion(uint16_t version)
{
- return version == 2 || version == 3;
+ return version == 2 || version == 3 || version == 4;
}
uint32_t
@@ -659,11 +661,27 @@ SymbolFileDWARF::DebugInfo() const
}
DWARFCompileUnit*
-SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
+SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
{
DWARFDebugInfo* info = DebugInfo();
- if (info && UserIDMatches(cu_uid))
- return info->GetCompileUnit((dw_offset_t)cu_uid).get();
+ if (info)
+ {
+ if (GetDebugMapSymfile ())
+ {
+ // The debug map symbol file made the compile units for this DWARF
+ // file which is .o file with DWARF in it, and we should have
+ // only 1 compile unit which is at offset zero in the DWARF.
+ // TODO: modify to support LTO .o files where each .o file might
+ // have multiple DW_TAG_compile_unit tags.
+ return info->GetCompileUnit(0).get();
+ }
+ else
+ {
+ // Just a normal DWARF file whose user ID for the compile unit is
+ // the DWARF offset itself
+ return info->GetCompileUnit((dw_offset_t)comp_unit->GetID()).get();
+ }
+ }
return NULL;
}
@@ -704,59 +722,58 @@ SymbolFileDWARF::ParseCompileUnit (DWARF
}
else
{
- ModuleSP module_sp (m_obj_file->GetModule());
- if (module_sp)
+ if (GetDebugMapSymfile ())
+ {
+ // Let the debug map create the compile unit
+ cu_sp = m_debug_map_symfile->GetCompileUnit(this);
+ dwarf_cu->SetUserData(cu_sp.get());
+ }
+ else
{
- const DWARFDebugInfoEntry * cu_die = dwarf_cu->GetCompileUnitDIEOnly ();
- if (cu_die)
+ ModuleSP module_sp (m_obj_file->GetModule());
+ if (module_sp)
{
- const char * cu_die_name = cu_die->GetName(this, dwarf_cu);
- const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_comp_dir, NULL);
- LanguageType cu_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0);
- if (cu_die_name)
- {
- std::string ramapped_file;
- FileSpec cu_file_spec;
-
- if (cu_die_name[0] == '/' || cu_comp_dir == NULL || cu_comp_dir[0] == '\0')
- {
- // If we have a full path to the compile unit, we don't need to resolve
- // the file. This can be expensive e.g. when the source files are NFS mounted.
- if (module_sp->RemapSourceFile(cu_die_name, ramapped_file))
- cu_file_spec.SetFile (ramapped_file.c_str(), false);
- else
- cu_file_spec.SetFile (cu_die_name, false);
- }
- else
- {
- std::string fullpath(cu_comp_dir);
- if (*fullpath.rbegin() != '/')
- fullpath += '/';
- fullpath += cu_die_name;
- if (module_sp->RemapSourceFile (fullpath.c_str(), ramapped_file))
- cu_file_spec.SetFile (ramapped_file.c_str(), false);
+ const DWARFDebugInfoEntry * cu_die = dwarf_cu->GetCompileUnitDIEOnly ();
+ if (cu_die)
+ {
+ const char * cu_die_name = cu_die->GetName(this, dwarf_cu);
+ const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_comp_dir, NULL);
+ LanguageType cu_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0);
+ if (cu_die_name)
+ {
+ std::string ramapped_file;
+ FileSpec cu_file_spec;
+
+ if (cu_die_name[0] == '/' || cu_comp_dir == NULL || cu_comp_dir[0] == '\0')
+ {
+ // If we have a full path to the compile unit, we don't need to resolve
+ // the file. This can be expensive e.g. when the source files are NFS mounted.
+ if (module_sp->RemapSourceFile(cu_die_name, ramapped_file))
+ cu_file_spec.SetFile (ramapped_file.c_str(), false);
+ else
+ cu_file_spec.SetFile (cu_die_name, false);
+ }
else
- cu_file_spec.SetFile (fullpath.c_str(), false);
- }
-
- cu_sp.reset(new CompileUnit (module_sp,
- dwarf_cu,
- cu_file_spec,
- MakeUserID(dwarf_cu->GetOffset()),
- cu_language));
- if (cu_sp)
- {
- dwarf_cu->SetUserData(cu_sp.get());
-
- if (m_debug_map_symfile)
{
- // Let the symbol file register the compile unit with
- // the symbol vendor using its compile unit index
- // when we are doing DWARF in .o files + debug map
- m_debug_map_symfile->SetCompileUnit(this, cu_sp);
+ std::string fullpath(cu_comp_dir);
+ if (*fullpath.rbegin() != '/')
+ fullpath += '/';
+ fullpath += cu_die_name;
+ if (module_sp->RemapSourceFile (fullpath.c_str(), ramapped_file))
+ cu_file_spec.SetFile (ramapped_file.c_str(), false);
+ else
+ cu_file_spec.SetFile (fullpath.c_str(), false);
}
- else
+
+ cu_sp.reset(new CompileUnit (module_sp,
+ dwarf_cu,
+ cu_file_spec,
+ MakeUserID(dwarf_cu->GetOffset()),
+ cu_language));
+ if (cu_sp)
{
+ dwarf_cu->SetUserData(cu_sp.get());
+
// Figure out the compile unit index if we weren't given one
if (cu_idx == UINT32_MAX)
DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx);
@@ -864,7 +881,7 @@ SymbolFileDWARF::ParseCompileUnitFunctio
func_name.SetValue(ConstString(name), false);
FunctionSP func_sp;
- std::auto_ptr<Declaration> decl_ap;
+ std::unique_ptr<Declaration> decl_ap;
if (decl_file != 0 || decl_line != 0 || decl_column != 0)
decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
decl_line,
@@ -875,40 +892,70 @@ SymbolFileDWARF::ParseCompileUnitFunctio
assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
- func_range.GetBaseAddress().ResolveLinkedAddress();
-
- const user_id_t func_user_id = MakeUserID(die->GetOffset());
- func_sp.reset(new Function (sc.comp_unit,
- func_user_id, // UserID is the DIE offset
- func_user_id,
- func_name,
- func_type,
- func_range)); // first address range
-
- if (func_sp.get() != NULL)
- {
- if (frame_base.IsValid())
- func_sp->GetFrameBaseExpression() = frame_base;
- sc.comp_unit->AddFunction(func_sp);
- return func_sp.get();
+ if (FixupAddress (func_range.GetBaseAddress()))
+ {
+ const user_id_t func_user_id = MakeUserID(die->GetOffset());
+ func_sp.reset(new Function (sc.comp_unit,
+ MakeUserID(func_user_id), // UserID is the DIE offset
+ MakeUserID(func_user_id),
+ func_name,
+ func_type,
+ func_range)); // first address range
+
+ if (func_sp.get() != NULL)
+ {
+ if (frame_base.IsValid())
+ func_sp->GetFrameBaseExpression() = frame_base;
+ sc.comp_unit->AddFunction(func_sp);
+ return func_sp.get();
+ }
}
}
}
return NULL;
}
+bool
+SymbolFileDWARF::FixupAddress (Address &addr)
+{
+ SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
+ if (debug_map_symfile)
+ {
+ return debug_map_symfile->LinkOSOAddress(addr);
+ }
+ // This is a normal DWARF file, no address fixups need to happen
+ return true;
+}
+lldb::LanguageType
+SymbolFileDWARF::ParseCompileUnitLanguage (const SymbolContext& sc)
+{
+ assert (sc.comp_unit);
+ DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu)
+ {
+ const DWARFDebugInfoEntry *die = dwarf_cu->GetCompileUnitDIEOnly();
+ if (die)
+ {
+ const uint32_t language = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0);
+ if (language)
+ return (lldb::LanguageType)language;
+ }
+ }
+ return eLanguageTypeUnknown;
+}
+
size_t
SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
{
assert (sc.comp_unit);
size_t functions_added = 0;
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
+ DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (dwarf_cu)
{
DWARFDIECollection function_dies;
- const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
+ const size_t num_functions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
size_t func_idx;
- for (func_idx = 0; func_idx < num_funtions; ++func_idx)
+ for (func_idx = 0; func_idx < num_functions; ++func_idx)
{
const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
if (sc.comp_unit->FindFunctionByUID (MakeUserID(die->GetOffset())).get() == NULL)
@@ -926,20 +973,22 @@ bool
SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
{
assert (sc.comp_unit);
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
- assert (dwarf_cu);
- const DWARFDebugInfoEntry * cu_die = dwarf_cu->GetCompileUnitDIEOnly();
-
- if (cu_die)
+ DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu)
{
- const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_comp_dir, NULL);
- dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
+ const DWARFDebugInfoEntry * cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+
+ if (cu_die)
+ {
+ const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_comp_dir, NULL);
+ dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
- // All file indexes in DWARF are one based and a file of index zero is
- // supposed to be the compile unit itself.
- support_files.Append (*sc.comp_unit);
+ // All file indexes in DWARF are one based and a file of index zero is
+ // supposed to be the compile unit itself.
+ support_files.Append (*sc.comp_unit);
- return DWARFDebugLine::ParseSupportFiles(sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
+ return DWARFDebugLine::ParseSupportFiles(sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
+ }
}
return false;
}
@@ -947,14 +996,7 @@ SymbolFileDWARF::ParseCompileUnitSupport
struct ParseDWARFLineTableCallbackInfo
{
LineTable* line_table;
- const SectionList *section_list;
- lldb::addr_t prev_sect_file_base_addr;
- lldb::addr_t curr_sect_file_base_addr;
- bool is_oso_for_debug_map;
- bool prev_in_final_executable;
- DWARFDebugLine::Row prev_row;
- SectionSP prev_section_sp;
- SectionSP curr_section_sp;
+ std::unique_ptr<LineSequence> sequence_ap;
};
//----------------------------------------------------------------------
@@ -963,7 +1005,6 @@ struct ParseDWARFLineTableCallbackInfo
static void
ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
{
- LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
if (state.row == DWARFDebugLine::State::StartParsingLineTable)
{
// Just started parsing the line table
@@ -975,150 +1016,32 @@ ParseDWARFLineTableCallback(dw_offset_t
else
{
ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
- // We have a new row, lets append it
+ LineTable* line_table = info->line_table;
- if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
- {
- info->prev_section_sp = info->curr_section_sp;
- info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
- // If this is an end sequence entry, then we subtract one from the
- // address to make sure we get an address that is not the end of
- // a section.
- if (state.end_sequence && state.address != 0)
- info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
- else
- info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
-
- if (info->curr_section_sp.get())
- info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
- else
- info->curr_sect_file_base_addr = 0;
+ // If this is our first time here, we need to create a
+ // sequence container.
+ if (!info->sequence_ap.get())
+ {
+ info->sequence_ap.reset(line_table->CreateLineSequenceContainer());
+ assert(info->sequence_ap.get());
+ }
+ line_table->AppendLineEntryToSequence (info->sequence_ap.get(),
+ state.address,
+ state.line,
+ state.column,
+ state.file,
+ state.is_stmt,
+ state.basic_block,
+ state.prologue_end,
+ state.epilogue_begin,
+ state.end_sequence);
+ if (state.end_sequence)
+ {
+ // First, put the current sequence into the line table.
+ line_table->InsertSequence(info->sequence_ap.get());
+ // Then, empty it to prepare for the next sequence.
+ info->sequence_ap->Clear();
}
- if (info->curr_section_sp.get())
- {
- lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
- // Check for the fancy section magic to determine if we
-
- if (info->is_oso_for_debug_map)
- {
- // When this is a debug map object file that contains DWARF
- // (referenced from an N_OSO debug map nlist entry) we will have
- // a file address in the file range for our section from the
- // original .o file, and a load address in the executable that
- // contains the debug map.
- //
- // If the sections for the file range and load range are
- // different, we have a remapped section for the function and
- // this address is resolved. If they are the same, then the
- // function for this address didn't make it into the final
- // executable.
- bool curr_in_final_executable = (bool) info->curr_section_sp->GetLinkedSection ();
-
- // If we are doing DWARF with debug map, then we need to carefully
- // add each line table entry as there may be gaps as functions
- // get moved around or removed.
- if (!info->prev_row.end_sequence && info->prev_section_sp.get())
- {
- if (info->prev_in_final_executable)
- {
- bool terminate_previous_entry = false;
- if (!curr_in_final_executable)
- {
- // Check for the case where the previous line entry
- // in a function made it into the final executable,
- // yet the current line entry falls in a function
- // that didn't. The line table used to be contiguous
- // through this address range but now it isn't. We
- // need to terminate the previous line entry so
- // that we can reconstruct the line range correctly
- // for it and to keep the line table correct.
- terminate_previous_entry = true;
- }
- else if (info->curr_section_sp.get() != info->prev_section_sp.get())
- {
- // Check for cases where the line entries used to be
- // contiguous address ranges, but now they aren't.
- // This can happen when order files specify the
- // ordering of the functions.
- lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
- Section *curr_sect = info->curr_section_sp.get();
- Section *prev_sect = info->prev_section_sp.get();
- assert (curr_sect->GetLinkedSection());
- assert (prev_sect->GetLinkedSection());
- lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
- lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
- lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
- lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
- if (object_file_addr_delta != linked_file_addr_delta)
- terminate_previous_entry = true;
- }
-
- if (terminate_previous_entry)
- {
- line_table->InsertLineEntry (info->prev_section_sp,
- state.address - info->prev_sect_file_base_addr,
- info->prev_row.line,
- info->prev_row.column,
- info->prev_row.file,
- false, // is_stmt
- false, // basic_block
- false, // state.prologue_end
- false, // state.epilogue_begin
- true); // end_sequence);
- }
- }
- }
-
- if (curr_in_final_executable)
- {
- line_table->InsertLineEntry (info->curr_section_sp,
- curr_line_section_offset,
- state.line,
- state.column,
- state.file,
- state.is_stmt,
- state.basic_block,
- state.prologue_end,
- state.epilogue_begin,
- state.end_sequence);
- info->prev_section_sp = info->curr_section_sp;
- }
- else
- {
- // If the current address didn't make it into the final
- // executable, the current section will be the __text
- // segment in the .o file, so we need to clear this so
- // we can catch the next function that did make it into
- // the final executable.
- info->prev_section_sp.reset();
- info->curr_section_sp.reset();
- }
-
- info->prev_in_final_executable = curr_in_final_executable;
- }
- else
- {
- // We are not in an object file that contains DWARF for an
- // N_OSO, this is just a normal DWARF file. The DWARF spec
- // guarantees that the addresses will be in increasing order
- // so, since we store line tables in file address order, we
- // can always just append the line entry without needing to
- // search for the correct insertion point (we don't need to
- // use LineEntry::InsertLineEntry()).
- line_table->AppendLineEntry (info->curr_section_sp,
- curr_line_section_offset,
- state.line,
- state.column,
- state.file,
- state.is_stmt,
- state.basic_block,
- state.prologue_end,
- state.epilogue_begin,
- state.end_sequence);
- }
- }
-
- info->prev_row = state;
}
}
@@ -1129,7 +1052,7 @@ SymbolFileDWARF::ParseCompileUnitLineTab
if (sc.comp_unit->GetLineTable() != NULL)
return true;
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
+ DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (dwarf_cu)
{
const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
@@ -1138,24 +1061,26 @@ SymbolFileDWARF::ParseCompileUnitLineTab
const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
if (cu_line_offset != DW_INVALID_OFFSET)
{
- std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
+ std::unique_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
if (line_table_ap.get())
{
- ParseDWARFLineTableCallbackInfo info = {
- line_table_ap.get(),
- m_obj_file->GetSectionList(),
- 0,
- 0,
- m_debug_map_symfile != NULL,
- false,
- DWARFDebugLine::Row(),
- SectionSP(),
- SectionSP()
- };
- uint32_t offset = cu_line_offset;
+ ParseDWARFLineTableCallbackInfo info;
+ info.line_table = line_table_ap.get();
+ lldb::offset_t offset = cu_line_offset;
DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
- sc.comp_unit->SetLineTable(line_table_ap.release());
- return true;
+ if (m_debug_map_symfile)
+ {
+ // We have an object file that has a line table with addresses
+ // that are not linked. We need to link the line table and convert
+ // the addresses that are relative to the .o file into addresses
+ // for the main executable.
+ sc.comp_unit->SetLineTable (m_debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get()));
+ }
+ else
+ {
+ sc.comp_unit->SetLineTable(line_table_ap.release());
+ return true;
+ }
}
}
}
@@ -1246,12 +1171,12 @@ SymbolFileDWARF::ParseFunctionBlocks
if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
{
- std::auto_ptr<Declaration> decl_ap;
+ std::unique_ptr<Declaration> decl_ap;
if (decl_file != 0 || decl_line != 0 || decl_column != 0)
decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
decl_line, decl_column));
- std::auto_ptr<Declaration> call_ap;
+ std::unique_ptr<Declaration> call_ap;
if (call_file != 0 || call_line != 0 || call_column != 0)
call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
call_line, call_column));
@@ -1349,15 +1274,28 @@ SymbolFileDWARF::ParseTemplateDIE (DWARF
}
}
- if (name && lldb_type && clang_type)
+ clang::ASTContext *ast = GetClangASTContext().getASTContext();
+ if (!clang_type)
+ clang_type = ast->VoidTy.getAsOpaquePtr();
+
+ if (clang_type)
{
bool is_signed = false;
- template_param_infos.names.push_back(name);
+ if (name && name[0])
+ template_param_infos.names.push_back(name);
+ else
+ template_param_infos.names.push_back(NULL);
+
clang::QualType clang_qual_type (clang::QualType::getFromOpaquePtr (clang_type));
- if (tag == DW_TAG_template_value_parameter && ClangASTContext::IsIntegerType (clang_type, is_signed) && uval64_valid)
+ if (tag == DW_TAG_template_value_parameter &&
+ lldb_type != NULL &&
+ ClangASTContext::IsIntegerType (clang_type, is_signed) &&
+ uval64_valid)
{
llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed);
- template_param_infos.args.push_back (clang::TemplateArgument (llvm::APSInt(apint), clang_qual_type));
+ template_param_infos.args.push_back (clang::TemplateArgument (*ast,
+ llvm::APSInt(apint),
+ clang_qual_type));
}
else
{
@@ -1446,7 +1384,7 @@ public:
const char *property_setter_name,
const char *property_getter_name,
uint32_t property_attributes,
- uint64_t metadata = 0
+ const ClangASTMetadata *metadata
) :
m_ast (ast),
m_class_opaque_type (class_opaque_type),
@@ -1455,22 +1393,50 @@ public:
m_ivar_decl (ivar_decl),
m_property_setter_name (property_setter_name),
m_property_getter_name (property_getter_name),
- m_property_attributes (property_attributes),
- m_metadata (metadata)
+ m_property_attributes (property_attributes)
{
+ if (metadata != NULL)
+ {
+ m_metadata_ap.reset(new ClangASTMetadata());
+ *m_metadata_ap = *metadata;
+ }
+ }
+
+ DelayedAddObjCClassProperty (const DelayedAddObjCClassProperty &rhs)
+ {
+ *this = rhs;
+ }
+
+ DelayedAddObjCClassProperty& operator= (const DelayedAddObjCClassProperty &rhs)
+ {
+ m_ast = rhs.m_ast;
+ m_class_opaque_type = rhs.m_class_opaque_type;
+ m_property_name = rhs.m_property_name;
+ m_property_opaque_type = rhs.m_property_opaque_type;
+ m_ivar_decl = rhs.m_ivar_decl;
+ m_property_setter_name = rhs.m_property_setter_name;
+ m_property_getter_name = rhs.m_property_getter_name;
+ m_property_attributes = rhs.m_property_attributes;
+
+ if (rhs.m_metadata_ap.get())
+ {
+ m_metadata_ap.reset (new ClangASTMetadata());
+ *m_metadata_ap = *rhs.m_metadata_ap;
+ }
+ return *this;
}
bool Finalize() const
{
- return ClangASTContext::AddObjCClassProperty(m_ast,
- m_class_opaque_type,
- m_property_name,
- m_property_opaque_type,
- m_ivar_decl,
- m_property_setter_name,
- m_property_getter_name,
- m_property_attributes,
- m_metadata);
+ return ClangASTContext::AddObjCClassProperty (m_ast,
+ m_class_opaque_type,
+ m_property_name,
+ m_property_opaque_type,
+ m_ivar_decl,
+ m_property_setter_name,
+ m_property_getter_name,
+ m_property_attributes,
+ m_metadata_ap.get());
}
private:
clang::ASTContext *m_ast;
@@ -1481,9 +1447,57 @@ private:
const char *m_property_setter_name;
const char *m_property_getter_name;
uint32_t m_property_attributes;
- uint64_t m_metadata;
+ std::unique_ptr<ClangASTMetadata> m_metadata_ap;
};
+struct BitfieldInfo
+{
+ uint64_t bit_size;
+ uint64_t bit_offset;
+
+ BitfieldInfo () :
+ bit_size (LLDB_INVALID_ADDRESS),
+ bit_offset (LLDB_INVALID_ADDRESS)
+ {
+ }
+
+ bool IsValid ()
+ {
+ return (bit_size != LLDB_INVALID_ADDRESS) &&
+ (bit_offset != LLDB_INVALID_ADDRESS);
+ }
+};
+
+
+bool
+SymbolFileDWARF::ClassOrStructIsVirtual (DWARFCompileUnit* dwarf_cu,
+ const DWARFDebugInfoEntry *parent_die)
+{
+ if (parent_die)
+ {
+ for (const DWARFDebugInfoEntry *die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
+ {
+ dw_tag_t tag = die->Tag();
+ bool check_virtuality = false;
+ switch (tag)
+ {
+ case DW_TAG_inheritance:
+ case DW_TAG_subprogram:
+ check_virtuality = true;
+ break;
+ default:
+ break;
+ }
+ if (check_virtuality)
+ {
+ if (die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_virtuality, 0) != 0)
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
size_t
SymbolFileDWARF::ParseChildMembers
(
@@ -1508,6 +1522,7 @@ SymbolFileDWARF::ParseChildMembers
const DWARFDebugInfoEntry *die;
const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
uint32_t member_idx = 0;
+ BitfieldInfo last_field_info;
for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
{
@@ -1516,7 +1531,7 @@ SymbolFileDWARF::ParseChildMembers
switch (tag)
{
case DW_TAG_member:
- case DW_TAG_APPLE_Property:
+ case DW_TAG_APPLE_property:
{
DWARFDebugInfoEntry::Attributes attributes;
const size_t num_attributes = die->GetAttributes (this,
@@ -1531,7 +1546,7 @@ SymbolFileDWARF::ParseChildMembers
const char *prop_name = NULL;
const char *prop_getter_name = NULL;
const char *prop_setter_name = NULL;
- uint32_t prop_attributes = 0;
+ uint32_t prop_attributes = 0;
bool is_artificial = false;
@@ -1541,6 +1556,7 @@ SymbolFileDWARF::ParseChildMembers
size_t byte_size = 0;
size_t bit_offset = 0;
size_t bit_size = 0;
+ bool is_external = false; // On DW_TAG_members, this means the member is static
uint32_t i;
for (i=0; i<num_attributes && !is_artificial; ++i)
{
@@ -1585,11 +1601,12 @@ SymbolFileDWARF::ParseChildMembers
break;
case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
- case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
+ case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
case DW_AT_APPLE_property_name: prop_name = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_APPLE_property_getter: prop_getter_name = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_APPLE_property_setter: prop_setter_name = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_APPLE_property_attribute: prop_attributes = form_value.Unsigned(); break;
+ case DW_AT_external: is_external = form_value.Boolean(); break;
default:
case DW_AT_declaration:
@@ -1612,22 +1629,14 @@ SymbolFileDWARF::ParseChildMembers
if (prop_getter_name && prop_getter_name[0] == '-')
{
- ObjCLanguageRuntime::ParseMethodName (prop_getter_name,
- NULL,
- &fixed_getter,
- NULL,
- NULL);
- prop_getter_name = fixed_getter.GetCString();
+ ObjCLanguageRuntime::MethodName prop_getter_method(prop_getter_name, true);
+ prop_getter_name = prop_getter_method.GetSelector().GetCString();
}
if (prop_setter_name && prop_setter_name[0] == '-')
{
- ObjCLanguageRuntime::ParseMethodName (prop_setter_name,
- NULL,
- &fixed_setter,
- NULL,
- NULL);
- prop_setter_name = fixed_setter.GetCString();
+ ObjCLanguageRuntime::MethodName prop_setter_method(prop_setter_name, true);
+ prop_setter_name = prop_setter_method.GetSelector().GetCString();
}
// If the names haven't been provided, they need to be
@@ -1686,9 +1695,25 @@ SymbolFileDWARF::ParseChildMembers
is_artificial = true;
}
+ // Skip static members
+ if (is_external && member_byte_offset == UINT32_MAX)
+ {
+ Type *var_type = ResolveTypeUID(encoding_uid);
+
+ if (var_type)
+ {
+ GetClangASTContext().AddVariableToRecordType (class_clang_type,
+ name,
+ var_type->GetClangLayoutType(),
+ accessibility);
+ }
+ break;
+ }
+
if (is_artificial == false)
{
Type *member_type = ResolveTypeUID(encoding_uid);
+
clang::FieldDecl *field_decl = NULL;
if (tag == DW_TAG_member)
{
@@ -1697,64 +1722,175 @@ SymbolFileDWARF::ParseChildMembers
if (accessibility == eAccessNone)
accessibility = default_accessibility;
member_accessibilities.push_back(accessibility);
+
+ BitfieldInfo this_field_info;
+
+ this_field_info.bit_size = bit_size;
+
+ if (member_byte_offset != UINT32_MAX || bit_size != 0)
+ {
+ /////////////////////////////////////////////////////////////
+ // How to locate a field given the DWARF debug information
+ //
+ // AT_byte_size indicates the size of the word in which the
+ // bit offset must be interpreted.
+ //
+ // AT_data_member_location indicates the byte offset of the
+ // word from the base address of the structure.
+ //
+ // AT_bit_offset indicates how many bits into the word
+ // (according to the host endianness) the low-order bit of
+ // the field starts. AT_bit_offset can be negative.
+ //
+ // AT_bit_size indicates the size of the field in bits.
+ /////////////////////////////////////////////////////////////
+
+ this_field_info.bit_offset = 0;
+
+ this_field_info.bit_offset += (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
+
+ if (GetObjectFile()->GetByteOrder() == eByteOrderLittle)
+ {
+ this_field_info.bit_offset += byte_size * 8;
+ this_field_info.bit_offset -= (bit_offset + bit_size);
+ }
+ else
+ {
+ this_field_info.bit_offset += bit_offset;
+ }
+ }
- field_decl = GetClangASTContext().AddFieldToRecordType (class_clang_type,
+ // If the member to be emitted did not start on a character boundary and there is
+ // empty space between the last field and this one, then we need to emit an
+ // anonymous member filling up the space up to its start. There are three cases
+ // here:
+ //
+ // 1 If the previous member ended on a character boundary, then we can emit an
+ // anonymous member starting at the most recent character boundary.
+ //
+ // 2 If the previous member did not end on a character boundary and the distance
+ // from the end of the previous member to the current member is less than a
+ // word width, then we can emit an anonymous member starting right after the
+ // previous member and right before this member.
+ //
+ // 3 If the previous member did not end on a character boundary and the distance
+ // from the end of the previous member to the current member is greater than
+ // or equal a word width, then we act as in Case 1.
+
+ const uint64_t character_width = 8;
+ const uint64_t word_width = 32;
+
+ if (this_field_info.IsValid())
+ {
+ // Objective-C has invalid DW_AT_bit_offset values in older versions
+ // of clang, so we have to be careful and only insert unnammed bitfields
+ // if we have a new enough clang.
+ bool detect_unnamed_bitfields = true;
+
+ if (class_language == eLanguageTypeObjC || class_language == eLanguageTypeObjC_plus_plus)
+ detect_unnamed_bitfields = dwarf_cu->Supports_unnamed_objc_bitfields ();
+
+ if (detect_unnamed_bitfields)
+ {
+ BitfieldInfo anon_field_info;
+
+ if ((this_field_info.bit_offset % character_width) != 0) // not char aligned
+ {
+ uint64_t last_field_end = 0;
+
+ if (last_field_info.IsValid())
+ last_field_end = last_field_info.bit_offset + last_field_info.bit_size;
+
+ if (this_field_info.bit_offset != last_field_end)
+ {
+ if (((last_field_end % character_width) == 0) || // case 1
+ (this_field_info.bit_offset - last_field_end >= word_width)) // case 3
+ {
+ anon_field_info.bit_size = this_field_info.bit_offset % character_width;
+ anon_field_info.bit_offset = this_field_info.bit_offset - anon_field_info.bit_size;
+ }
+ else // case 2
+ {
+ anon_field_info.bit_size = this_field_info.bit_offset - last_field_end;
+ anon_field_info.bit_offset = last_field_end;
+ }
+ }
+ }
+
+ if (anon_field_info.IsValid())
+ {
+ clang::FieldDecl *unnamed_bitfield_decl = GetClangASTContext().AddFieldToRecordType (class_clang_type,
+ NULL,
+ GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width),
+ accessibility,
+ anon_field_info.bit_size);
+
+ layout_info.field_offsets.insert(std::make_pair(unnamed_bitfield_decl, anon_field_info.bit_offset));
+ }
+ }
+ }
+
+ clang_type_t member_clang_type = member_type->GetClangLayoutType();
+
+ {
+ // Older versions of clang emit array[0] and array[1] in the same way (<rdar://problem/12566646>).
+ // If the current field is at the end of the structure, then there is definitely no room for extra
+ // elements and we override the type to array[0].
+
+ clang_type_t member_array_element_type;
+ uint64_t member_array_size;
+ bool member_array_is_incomplete;
+
+ if (GetClangASTContext().IsArrayType(member_clang_type,
+ &member_array_element_type,
+ &member_array_size,
+ &member_array_is_incomplete) &&
+ !member_array_is_incomplete)
+ {
+ uint64_t parent_byte_size = parent_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, UINT64_MAX);
+
+ if (member_byte_offset >= parent_byte_size)
+ {
+ if (member_array_size != 1)
+ {
+ GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 " which extends beyond the bounds of 0x%8.8" PRIx64,
+ MakeUserID(die->GetOffset()),
+ name,
+ encoding_uid,
+ MakeUserID(parent_die->GetOffset()));
+ }
+
+ member_clang_type = GetClangASTContext().CreateArrayType(member_array_element_type, 0, false);
+ }
+ }
+ }
+
+ field_decl = GetClangASTContext().AddFieldToRecordType (class_clang_type,
name,
- member_type->GetClangLayoutType(),
+ member_clang_type,
accessibility,
bit_size);
- GetClangASTContext().SetMetadata((uintptr_t)field_decl, MakeUserID(die->GetOffset()));
+ GetClangASTContext().SetMetadataAsUserID (field_decl, MakeUserID(die->GetOffset()));
+
+ if (this_field_info.IsValid())
+ {
+ layout_info.field_offsets.insert(std::make_pair(field_decl, this_field_info.bit_offset));
+ last_field_info = this_field_info;
+ }
}
else
{
if (name)
- GetObjectFile()->GetModule()->ReportError ("0x%8.8llx: DW_TAG_member '%s' refers to type 0x%8.8llx which was unable to be parsed",
+ GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 " which was unable to be parsed",
MakeUserID(die->GetOffset()),
name,
encoding_uid);
else
- GetObjectFile()->GetModule()->ReportError ("0x%8.8llx: DW_TAG_member refers to type 0x%8.8llx which was unable to be parsed",
+ GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8" PRIx64 " which was unable to be parsed",
MakeUserID(die->GetOffset()),
encoding_uid);
}
-
- if (member_byte_offset != UINT32_MAX || bit_size != 0)
- {
- /////////////////////////////////////////////////////////////
- // How to locate a field given the DWARF debug information
- //
- // AT_byte_size indicates the size of the word in which the
- // bit offset must be interpreted.
- //
- // AT_data_member_location indicates the byte offset of the
- // word from the base address of the structure.
- //
- // AT_bit_offset indicates how many bits into the word
- // (according to the host endianness) the low-order bit of
- // the field starts. AT_bit_offset can be negative.
- //
- // AT_bit_size indicates the size of the field in bits.
- /////////////////////////////////////////////////////////////
-
- ByteOrder object_endian = GetObjectFile()->GetModule()->GetArchitecture().GetDefaultEndian();
-
- uint64_t total_bit_offset = 0;
-
- total_bit_offset += (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
-
- if (object_endian == eByteOrderLittle)
- {
- total_bit_offset += byte_size * 8;
- total_bit_offset -= (bit_offset + bit_size);
- }
- else
- {
- total_bit_offset += bit_offset;
- }
-
- layout_info.field_offsets.insert(std::make_pair(field_decl, total_bit_offset));
- }
}
if (prop_name != NULL)
@@ -1767,6 +1903,8 @@ SymbolFileDWARF::ParseChildMembers
assert (ivar_decl != NULL);
}
+ ClangASTMetadata metadata;
+ metadata.SetUserID (MakeUserID(die->GetOffset()));
delayed_properties.push_back(DelayedAddObjCClassProperty(GetClangASTContext().getASTContext(),
class_clang_type,
prop_name,
@@ -1775,10 +1913,10 @@ SymbolFileDWARF::ParseChildMembers
prop_setter_name,
prop_getter_name,
prop_attributes,
- MakeUserID(die->GetOffset())));
+ &metadata));
if (ivar_decl)
- GetClangASTContext().SetMetadata((uintptr_t)ivar_decl, MakeUserID(die->GetOffset()));
+ GetClangASTContext().SetMetadataAsUserID (ivar_decl, MakeUserID(die->GetOffset()));
}
}
}
@@ -1810,7 +1948,7 @@ SymbolFileDWARF::ParseChildMembers
AccessType accessibility = default_accessibility;
bool is_virtual = false;
bool is_base_of_class = true;
- //off_t member_offset = 0;
+ off_t member_byte_offset = 0;
uint32_t i;
for (i=0; i<num_attributes; ++i)
{
@@ -1824,37 +1962,37 @@ SymbolFileDWARF::ParseChildMembers
case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
-// case DW_AT_data_member_location:
-// if (form_value.BlockData())
-// {
-// Value initialValue(0);
-// Value memberOffset(0);
-// const DataExtractor& debug_info_data = get_debug_info_data();
-// uint32_t block_length = form_value.Unsigned();
-// uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
-// if (DWARFExpression::Evaluate (NULL,
-// NULL,
-// NULL,
-// NULL,
-// NULL,
-// debug_info_data,
-// block_offset,
-// block_length,
-// eRegisterKindDWARF,
-// &initialValue,
-// memberOffset,
-// NULL))
-// {
-// member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
-// }
-// }
-// break;
+ case DW_AT_data_member_location:
+ if (form_value.BlockData())
+ {
+ Value initialValue(0);
+ Value memberOffset(0);
+ const DataExtractor& debug_info_data = get_debug_info_data();
+ uint32_t block_length = form_value.Unsigned();
+ uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
+ if (DWARFExpression::Evaluate (NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ debug_info_data,
+ block_offset,
+ block_length,
+ eRegisterKindDWARF,
+ &initialValue,
+ memberOffset,
+ NULL))
+ {
+ member_byte_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
+ }
+ }
+ break;
case DW_AT_accessibility:
accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
break;
- case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
+ case DW_AT_virtuality: is_virtual = form_value.Boolean(); break;
default:
case DW_AT_sibling:
break;
@@ -1877,6 +2015,17 @@ SymbolFileDWARF::ParseChildMembers
accessibility,
is_virtual,
is_base_of_class));
+
+ if (is_virtual)
+ {
+ layout_info.vbase_offsets.insert(std::make_pair(ClangASTType::GetAsCXXRecordDecl(class_clang_type),
+ clang::CharUnits::fromQuantity(member_byte_offset)));
+ }
+ else
+ {
+ layout_info.base_offsets.insert(std::make_pair(ClangASTType::GetAsCXXRecordDecl(class_clang_type),
+ clang::CharUnits::fromQuantity(member_byte_offset)));
+ }
}
}
}
@@ -1935,9 +2084,9 @@ SymbolFileDWARF::ResolveTypeUID (DWARFCo
{
if (die != NULL)
{
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
if (log)
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'",
die->GetOffset(),
DW_TAG_value_to_name(die->Tag()),
@@ -1955,7 +2104,7 @@ SymbolFileDWARF::ResolveTypeUID (DWARFCo
{
// Get the type, which could be a forward declaration
if (log)
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent forward type for 0x%8.8x",
die->GetOffset(),
DW_TAG_value_to_name(die->Tag()),
@@ -1966,7 +2115,7 @@ SymbolFileDWARF::ResolveTypeUID (DWARFCo
// if (child_requires_parent_class_union_or_struct_to_be_completed(die->Tag()))
// {
// if (log)
-// GetObjectFile()->GetModule()->LogMessage (log.get(),
+// GetObjectFile()->GetModule()->LogMessage (log,
// "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent full type for 0x%8.8x since die is a function",
// die->GetOffset(),
// DW_TAG_value_to_name(die->Tag()),
@@ -2030,11 +2179,11 @@ SymbolFileDWARF::ResolveClangOpaqueTypeD
const dw_tag_t tag = die->Tag();
- LogSP log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
+ Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
if (log)
{
- GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log.get(),
- "0x%8.8llx: %s '%s' resolving forward declaration...",
+ GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log,
+ "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
MakeUserID(die->GetOffset()),
DW_TAG_value_to_name(tag),
type->GetName().AsCString());
@@ -2093,8 +2242,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeD
DWARFDIECollection member_function_dies;
DelayedPropertyList delayed_properties;
-
- ParseChildMembers (sc,
+ ParseChildMembers (sc,
dwarf_cu,
die,
clang_type,
@@ -2215,37 +2363,68 @@ SymbolFileDWARF::ResolveClangOpaqueTypeD
ast.CompleteTagDeclarationDefinition (clang_type);
- if (!layout_info.field_offsets.empty())
+ if (!layout_info.field_offsets.empty() ||
+ !layout_info.base_offsets.empty() ||
+ !layout_info.vbase_offsets.empty() )
{
if (type)
layout_info.bit_size = type->GetByteSize() * 8;
if (layout_info.bit_size == 0)
layout_info.bit_size = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, 0) * 8;
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
- const clang::RecordType *record_type = clang::dyn_cast<clang::RecordType>(qual_type.getTypePtr());
- if (record_type)
+
+ clang::CXXRecordDecl *record_decl = ClangASTType::GetAsCXXRecordDecl(clang_type);
+ if (record_decl)
{
- const clang::RecordDecl *record_decl = record_type->getDecl();
-
if (log)
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
- "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) caching layout info for record_decl = %p, bit_size = %llu, alignment = %llu, field_offsets[%u], base_offsets[0], vbase_offsets[0])",
+ GetObjectFile()->GetModule()->LogMessage (log,
+ "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) caching layout info for record_decl = %p, bit_size = %" PRIu64 ", alignment = %" PRIu64 ", field_offsets[%u], base_offsets[%u], vbase_offsets[%u])",
clang_type,
record_decl,
layout_info.bit_size,
layout_info.alignment,
- (uint32_t)layout_info.field_offsets.size());
+ (uint32_t)layout_info.field_offsets.size(),
+ (uint32_t)layout_info.base_offsets.size(),
+ (uint32_t)layout_info.vbase_offsets.size());
+ uint32_t idx;
+ {
llvm::DenseMap <const clang::FieldDecl *, uint64_t>::const_iterator pos, end = layout_info.field_offsets.end();
- for (pos = layout_info.field_offsets.begin(); pos != end; ++pos)
+ for (idx = 0, pos = layout_info.field_offsets.begin(); pos != end; ++pos, ++idx)
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
- "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) field = { bit_offset=%u, name='%s' }",
+ GetObjectFile()->GetModule()->LogMessage (log,
+ "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) field[%u] = { bit_offset=%u, name='%s' }",
clang_type,
+ idx,
(uint32_t)pos->second,
pos->first->getNameAsString().c_str());
}
+ }
+
+ {
+ llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator base_pos, base_end = layout_info.base_offsets.end();
+ for (idx = 0, base_pos = layout_info.base_offsets.begin(); base_pos != base_end; ++base_pos, ++idx)
+ {
+ GetObjectFile()->GetModule()->LogMessage (log,
+ "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) base[%u] = { byte_offset=%u, name='%s' }",
+ clang_type,
+ idx,
+ (uint32_t)base_pos->second.getQuantity(),
+ base_pos->first->getNameAsString().c_str());
+ }
+ }
+ {
+ llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator vbase_pos, vbase_end = layout_info.vbase_offsets.end();
+ for (idx = 0, vbase_pos = layout_info.vbase_offsets.begin(); vbase_pos != vbase_end; ++vbase_pos, ++idx)
+ {
+ GetObjectFile()->GetModule()->LogMessage (log,
+ "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) vbase[%u] = { byte_offset=%u, name='%s' }",
+ clang_type,
+ idx,
+ (uint32_t)vbase_pos->second.getQuantity(),
+ vbase_pos->first->getNameAsString().c_str());
+ }
+ }
}
m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
}
@@ -2259,7 +2438,9 @@ SymbolFileDWARF::ResolveClangOpaqueTypeD
if (die->HasChildren())
{
SymbolContext sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
- ParseChildEnumerators(sc, clang_type, type->GetByteSize(), dwarf_cu, die);
+ bool is_signed = false;
+ ast.IsIntegerType(clang_type, is_signed);
+ ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), dwarf_cu, die);
}
ast.CompleteTagDeclarationDefinition (clang_type);
return clang_type;
@@ -2314,7 +2495,7 @@ SymbolFileDWARF::GetCompUnitForDWARFComp
bool
SymbolFileDWARF::GetFunction (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
{
- sc.Clear();
+ sc.Clear(false);
// Check if the symbol vendor already knows about this compile unit?
sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
@@ -2335,7 +2516,7 @@ uint32_t
SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
{
Timer scoped_timer(__PRETTY_FUNCTION__,
- "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
+ "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%" PRIx64 " }, resolve_scope = 0x%8.8x)",
so_addr.GetSection().get(),
so_addr.GetOffset(),
resolve_scope);
@@ -2362,27 +2543,7 @@ SymbolFileDWARF::ResolveSymbolContext (c
{
resolved |= eSymbolContextCompUnit;
- if (resolve_scope & eSymbolContextLineEntry)
- {
- LineTable *line_table = sc.comp_unit->GetLineTable();
- if (line_table != NULL)
- {
- if (so_addr.IsLinkedAddress())
- {
- Address linked_addr (so_addr);
- linked_addr.ResolveLinkedAddress();
- if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
- {
- resolved |= eSymbolContextLineEntry;
- }
- }
- else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
- {
- resolved |= eSymbolContextLineEntry;
- }
- }
- }
-
+ bool force_check_line_table = false;
if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
{
DWARFDebugInfoEntry *function_die = NULL;
@@ -2410,8 +2571,7 @@ SymbolFileDWARF::ResolveSymbolContext (c
// should only happen when there aren't other functions from
// other compile units in these gaps. This helps keep the size
// of the aranges down.
- sc.comp_unit = NULL;
- resolved &= ~eSymbolContextCompUnit;
+ force_check_line_table = true;
}
if (sc.function != NULL)
@@ -2431,6 +2591,39 @@ SymbolFileDWARF::ResolveSymbolContext (c
}
}
}
+
+ if ((resolve_scope & eSymbolContextLineEntry) || force_check_line_table)
+ {
+ LineTable *line_table = sc.comp_unit->GetLineTable();
+ if (line_table != NULL)
+ {
+ // And address that makes it into this function should be in terms
+ // of this debug file if there is no debug map, or it will be an
+ // address in the .o file which needs to be fixed up to be in terms
+ // of the debug map executable. Either way, calling FixupAddress()
+ // will work for us.
+ Address exe_so_addr (so_addr);
+ if (FixupAddress(exe_so_addr))
+ {
+ if (line_table->FindLineEntryByAddress (exe_so_addr, sc.line_entry))
+ {
+ resolved |= eSymbolContextLineEntry;
+ }
+ }
+ }
+ }
+
+ if (force_check_line_table && !(resolved & eSymbolContextLineEntry))
+ {
+ // We might have had a compile unit that had discontiguous
+ // address ranges where the gaps are symbols that don't have
+ // any debug info. Discontiguous compile unit address ranges
+ // should only happen when there aren't other functions from
+ // other compile units in these gaps. This helps keep the size
+ // of the aranges down.
+ sc.comp_unit = NULL;
+ resolved &= ~eSymbolContextCompUnit;
+ }
}
else
{
@@ -2462,7 +2655,8 @@ SymbolFileDWARF::ResolveSymbolContext(co
for (cu_idx = 0; (dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
{
CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
- bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
+ const bool full_match = file_spec.GetDirectory();
+ bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Equal(file_spec, *dc_cu, full_match);
if (check_inlines || file_spec_matches_cu_file_spec)
{
SymbolContext sc (m_obj_file->GetModule());
@@ -2606,9 +2800,8 @@ SymbolFileDWARF::Index ()
#if defined (ENABLE_DEBUG_PRINTF)
StreamFile s(stdout, false);
- s.Printf ("DWARF index for '%s/%s':",
- GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
- GetObjectFile()->GetFileSpec().GetFilename().AsCString());
+ s.Printf ("DWARF index for '%s':",
+ GetObjectFile()->GetFileSpec().GetPath().c_str());
s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
@@ -2642,10 +2835,10 @@ SymbolFileDWARF::NamespaceDeclMatchesThi
return true; // The ASTs match, return true
// The namespace AST was valid, and it does not match...
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log)
- GetObjectFile()->GetModule()->LogMessage(log.get(), "Valid namespace does not match symbol file");
+ GetObjectFile()->GetModule()->LogMessage(log, "Valid namespace does not match symbol file");
return false;
}
@@ -2659,7 +2852,7 @@ SymbolFileDWARF::DIEIsInNamespace (const
if (namespace_decl == NULL)
return true;
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
const DWARFDebugInfoEntry *decl_ctx_die = NULL;
clang::DeclContext *die_clang_decl_ctx = GetClangDeclContextContainingDIE (cu, die, &decl_ctx_die);
@@ -2672,7 +2865,7 @@ SymbolFileDWARF::DIEIsInNamespace (const
if (decl_ctx_die->Tag() != DW_TAG_namespace)
{
if (log)
- GetObjectFile()->GetModule()->LogMessage(log.get(), "Found a match, but its parent is not a namespace");
+ GetObjectFile()->GetModule()->LogMessage(log, "Found a match, but its parent is not a namespace");
return false;
}
@@ -2693,18 +2886,18 @@ SymbolFileDWARF::DIEIsInNamespace (const
}
if (log)
- GetObjectFile()->GetModule()->LogMessage(log.get(), "Found a match, but its parent doesn't exist");
+ GetObjectFile()->GetModule()->LogMessage(log, "Found a match, but its parent doesn't exist");
return false;
}
uint32_t
SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
{
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log)
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::FindGlobalVariables (name=\"%s\", namespace_decl=%p, append=%u, max_matches=%u, variables)",
name.GetCString(),
namespace_decl,
@@ -2809,7 +3002,7 @@ SymbolFileDWARF::FindGlobalVariables (co
const uint32_t num_matches = variables.GetSize() - original_size;
if (log && num_matches > 0)
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::FindGlobalVariables (name=\"%s\", namespace_decl=%p, append=%u, max_matches=%u, variables) => %u",
name.GetCString(),
namespace_decl,
@@ -2823,11 +3016,11 @@ SymbolFileDWARF::FindGlobalVariables (co
uint32_t
SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
{
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log)
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, max_matches=%u, variables)",
regex.GetText(),
append,
@@ -3035,9 +3228,8 @@ SymbolFileDWARF::FunctionDieMatchesParti
const char *base_name_start,
const char *base_name_end)
{
- // If we are looking only for methods, throw away all the ones that aren't in C++ classes:
- if (name_type_mask == eFunctionNameTypeMethod
- || name_type_mask == eFunctionNameTypeBase)
+ // If we are looking only for methods, throw away all the ones that are or aren't in C++ classes:
+ if (name_type_mask == eFunctionNameTypeMethod || name_type_mask == eFunctionNameTypeBase)
{
clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIEOffset(die->GetOffset());
if (!containing_decl_ctx)
@@ -3045,10 +3237,17 @@ SymbolFileDWARF::FunctionDieMatchesParti
bool is_cxx_method = DeclKindIsCXXClass(containing_decl_ctx->getDeclKind());
- if (!is_cxx_method && name_type_mask == eFunctionNameTypeMethod)
- return false;
- if (is_cxx_method && name_type_mask == eFunctionNameTypeBase)
- return false;
+ if (name_type_mask == eFunctionNameTypeMethod)
+ {
+ if (is_cxx_method == false)
+ return false;
+ }
+
+ if (name_type_mask == eFunctionNameTypeBase)
+ {
+ if (is_cxx_method == true)
+ return false;
+ }
}
// Now we need to check whether the name we got back for this type matches the extra specifications
@@ -3059,20 +3258,33 @@ SymbolFileDWARF::FunctionDieMatchesParti
// we can pull out the mips linkage name attribute:
Mangled best_name;
-
DWARFDebugInfoEntry::Attributes attributes;
+ DWARFFormValue form_value;
die->GetAttributes(this, dwarf_cu, NULL, attributes);
uint32_t idx = attributes.FindAttributeIndex(DW_AT_MIPS_linkage_name);
+ if (idx == UINT32_MAX)
+ idx = attributes.FindAttributeIndex(DW_AT_linkage_name);
if (idx != UINT32_MAX)
{
- DWARFFormValue form_value;
if (attributes.ExtractFormValueAtIndex(this, idx, form_value))
{
+ const char *mangled_name = form_value.AsCString(&get_debug_str_data());
+ if (mangled_name)
+ best_name.SetValue (ConstString(mangled_name), true);
+ }
+ }
+
+ if (!best_name)
+ {
+ idx = attributes.FindAttributeIndex(DW_AT_name);
+ if (idx != UINT32_MAX && attributes.ExtractFormValueAtIndex(this, idx, form_value))
+ {
const char *name = form_value.AsCString(&get_debug_str_data());
- best_name.SetValue (ConstString(name), true);
- }
+ best_name.SetValue (ConstString(name), false);
+ }
}
- if (best_name)
+
+ if (best_name.GetDemangledName())
{
const char *demangled = best_name.GetDemangledName().GetCString();
if (demangled)
@@ -3132,11 +3344,14 @@ SymbolFileDWARF::FindFunctions (const Co
"SymbolFileDWARF::FindFunctions (name = '%s')",
name.AsCString());
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+ // eFunctionNameTypeAuto should be pre-resolved by a call to Module::PrepareForFunctionNameLookup()
+ assert ((name_type_mask & eFunctionNameTypeAuto) == 0);
+
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log)
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)",
name.GetCString(),
name_type_mask,
@@ -3157,59 +3372,16 @@ SymbolFileDWARF::FindFunctions (const Co
// Remember how many sc_list are in the list before we search in case
// we are appending the results to a variable list.
- const uint32_t original_size = sc_list.GetSize();
-
const char *name_cstr = name.GetCString();
- uint32_t effective_name_type_mask = eFunctionNameTypeNone;
- const char *base_name_start = name_cstr;
- const char *base_name_end = name_cstr + strlen(name_cstr);
-
- if (name_type_mask & eFunctionNameTypeAuto)
- {
- if (CPPLanguageRuntime::IsCPPMangledName (name_cstr))
- effective_name_type_mask = eFunctionNameTypeFull;
- else if (ObjCLanguageRuntime::IsPossibleObjCMethodName (name_cstr))
- effective_name_type_mask = eFunctionNameTypeFull;
- else
- {
- if (ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr))
- effective_name_type_mask |= eFunctionNameTypeSelector;
-
- if (CPPLanguageRuntime::IsPossibleCPPCall(name_cstr, base_name_start, base_name_end))
- effective_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
- }
- }
- else
- {
- effective_name_type_mask = name_type_mask;
- if (effective_name_type_mask & eFunctionNameTypeMethod || name_type_mask & eFunctionNameTypeBase)
- {
- // If they've asked for a CPP method or function name and it can't be that, we don't
- // even need to search for CPP methods or names.
- if (!CPPLanguageRuntime::IsPossibleCPPCall(name_cstr, base_name_start, base_name_end))
- {
- effective_name_type_mask &= ~(eFunctionNameTypeMethod | eFunctionNameTypeBase);
- if (effective_name_type_mask == eFunctionNameTypeNone)
- return 0;
- }
- }
-
- if (effective_name_type_mask & eFunctionNameTypeSelector)
- {
- if (!ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr))
- {
- effective_name_type_mask &= ~(eFunctionNameTypeSelector);
- if (effective_name_type_mask == eFunctionNameTypeNone)
- return 0;
- }
- }
- }
-
+
+ const uint32_t original_size = sc_list.GetSize();
+
DWARFDebugInfo* info = DebugInfo();
if (info == NULL)
return 0;
DWARFCompileUnit *dwarf_cu = NULL;
+ std::set<const DWARFDebugInfoEntry *> resolved_dies;
if (m_using_apple_tables)
{
if (m_apple_names_ap.get())
@@ -3219,7 +3391,7 @@ SymbolFileDWARF::FindFunctions (const Co
uint32_t num_matches = 0;
- if (effective_name_type_mask & eFunctionNameTypeFull)
+ if (name_type_mask & eFunctionNameTypeFull)
{
// If they asked for the full name, match what they typed. At some point we may
// want to canonicalize this (strip double spaces, etc. For now, we just add all the
@@ -3237,7 +3409,11 @@ SymbolFileDWARF::FindFunctions (const Co
if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine)
continue;
- ResolveFunction (dwarf_cu, die, sc_list);
+ if (resolved_dies.find(die) == resolved_dies.end())
+ {
+ if (ResolveFunction (dwarf_cu, die, sc_list))
+ resolved_dies.insert(die);
+ }
}
else
{
@@ -3246,87 +3422,116 @@ SymbolFileDWARF::FindFunctions (const Co
}
}
}
- else
- {
- if (effective_name_type_mask & eFunctionNameTypeSelector)
- {
- if (namespace_decl && *namespace_decl)
- return 0; // no selectors in namespaces
-
- num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
- // Now make sure these are actually ObjC methods. In this case we can simply look up the name,
- // and if it is an ObjC method name, we're good.
+
+ if (name_type_mask & eFunctionNameTypeSelector)
+ {
+ if (namespace_decl && *namespace_decl)
+ return 0; // no selectors in namespaces
- for (uint32_t i = 0; i < num_matches; i++)
+ num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
+ // Now make sure these are actually ObjC methods. In this case we can simply look up the name,
+ // and if it is an ObjC method name, we're good.
+
+ for (uint32_t i = 0; i < num_matches; i++)
+ {
+ const dw_offset_t die_offset = die_offsets[i];
+ const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
+ if (die)
{
- const dw_offset_t die_offset = die_offsets[i];
- const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
- if (die)
+ const char *die_name = die->GetName(this, dwarf_cu);
+ if (ObjCLanguageRuntime::IsPossibleObjCMethodName(die_name))
{
- const char *die_name = die->GetName(this, dwarf_cu);
- if (ObjCLanguageRuntime::IsPossibleObjCMethodName(die_name))
+ if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine)
+ continue;
+
+ if (resolved_dies.find(die) == resolved_dies.end())
{
- if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine)
- continue;
-
- ResolveFunction (dwarf_cu, die, sc_list);
+ if (ResolveFunction (dwarf_cu, die, sc_list))
+ resolved_dies.insert(die);
}
}
- else
- {
- GetObjectFile()->GetModule()->ReportError ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
- die_offset, name_cstr);
- }
}
- die_offsets.clear();
+ else
+ {
+ GetObjectFile()->GetModule()->ReportError ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
+ die_offset, name_cstr);
+ }
}
+ die_offsets.clear();
+ }
+
+ if (((name_type_mask & eFunctionNameTypeMethod) && !namespace_decl) || name_type_mask & eFunctionNameTypeBase)
+ {
+ // The apple_names table stores just the "base name" of C++ methods in the table. So we have to
+ // extract the base name, look that up, and if there is any other information in the name we were
+ // passed in we have to post-filter based on that.
- if (effective_name_type_mask & eFunctionNameTypeMethod
- || effective_name_type_mask & eFunctionNameTypeBase)
+ // FIXME: Arrange the logic above so that we don't calculate the base name twice:
+ num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
+
+ for (uint32_t i = 0; i < num_matches; i++)
{
- if ((effective_name_type_mask & eFunctionNameTypeMethod) &&
- (namespace_decl && *namespace_decl))
- return 0; // no methods in namespaces
-
- // The apple_names table stores just the "base name" of C++ methods in the table. So we have to
- // extract the base name, look that up, and if there is any other information in the name we were
- // passed in we have to post-filter based on that.
-
- // FIXME: Arrange the logic above so that we don't calculate the base name twice:
- std::string base_name(base_name_start, base_name_end - base_name_start);
- num_matches = m_apple_names_ap->FindByName (base_name.c_str(), die_offsets);
-
- for (uint32_t i = 0; i < num_matches; i++)
+ const dw_offset_t die_offset = die_offsets[i];
+ const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
+ if (die)
{
- const dw_offset_t die_offset = die_offsets[i];
- const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
- if (die)
+ if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine)
+ continue;
+
+ if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
+ continue;
+
+ // If we get to here, the die is good, and we should add it:
+ if (resolved_dies.find(die) == resolved_dies.end())
+ if (ResolveFunction (dwarf_cu, die, sc_list))
{
- if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
- continue;
-
- if (!FunctionDieMatchesPartialName(die,
- dwarf_cu,
- effective_name_type_mask,
- name_cstr,
- base_name_start,
- base_name_end))
- continue;
-
- if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine)
- continue;
-
- // If we get to here, the die is good, and we should add it:
- ResolveFunction (dwarf_cu, die, sc_list);
+ bool keep_die = true;
+ if ((name_type_mask & (eFunctionNameTypeBase|eFunctionNameTypeMethod)) != (eFunctionNameTypeBase|eFunctionNameTypeMethod))
+ {
+ // We are looking for either basenames or methods, so we need to
+ // trim out the ones we won't want by looking at the type
+ SymbolContext sc;
+ if (sc_list.GetLastContext(sc))
+ {
+ if (sc.block)
+ {
+ // We have an inlined function
+ }
+ else if (sc.function)
+ {
+ Type *type = sc.function->GetType();
+
+ clang::DeclContext* decl_ctx = GetClangDeclContextContainingTypeUID (type->GetID());
+ if (decl_ctx->isRecord())
+ {
+ if (name_type_mask & eFunctionNameTypeBase)
+ {
+ sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
+ keep_die = false;
+ }
+ }
+ else
+ {
+ if (name_type_mask & eFunctionNameTypeMethod)
+ {
+ sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
+ keep_die = false;
+ }
+ }
+ }
+ }
+ }
+ if (keep_die)
+ resolved_dies.insert(die);
}
- else
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
- die_offset, name_cstr);
- }
}
- die_offsets.clear();
+ else
+ {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
+ die_offset, name_cstr);
+ }
}
+ die_offsets.clear();
}
}
}
@@ -3338,74 +3543,95 @@ SymbolFileDWARF::FindFunctions (const Co
Index ();
if (name_type_mask & eFunctionNameTypeFull)
+ {
FindFunctions (name, m_function_fullname_index, sc_list);
- std::string base_name(base_name_start, base_name_end - base_name_start);
- ConstString base_name_const(base_name.c_str());
+ // Temporary workaround for global/anonymous namespace functions on linux
+#if defined (__linux__)
+ // If we didn't find any functions in the global namespace try
+ // looking in the basename index but ignore any returned
+ // functions that have a namespace (ie. mangled names starting with
+ // '_ZN') but keep functions which have an anonymous namespace
+ if (sc_list.GetSize() == 0)
+ {
+ SymbolContextList temp_sc_list;
+ FindFunctions (name, m_function_basename_index, temp_sc_list);
+ if (!namespace_decl)
+ {
+ SymbolContext sc;
+ for (uint32_t i = 0; i < temp_sc_list.GetSize(); i++)
+ {
+ if (temp_sc_list.GetContextAtIndex(i, sc))
+ {
+ ConstString mangled_name = sc.GetFunctionName(Mangled::ePreferMangled);
+ ConstString demangled_name = sc.GetFunctionName(Mangled::ePreferDemangled);
+ if (strncmp(mangled_name.GetCString(), "_ZN", 3) ||
+ !strncmp(demangled_name.GetCString(), "(anonymous namespace)", 21))
+ {
+ sc_list.Append(sc);
+ }
+ }
+ }
+ }
+ }
+#endif
+ }
DIEArray die_offsets;
DWARFCompileUnit *dwarf_cu = NULL;
- if (effective_name_type_mask & eFunctionNameTypeBase)
+ if (name_type_mask & eFunctionNameTypeBase)
{
- uint32_t num_base = m_function_basename_index.Find(base_name_const, die_offsets);
+ uint32_t num_base = m_function_basename_index.Find(name, die_offsets);
for (uint32_t i = 0; i < num_base; i++)
{
const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
if (die)
{
- if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
- continue;
-
- if (!FunctionDieMatchesPartialName(die,
- dwarf_cu,
- effective_name_type_mask,
- name_cstr,
- base_name_start,
- base_name_end))
+ if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine)
continue;
- if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine)
+ if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
continue;
// If we get to here, the die is good, and we should add it:
- ResolveFunction (dwarf_cu, die, sc_list);
+ if (resolved_dies.find(die) == resolved_dies.end())
+ {
+ if (ResolveFunction (dwarf_cu, die, sc_list))
+ resolved_dies.insert(die);
+ }
}
}
die_offsets.clear();
}
- if (effective_name_type_mask & eFunctionNameTypeMethod)
+ if (name_type_mask & eFunctionNameTypeMethod)
{
if (namespace_decl && *namespace_decl)
return 0; // no methods in namespaces
- uint32_t num_base = m_function_method_index.Find(base_name_const, die_offsets);
+ uint32_t num_base = m_function_method_index.Find(name, die_offsets);
{
for (uint32_t i = 0; i < num_base; i++)
{
const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
if (die)
{
- if (!FunctionDieMatchesPartialName(die,
- dwarf_cu,
- effective_name_type_mask,
- name_cstr,
- base_name_start,
- base_name_end))
- continue;
-
if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine)
continue;
// If we get to here, the die is good, and we should add it:
- ResolveFunction (dwarf_cu, die, sc_list);
+ if (resolved_dies.find(die) == resolved_dies.end())
+ {
+ if (ResolveFunction (dwarf_cu, die, sc_list))
+ resolved_dies.insert(die);
+ }
}
}
}
die_offsets.clear();
}
- if ((effective_name_type_mask & eFunctionNameTypeSelector) && (!namespace_decl || !*namespace_decl))
+ if ((name_type_mask & eFunctionNameTypeSelector) && (!namespace_decl || !*namespace_decl))
{
FindFunctions (name, m_function_selector_index, sc_list);
}
@@ -3417,7 +3643,7 @@ SymbolFileDWARF::FindFunctions (const Co
if (log && num_matches > 0)
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, append=%u, sc_list) => %u",
name.GetCString(),
name_type_mask,
@@ -3434,11 +3660,11 @@ SymbolFileDWARF::FindFunctions(const Reg
"SymbolFileDWARF::FindFunctions (regex = '%s')",
regex.GetText());
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log)
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)",
regex.GetText(),
append);
@@ -3485,13 +3711,13 @@ SymbolFileDWARF::FindTypes (const Symbol
if (info == NULL)
return 0;
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log)
{
if (namespace_decl)
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(%p) \"%s\", append=%u, max_matches=%u, type_list)",
name.GetCString(),
namespace_decl->GetNamespaceDecl(),
@@ -3501,7 +3727,7 @@ SymbolFileDWARF::FindTypes (const Symbol
}
else
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(NULL), append=%u, max_matches=%u, type_list)",
name.GetCString(),
append,
@@ -3576,7 +3802,7 @@ SymbolFileDWARF::FindTypes (const Symbol
{
if (namespace_decl)
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(%p) \"%s\", append=%u, max_matches=%u, type_list) => %u",
name.GetCString(),
namespace_decl->GetNamespaceDecl(),
@@ -3587,7 +3813,7 @@ SymbolFileDWARF::FindTypes (const Symbol
}
else
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(NULL), append=%u, max_matches=%u, type_list) => %u",
name.GetCString(),
append,
@@ -3606,11 +3832,11 @@ SymbolFileDWARF::FindNamespace (const Sy
const ConstString &name,
const lldb_private::ClangNamespaceDecl *parent_namespace_decl)
{
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log)
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::FindNamespace (sc, name=\"%s\")",
name.GetCString());
}
@@ -3680,7 +3906,7 @@ SymbolFileDWARF::FindNamespace (const Sy
}
if (log && namespace_decl.GetNamespaceDecl())
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => clang::NamespaceDecl(%p) \"%s\"",
name.GetCString(),
namespace_decl.GetNamespaceDecl(),
@@ -3771,7 +3997,7 @@ SymbolFileDWARF::ParseChildParameters (c
case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
- case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
+ case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
case DW_AT_location:
// if (form_value.BlockData())
// {
@@ -3869,7 +4095,7 @@ SymbolFileDWARF::ParseChildParameters (c
assert(param_var_decl);
function_param_decls.push_back(param_var_decl);
- GetClangASTContext().SetMetadata((uintptr_t)param_var_decl, MakeUserID(die->GetOffset()));
+ GetClangASTContext().SetMetadataAsUserID (param_var_decl, MakeUserID(die->GetOffset()));
}
}
}
@@ -3893,7 +4119,8 @@ size_t
SymbolFileDWARF::ParseChildEnumerators
(
const SymbolContext& sc,
- clang_type_t enumerator_clang_type,
+ clang_type_t enumerator_clang_type,
+ bool is_signed,
uint32_t enumerator_byte_size,
DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *parent_die
@@ -3931,7 +4158,10 @@ SymbolFileDWARF::ParseChildEnumerators
{
case DW_AT_const_value:
got_value = true;
- enum_value = form_value.Unsigned();
+ if (is_signed)
+ enum_value = form_value.Signed();
+ else
+ enum_value = form_value.Unsigned();
break;
case DW_AT_name:
@@ -3996,6 +4226,7 @@ SymbolFileDWARF::ParseChildArrayInfo
uint64_t num_elements = 0;
uint64_t lower_bound = 0;
uint64_t upper_bound = 0;
+ bool upper_bound_valid = false;
uint32_t i;
for (i=0; i<num_child_attributes; ++i)
{
@@ -4025,6 +4256,7 @@ SymbolFileDWARF::ParseChildArrayInfo
break;
case DW_AT_upper_bound:
+ upper_bound_valid = true;
upper_bound = form_value.Unsigned();
break;
@@ -4045,11 +4277,13 @@ SymbolFileDWARF::ParseChildArrayInfo
}
}
- if (upper_bound > lower_bound)
- num_elements = upper_bound - lower_bound + 1;
+ if (num_elements == 0)
+ {
+ if (upper_bound_valid && upper_bound >= lower_bound)
+ num_elements = upper_bound - lower_bound + 1;
+ }
- if (num_elements > 0)
- element_orders.push_back (num_elements);
+ element_orders.push_back (num_elements);
}
}
break;
@@ -4126,13 +4360,13 @@ SymbolFileDWARF::ResolveNamespaceDIE (DW
const char *namespace_name = die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_name, NULL);
clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, NULL);
namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, containing_decl_ctx);
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
if (log)
{
if (namespace_name)
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
- "ASTContext => %p: 0x%8.8llx: DW_TAG_namespace with DW_AT_name(\"%s\") => clang::NamespaceDecl *%p (original = %p)",
+ GetObjectFile()->GetModule()->LogMessage (log,
+ "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace with DW_AT_name(\"%s\") => clang::NamespaceDecl *%p (original = %p)",
GetClangASTContext().getASTContext(),
MakeUserID(die->GetOffset()),
namespace_name,
@@ -4141,8 +4375,8 @@ SymbolFileDWARF::ResolveNamespaceDIE (DW
}
else
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
- "ASTContext => %p: 0x%8.8llx: DW_TAG_namespace (anonymous) => clang::NamespaceDecl *%p (original = %p)",
+ GetObjectFile()->GetModule()->LogMessage (log,
+ "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace (anonymous) => clang::NamespaceDecl *%p (original = %p)",
GetClangASTContext().getASTContext(),
MakeUserID(die->GetOffset()),
namespace_decl,
@@ -4174,9 +4408,9 @@ SymbolFileDWARF::GetClangDeclContextForD
if (die_offset != DW_INVALID_OFFSET)
return GetClangDeclContextForDIEOffset (sc, die_offset);
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
if (log)
- GetObjectFile()->GetModule()->LogMessage(log.get(), "SymbolFileDWARF::GetClangDeclContextForDIE (die = 0x%8.8x) %s '%s'", die->GetOffset(), DW_TAG_value_to_name(die->Tag()), die->GetName(this, cu));
+ GetObjectFile()->GetModule()->LogMessage(log, "SymbolFileDWARF::GetClangDeclContextForDIE (die = 0x%8.8x) %s '%s'", die->GetOffset(), DW_TAG_value_to_name(die->Tag()), die->GetName(this, cu));
// This is the DIE we want. Parse it, then query our map.
bool assert_not_being_parsed = true;
ResolveTypeUID (cu, die, assert_not_being_parsed);
@@ -4339,7 +4573,7 @@ SymbolFileDWARF::Supports_DW_AT_APPLE_ob
}
}
}
- if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo && m_debug_map_symfile)
+ if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo && GetDebugMapSymfile ())
return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type (this);
}
return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
@@ -4416,7 +4650,7 @@ SymbolFileDWARF::FindCompleteObjCDefinit
Type *resolved_type = ResolveType (type_cu, type_die, false);
if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
{
- DEBUG_PRINTF ("resolved 0x%8.8llx (cu 0x%8.8llx) from %s to 0x%8.8llx (cu 0x%8.8llx)\n",
+ DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ") from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n",
MakeUserID(die->GetOffset()),
MakeUserID(dwarf_cu->GetOffset()),
m_obj_file->GetFileSpec().GetFilename().AsCString(),
@@ -4569,12 +4803,13 @@ SymbolFileDWARF::FindDefinitionTypeForDI
if (cu == NULL || die == NULL || !type_name)
return type_sp;
- LogSP log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS));
+ std::string qualified_name;
+
+ Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS));
if (log)
{
- std::string qualified_name;
die->GetQualifiedName(this, cu, qualified_name);
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::FindDefinitionTypeForDIE(die=0x%8.8x (%s), name='%s')",
die->GetOffset(),
qualified_name.c_str(),
@@ -4587,8 +4822,22 @@ SymbolFileDWARF::FindDefinitionTypeForDI
{
if (m_apple_types_ap.get())
{
- if (m_apple_types_ap->GetHeader().header_data.atoms.size() > 1)
+ const bool has_tag = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeTag);
+ const bool has_qualified_name_hash = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeQualNameHash);
+ if (has_tag && has_qualified_name_hash)
+ {
+ if (qualified_name.empty())
+ die->GetQualifiedName(this, cu, qualified_name);
+
+ const uint32_t qualified_name_hash = MappedHash::HashStringUsingDJB (qualified_name.c_str());
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTagAndQualifiedNameHash()");
+ m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash (type_name.GetCString(), die->Tag(), qualified_name_hash, die_offsets);
+ }
+ else if (has_tag > 1)
{
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTag()");
m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), die->Tag(), die_offsets);
}
else
@@ -4663,7 +4912,7 @@ SymbolFileDWARF::FindDefinitionTypeForDI
{
std::string qualified_name;
type_die->GetQualifiedName(this, cu, qualified_name);
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::FindDefinitionTypeForDIE(die=0x%8.8x, name='%s') trying die=0x%8.8x (%s)",
die->GetOffset(),
type_name.GetCString(),
@@ -4677,7 +4926,7 @@ SymbolFileDWARF::FindDefinitionTypeForDI
Type *resolved_type = ResolveType (type_cu, type_die, false);
if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
{
- DEBUG_PRINTF ("resolved 0x%8.8llx (cu 0x%8.8llx) from %s to 0x%8.8llx (cu 0x%8.8llx)\n",
+ DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ") from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n",
MakeUserID(die->GetOffset()),
MakeUserID(dwarf_cu->GetOffset()),
m_obj_file->GetFileSpec().GetFilename().AsCString(),
@@ -4696,7 +4945,7 @@ SymbolFileDWARF::FindDefinitionTypeForDI
{
std::string qualified_name;
type_die->GetQualifiedName(this, cu, qualified_name);
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::FindDefinitionTypeForDIE(die=0x%8.8x, name='%s') ignoring die=0x%8.8x (%s)",
die->GetOffset(),
type_name.GetCString(),
@@ -4732,10 +4981,10 @@ SymbolFileDWARF::FindDefinitionTypeForDW
if (type_name)
{
- LogSP log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS));
+ Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS));
if (log)
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s')",
DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
dwarf_decl_ctx.GetQualifiedName());
@@ -4747,8 +4996,20 @@ SymbolFileDWARF::FindDefinitionTypeForDW
{
if (m_apple_types_ap.get())
{
- if (m_apple_types_ap->GetHeader().header_data.atoms.size() > 1)
+ const bool has_tag = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeTag);
+ const bool has_qualified_name_hash = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeQualNameHash);
+ if (has_tag && has_qualified_name_hash)
+ {
+ const char *qualified_name = dwarf_decl_ctx.GetQualifiedName();
+ const uint32_t qualified_name_hash = MappedHash::HashStringUsingDJB (qualified_name);
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTagAndQualifiedNameHash()");
+ m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash (type_name.GetCString(), tag, qualified_name_hash, die_offsets);
+ }
+ else if (has_tag)
{
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTag()");
m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), tag, die_offsets);
}
else
@@ -4820,7 +5081,7 @@ SymbolFileDWARF::FindDefinitionTypeForDW
if (log)
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') trying die=0x%8.8x (%s)",
DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
dwarf_decl_ctx.GetQualifiedName(),
@@ -4845,7 +5106,7 @@ SymbolFileDWARF::FindDefinitionTypeForDW
{
std::string qualified_name;
type_die->GetQualifiedName(this, type_cu, qualified_name);
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') ignoring die=0x%8.8x (%s)",
DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
dwarf_decl_ctx.GetQualifiedName(),
@@ -4871,11 +5132,13 @@ SymbolFileDWARF::FindDefinitionTypeForDW
}
bool
-SymbolFileDWARF::CopyUniqueClassMethodTypes (Type *class_type,
+SymbolFileDWARF::CopyUniqueClassMethodTypes (SymbolFileDWARF *src_symfile,
+ Type *class_type,
DWARFCompileUnit* src_cu,
const DWARFDebugInfoEntry *src_class_die,
DWARFCompileUnit* dst_cu,
- const DWARFDebugInfoEntry *dst_class_die)
+ const DWARFDebugInfoEntry *dst_class_die,
+ llvm::SmallVectorImpl <const DWARFDebugInfoEntry *> &failures)
{
if (!class_type || !src_cu || !src_class_die || !dst_cu || !dst_class_die)
return false;
@@ -4891,43 +5154,78 @@ SymbolFileDWARF::CopyUniqueClassMethodTy
const DWARFDebugInfoEntry *dst_die;
UniqueCStringMap<const DWARFDebugInfoEntry *> src_name_to_die;
UniqueCStringMap<const DWARFDebugInfoEntry *> dst_name_to_die;
+ UniqueCStringMap<const DWARFDebugInfoEntry *> src_name_to_die_artificial;
+ UniqueCStringMap<const DWARFDebugInfoEntry *> dst_name_to_die_artificial;
for (src_die = src_class_die->GetFirstChild(); src_die != NULL; src_die = src_die->GetSibling())
{
if (src_die->Tag() == DW_TAG_subprogram)
{
- const char *src_name = src_die->GetMangledName (this, src_cu);
- if (src_name)
- src_name_to_die.Append(ConstString(src_name).GetCString(), src_die);
+ // Make sure this is a declaration and not a concrete instance by looking
+ // for DW_AT_declaration set to 1. Sometimes concrete function instances
+ // are placed inside the class definitions and shouldn't be included in
+ // the list of things are are tracking here.
+ if (src_die->GetAttributeValueAsUnsigned(src_symfile, src_cu, DW_AT_declaration, 0) == 1)
+ {
+ const char *src_name = src_die->GetMangledName (src_symfile, src_cu);
+ if (src_name)
+ {
+ ConstString src_const_name(src_name);
+ if (src_die->GetAttributeValueAsUnsigned(src_symfile, src_cu, DW_AT_artificial, 0))
+ src_name_to_die_artificial.Append(src_const_name.GetCString(), src_die);
+ else
+ src_name_to_die.Append(src_const_name.GetCString(), src_die);
+ }
+ }
}
}
for (dst_die = dst_class_die->GetFirstChild(); dst_die != NULL; dst_die = dst_die->GetSibling())
{
if (dst_die->Tag() == DW_TAG_subprogram)
{
- const char *dst_name = dst_die->GetMangledName (this, dst_cu);
- if (dst_name)
- dst_name_to_die.Append(ConstString(dst_name).GetCString(), dst_die);
+ // Make sure this is a declaration and not a concrete instance by looking
+ // for DW_AT_declaration set to 1. Sometimes concrete function instances
+ // are placed inside the class definitions and shouldn't be included in
+ // the list of things are are tracking here.
+ if (dst_die->GetAttributeValueAsUnsigned(this, dst_cu, DW_AT_declaration, 0) == 1)
+ {
+ const char *dst_name = dst_die->GetMangledName (this, dst_cu);
+ if (dst_name)
+ {
+ ConstString dst_const_name(dst_name);
+ if (dst_die->GetAttributeValueAsUnsigned(this, dst_cu, DW_AT_artificial, 0))
+ dst_name_to_die_artificial.Append(dst_const_name.GetCString(), dst_die);
+ else
+ dst_name_to_die.Append(dst_const_name.GetCString(), dst_die);
+ }
+ }
}
}
const uint32_t src_size = src_name_to_die.GetSize ();
const uint32_t dst_size = dst_name_to_die.GetSize ();
- LogSP log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_TYPE_COMPLETION));
-
- if (src_size && dst_size)
+ Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_TYPE_COMPLETION));
+
+ // Is everything kosher so we can go through the members at top speed?
+ bool fast_path = true;
+
+ if (src_size != dst_size)
{
- if (src_size != dst_size)
+ if (src_size != 0 && dst_size != 0)
{
if (log)
- log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but they didn't have the same size (src=%d, dst=%d)",
+ log->Printf("warning: trying to unique class DIE 0x%8.8x to 0x%8.8x, but they didn't have the same size (src=%d, dst=%d)",
src_class_die->GetOffset(),
dst_class_die->GetOffset(),
src_size,
dst_size);
-
- return false;
}
-
- uint32_t idx;
+
+ fast_path = false;
+ }
+
+ uint32_t idx;
+
+ if (fast_path)
+ {
for (idx = 0; idx < src_size; ++idx)
{
src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
@@ -4943,10 +5241,10 @@ SymbolFileDWARF::CopyUniqueClassMethodTy
DW_TAG_value_to_name(src_die->Tag()),
dst_die->GetOffset(),
DW_TAG_value_to_name(src_die->Tag()));
- return false;
+ fast_path = false;
}
- const char *src_name = src_die->GetMangledName (this, src_cu);
+ const char *src_name = src_die->GetMangledName (src_symfile, src_cu);
const char *dst_name = dst_die->GetMangledName (this, dst_cu);
// Make sure the names match
@@ -4962,54 +5260,163 @@ SymbolFileDWARF::CopyUniqueClassMethodTy
dst_die->GetOffset(),
dst_name);
- return false;
+ fast_path = false;
+ }
+ }
+
+ // Now do the work of linking the DeclContexts and Types.
+ if (fast_path)
+ {
+ // We can do this quickly. Just run across the tables index-for-index since
+ // we know each node has matching names and tags.
+ for (idx = 0; idx < src_size; ++idx)
+ {
+ src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
+ dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx);
+
+ clang::DeclContext *src_decl_ctx = src_symfile->m_die_to_decl_ctx[src_die];
+ if (src_decl_ctx)
+ {
+ if (log)
+ log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x", src_decl_ctx, src_die->GetOffset(), dst_die->GetOffset());
+ LinkDeclContextToDIE (src_decl_ctx, dst_die);
+ }
+ else
+ {
+ if (log)
+ log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
+ }
+
+ Type *src_child_type = m_die_to_type[src_die];
+ if (src_child_type)
+ {
+ if (log)
+ log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x", src_child_type, src_child_type->GetID(), src_die->GetOffset(), dst_die->GetOffset());
+ m_die_to_type[dst_die] = src_child_type;
+ }
+ else
+ {
+ if (log)
+ log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
+ }
+ }
+ }
+ else
+ {
+ // We must do this slowly. For each member of the destination, look
+ // up a member in the source with the same name, check its tag, and
+ // unique them if everything matches up. Report failures.
+
+ if (!src_name_to_die.IsEmpty() && !dst_name_to_die.IsEmpty())
+ {
+ src_name_to_die.Sort();
+
+ for (idx = 0; idx < dst_size; ++idx)
+ {
+ const char *dst_name = dst_name_to_die.GetCStringAtIndex(idx);
+ dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
+ src_die = src_name_to_die.Find(dst_name, NULL);
+
+ if (src_die && (src_die->Tag() == dst_die->Tag()))
+ {
+ clang::DeclContext *src_decl_ctx = src_symfile->m_die_to_decl_ctx[src_die];
+ if (src_decl_ctx)
+ {
+ if (log)
+ log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x", src_decl_ctx, src_die->GetOffset(), dst_die->GetOffset());
+ LinkDeclContextToDIE (src_decl_ctx, dst_die);
+ }
+ else
+ {
+ if (log)
+ log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
+ }
+
+ Type *src_child_type = m_die_to_type[src_die];
+ if (src_child_type)
+ {
+ if (log)
+ log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x", src_child_type, src_child_type->GetID(), src_die->GetOffset(), dst_die->GetOffset());
+ m_die_to_type[dst_die] = src_child_type;
+ }
+ else
+ {
+ if (log)
+ log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf ("warning: couldn't find a match for 0x%8.8x", dst_die->GetOffset());
+
+ failures.push_back(dst_die);
+ }
+ }
}
+ }
+
+ const uint32_t src_size_artificial = src_name_to_die_artificial.GetSize ();
+ const uint32_t dst_size_artificial = dst_name_to_die_artificial.GetSize ();
+
+ UniqueCStringMap<const DWARFDebugInfoEntry *> name_to_die_artificial_not_in_src;
- for (idx = 0; idx < src_size; ++idx)
+ if (src_size_artificial && dst_size_artificial)
+ {
+ dst_name_to_die_artificial.Sort();
+
+ for (idx = 0; idx < src_size_artificial; ++idx)
{
- src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
- dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx);
-
- clang::DeclContext *src_decl_ctx = m_die_to_decl_ctx[src_die];
- if (src_decl_ctx)
- {
- if (log)
- log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x\n", src_decl_ctx, src_die->GetOffset(), dst_die->GetOffset());
- LinkDeclContextToDIE (src_decl_ctx, dst_die);
- }
- else
- {
- if (log)
- log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found\n", src_die->GetOffset(), dst_die->GetOffset());
- }
+ const char *src_name_artificial = src_name_to_die_artificial.GetCStringAtIndex(idx);
+ src_die = src_name_to_die_artificial.GetValueAtIndexUnchecked (idx);
+ dst_die = dst_name_to_die_artificial.Find(src_name_artificial, NULL);
- Type *src_child_type = m_die_to_type[src_die];
- if (src_child_type)
- {
- if (log)
- log->Printf ("uniquing type %p (uid=0x%llx) from 0x%8.8x for 0x%8.8x\n", src_child_type, src_child_type->GetID(), src_die->GetOffset(), dst_die->GetOffset());
- m_die_to_type[dst_die] = src_child_type;
- }
- else
+ if (dst_die)
{
- if (log)
- log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found\n", src_die->GetOffset(), dst_die->GetOffset());
+ // Both classes have the artificial types, link them
+ clang::DeclContext *src_decl_ctx = m_die_to_decl_ctx[src_die];
+ if (src_decl_ctx)
+ {
+ if (log)
+ log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x", src_decl_ctx, src_die->GetOffset(), dst_die->GetOffset());
+ LinkDeclContextToDIE (src_decl_ctx, dst_die);
+ }
+ else
+ {
+ if (log)
+ log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
+ }
+
+ Type *src_child_type = m_die_to_type[src_die];
+ if (src_child_type)
+ {
+ if (log)
+ log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x", src_child_type, src_child_type->GetID(), src_die->GetOffset(), dst_die->GetOffset());
+ m_die_to_type[dst_die] = src_child_type;
+ }
+ else
+ {
+ if (log)
+ log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
+ }
}
}
- return true;
}
- else
+
+ if (dst_size_artificial)
{
- if (log)
- log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x has %u methods and 0x%8.8x has %u",
- src_class_die->GetOffset(),
- dst_class_die->GetOffset(),
- src_die->GetOffset(),
- src_size,
- dst_die->GetOffset(),
- dst_size);
+ for (idx = 0; idx < dst_size_artificial; ++idx)
+ {
+ const char *dst_name_artificial = dst_name_to_die_artificial.GetCStringAtIndex(idx);
+ dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked (idx);
+ if (log)
+ log->Printf ("warning: need to create artificial method for 0x%8.8x for method '%s'", dst_die->GetOffset(), dst_name_artificial);
+
+ failures.push_back(dst_die);
+ }
}
- return false;
+
+ return (failures.size() != 0);
}
TypeSP
@@ -5028,13 +5435,13 @@ SymbolFileDWARF::ParseType (const Symbol
AccessType accessibility = eAccessNone;
if (die != NULL)
{
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
if (log)
{
const DWARFDebugInfoEntry *context_die;
clang::DeclContext *context = GetClangDeclContextContainingDIE (dwarf_cu, die, &context_die);
- GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x, decl_ctx = %p (die 0x%8.8x)) %s name = '%s')",
+ GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x, decl_ctx = %p (die 0x%8.8x)) %s name = '%s')",
die->GetOffset(),
context,
context_die->GetOffset(),
@@ -5043,16 +5450,16 @@ SymbolFileDWARF::ParseType (const Symbol
#if defined(LLDB_CONFIGURATION_DEBUG) or defined(LLDB_CONFIGURATION_RELEASE)
scoped_die_logger.Push (dwarf_cu, die);
- g_die_stack.LogDIEs(log.get(), this);
+ g_die_stack.LogDIEs(log, this);
#endif
}
//
-// LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
+// Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
// if (log && dwarf_cu)
// {
// StreamString s;
// die->DumpLocation (this, dwarf_cu, s);
-// GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData());
+// GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData());
//
// }
@@ -5071,7 +5478,7 @@ SymbolFileDWARF::ParseType (const Symbol
const char *type_name_cstr = NULL;
ConstString type_name_const_str;
Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
- size_t byte_size = 0;
+ uint64_t byte_size = 0;
Declaration decl;
Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
@@ -5136,7 +5543,7 @@ SymbolFileDWARF::ParseType (const Symbol
}
}
- DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\") type => 0x%8.8x\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
+ DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8x\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
switch (tag)
{
@@ -5168,51 +5575,80 @@ SymbolFileDWARF::ParseType (const Symbol
case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
}
- if (clang_type == NULL && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID))
+ if (clang_type == NULL && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL)
{
- if (type_name_cstr != NULL && sc.comp_unit != NULL &&
- (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
+ bool translation_unit_is_objc = (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus);
+
+ if (translation_unit_is_objc)
{
- static ConstString g_objc_type_name_id("id");
- static ConstString g_objc_type_name_Class("Class");
- static ConstString g_objc_type_name_selector("SEL");
-
- if (type_name_const_str == g_objc_type_name_id)
+ if (type_name_cstr != NULL)
{
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'id' built-in type.",
- die->GetOffset(),
- DW_TAG_value_to_name(die->Tag()),
- die->GetName(this, dwarf_cu));
- clang_type = ast.GetBuiltInType_objc_id();
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid = LLDB_INVALID_UID;
- resolve_state = Type::eResolveStateFull;
+ static ConstString g_objc_type_name_id("id");
+ static ConstString g_objc_type_name_Class("Class");
+ static ConstString g_objc_type_name_selector("SEL");
+
+ if (type_name_const_str == g_objc_type_name_id)
+ {
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'id' built-in type.",
+ die->GetOffset(),
+ DW_TAG_value_to_name(die->Tag()),
+ die->GetName(this, dwarf_cu));
+ clang_type = ast.GetBuiltInType_objc_id();
+ encoding_data_type = Type::eEncodingIsUID;
+ encoding_uid = LLDB_INVALID_UID;
+ resolve_state = Type::eResolveStateFull;
+ }
+ else if (type_name_const_str == g_objc_type_name_Class)
+ {
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'Class' built-in type.",
+ die->GetOffset(),
+ DW_TAG_value_to_name(die->Tag()),
+ die->GetName(this, dwarf_cu));
+ clang_type = ast.GetBuiltInType_objc_Class();
+ encoding_data_type = Type::eEncodingIsUID;
+ encoding_uid = LLDB_INVALID_UID;
+ resolve_state = Type::eResolveStateFull;
+ }
+ else if (type_name_const_str == g_objc_type_name_selector)
+ {
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'selector' built-in type.",
+ die->GetOffset(),
+ DW_TAG_value_to_name(die->Tag()),
+ die->GetName(this, dwarf_cu));
+ clang_type = ast.GetBuiltInType_objc_selector();
+ encoding_data_type = Type::eEncodingIsUID;
+ encoding_uid = LLDB_INVALID_UID;
+ resolve_state = Type::eResolveStateFull;
+ }
}
- else if (type_name_const_str == g_objc_type_name_Class)
- {
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'Class' built-in type.",
- die->GetOffset(),
- DW_TAG_value_to_name(die->Tag()),
- die->GetName(this, dwarf_cu));
- clang_type = ast.GetBuiltInType_objc_Class();
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid = LLDB_INVALID_UID;
- resolve_state = Type::eResolveStateFull;
- }
- else if (type_name_const_str == g_objc_type_name_selector)
+ else if (encoding_data_type == Type::eEncodingIsPointerUID && encoding_uid != LLDB_INVALID_UID)
{
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'selector' built-in type.",
- die->GetOffset(),
- DW_TAG_value_to_name(die->Tag()),
- die->GetName(this, dwarf_cu));
- clang_type = ast.GetBuiltInType_objc_selector();
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid = LLDB_INVALID_UID;
- resolve_state = Type::eResolveStateFull;
+ // Clang sometimes erroneously emits id as objc_object*. In that case we fix up the type to "id".
+
+ DWARFDebugInfoEntry* encoding_die = dwarf_cu->GetDIEPtr(encoding_uid);
+
+ if (encoding_die && encoding_die->Tag() == DW_TAG_structure_type)
+ {
+ if (const char *struct_name = encoding_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_name, NULL))
+ {
+ if (!strcmp(struct_name, "objc_object"))
+ {
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is 'objc_object*', which we overrode to 'id'.",
+ die->GetOffset(),
+ DW_TAG_value_to_name(die->Tag()),
+ die->GetName(this, dwarf_cu));
+ clang_type = ast.GetBuiltInType_objc_id();
+ encoding_data_type = Type::eEncodingIsUID;
+ encoding_uid = LLDB_INVALID_UID;
+ resolve_state = Type::eResolveStateFull;
+ }
+ }
+ }
}
}
}
@@ -5299,7 +5735,7 @@ SymbolFileDWARF::ParseType (const Symbol
break;
case DW_AT_declaration:
- is_forward_declaration = form_value.Unsigned() != 0;
+ is_forward_declaration = form_value.Boolean();
break;
case DW_AT_APPLE_runtime_class:
@@ -5349,7 +5785,7 @@ SymbolFileDWARF::ParseType (const Symbol
}
}
- DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
+ DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
int tag_decl_kind = -1;
AccessType default_accessibility = eAccessNone;
@@ -5399,7 +5835,7 @@ SymbolFileDWARF::ParseType (const Symbol
// know it is false), so the real definition is in here somewhere
type_sp = FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true);
- if (!type_sp && m_debug_map_symfile)
+ if (!type_sp && GetDebugMapSymfile ())
{
// We weren't able to find a full declaration in
// this DWARF, see if we have a declaration anywhere
@@ -5411,8 +5847,8 @@ SymbolFileDWARF::ParseType (const Symbol
{
if (log)
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an incomplete objc type, complete type is 0x%8.8llx",
+ GetObjectFile()->GetModule()->LogMessage (log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an incomplete objc type, complete type is 0x%8.8" PRIx64,
this,
die->GetOffset(),
DW_TAG_value_to_name(tag),
@@ -5439,7 +5875,7 @@ SymbolFileDWARF::ParseType (const Symbol
// DWARF. If this fails, we need to look elsewhere...
if (log)
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
+ GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, trying to find complete type",
this,
die->GetOffset(),
@@ -5453,7 +5889,7 @@ SymbolFileDWARF::ParseType (const Symbol
//type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
type_sp = FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
- if (!type_sp && m_debug_map_symfile)
+ if (!type_sp && GetDebugMapSymfile ())
{
// We weren't able to find a full declaration in
// this DWARF, see if we have a declaration anywhere
@@ -5465,8 +5901,8 @@ SymbolFileDWARF::ParseType (const Symbol
{
if (log)
{
- GetObjectFile()->GetModule()->LogMessage (log.get(),
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8llx",
+ GetObjectFile()->GetModule()->LogMessage (log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8" PRIx64,
this,
die->GetOffset(),
DW_TAG_value_to_name(tag),
@@ -5498,6 +5934,10 @@ SymbolFileDWARF::ParseType (const Symbol
accessibility = default_accessibility;
}
+ ClangASTMetadata metadata;
+ metadata.SetUserID(MakeUserID(die->GetOffset()));
+ metadata.SetIsDynamicCXXType(ClassOrStructIsVirtual (dwarf_cu, die));
+
if (type_name_cstr && strchr (type_name_cstr, '<'))
{
ClangASTContext::TemplateParameterInfos template_param_infos;
@@ -5516,8 +5956,8 @@ SymbolFileDWARF::ParseType (const Symbol
clang_type = ast.CreateClassTemplateSpecializationType (class_specialization_decl);
clang_type_was_created = true;
- GetClangASTContext().SetMetadata((uintptr_t)class_template_decl, MakeUserID(die->GetOffset()));
- GetClangASTContext().SetMetadata((uintptr_t)class_specialization_decl, MakeUserID(die->GetOffset()));
+ GetClangASTContext().SetMetadata (class_template_decl, metadata);
+ GetClangASTContext().SetMetadata (class_specialization_decl, metadata);
}
}
@@ -5529,7 +5969,7 @@ SymbolFileDWARF::ParseType (const Symbol
type_name_cstr,
tag_decl_kind,
class_language,
- MakeUserID(die->GetOffset()));
+ &metadata);
}
}
@@ -5574,6 +6014,27 @@ SymbolFileDWARF::ParseType (const Symbol
// No children for this struct/union/class, lets finish it
ast.StartTagDeclarationDefinition (clang_type);
ast.CompleteTagDeclarationDefinition (clang_type);
+
+ if (tag == DW_TAG_structure_type) // this only applies in C
+ {
+ clang::QualType qual_type = clang::QualType::getFromOpaquePtr (clang_type);
+ const clang::RecordType *record_type = qual_type->getAs<clang::RecordType> ();
+
+ if (record_type)
+ {
+ clang::RecordDecl *record_decl = record_type->getDecl();
+
+ if (record_decl)
+ {
+ LayoutInfo layout_info;
+
+ layout_info.alignment = 0;
+ layout_info.bit_size = 0;
+
+ m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
+ }
+ }
+ }
}
else if (clang_type_was_created)
{
@@ -5633,7 +6094,7 @@ SymbolFileDWARF::ParseType (const Symbol
case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
- case DW_AT_declaration: break; //is_forward_declaration = form_value.Unsigned() != 0; break;
+ case DW_AT_declaration: break; //is_forward_declaration = form_value.Boolean(); break;
case DW_AT_allocated:
case DW_AT_associated:
case DW_AT_bit_stride:
@@ -5650,15 +6111,24 @@ SymbolFileDWARF::ParseType (const Symbol
}
}
- DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
+ DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
clang_type_t enumerator_clang_type = NULL;
clang_type = m_forward_decl_die_to_clang_type.lookup (die);
if (clang_type == NULL)
{
- enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
- DW_ATE_signed,
- byte_size * 8);
+ if (encoding_uid != DW_INVALID_OFFSET)
+ {
+ Type *enumerator_type = ResolveTypeUID(encoding_uid);
+ if (enumerator_type)
+ enumerator_clang_type = enumerator_type->GetClangFullType();
+ }
+
+ if (enumerator_clang_type == NULL)
+ enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
+ DW_ATE_signed,
+ byte_size * 8);
+
clang_type = ast.CreateEnumerationType (type_name_cstr,
GetClangDeclContextContainingDIE (dwarf_cu, die, NULL),
decl,
@@ -5667,7 +6137,6 @@ SymbolFileDWARF::ParseType (const Symbol
else
{
enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
- assert (enumerator_clang_type != NULL);
}
LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
@@ -5687,7 +6156,9 @@ SymbolFileDWARF::ParseType (const Symbol
if (die->HasChildren())
{
SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
- ParseChildEnumerators(cu_sc, clang_type, type_sp->GetByteSize(), dwarf_cu, die);
+ bool is_signed = false;
+ ast.IsIntegerType(enumerator_clang_type, is_signed);
+ ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), dwarf_cu, die);
}
ast.CompleteTagDeclarationDefinition (clang_type);
}
@@ -5711,6 +6182,7 @@ SymbolFileDWARF::ParseType (const Symbol
bool is_artificial = false;
dw_offset_t specification_die_offset = DW_INVALID_OFFSET;
dw_offset_t abstract_origin_die_offset = DW_INVALID_OFFSET;
+ dw_offset_t object_pointer_die_offset = DW_INVALID_OFFSET;
unsigned type_quals = 0;
clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
@@ -5736,14 +6208,15 @@ SymbolFileDWARF::ParseType (const Symbol
type_name_const_str.SetCString(type_name_cstr);
break;
+ case DW_AT_linkage_name:
case DW_AT_MIPS_linkage_name: break; // mangled = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
- case DW_AT_declaration: break; // is_forward_declaration = form_value.Unsigned() != 0; break;
- case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
- case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
- case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break;
- case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
+ case DW_AT_declaration: break; // is_forward_declaration = form_value.Boolean(); break;
+ case DW_AT_inline: is_inline = form_value.Boolean(); break;
+ case DW_AT_virtuality: is_virtual = form_value.Boolean(); break;
+ case DW_AT_explicit: is_explicit = form_value.Boolean(); break;
+ case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
case DW_AT_external:
@@ -5764,6 +6237,10 @@ SymbolFileDWARF::ParseType (const Symbol
abstract_origin_die_offset = form_value.Reference(dwarf_cu);
break;
+ case DW_AT_object_pointer:
+ object_pointer_die_offset = form_value.Reference(dwarf_cu);
+ break;
+
case DW_AT_allocated:
case DW_AT_associated:
case DW_AT_address_class:
@@ -5774,7 +6251,6 @@ SymbolFileDWARF::ParseType (const Symbol
case DW_AT_frame_base:
case DW_AT_high_pc:
case DW_AT_low_pc:
- case DW_AT_object_pointer:
case DW_AT_prototyped:
case DW_AT_pure:
case DW_AT_ranges:
@@ -5794,7 +6270,18 @@ SymbolFileDWARF::ParseType (const Symbol
}
}
- DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
+ std::string object_pointer_name;
+ if (object_pointer_die_offset != DW_INVALID_OFFSET)
+ {
+ // Get the name from the object pointer die
+ StreamString s;
+ if (DWARFDebugInfoEntry::GetName (this, dwarf_cu, object_pointer_die_offset, s))
+ {
+ object_pointer_name.assign(s.GetData());
+ }
+ }
+
+ DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
clang_type_t return_clang_type = NULL;
Type *func_type = NULL;
@@ -5827,14 +6314,14 @@ SymbolFileDWARF::ParseType (const Symbol
if (die->HasChildren())
{
bool skip_artificial = true;
- ParseChildParameters (sc,
+ ParseChildParameters (sc,
containing_decl_ctx,
- dwarf_cu,
- die,
+ dwarf_cu,
+ die,
skip_artificial,
is_static,
- type_list,
- function_param_types,
+ type_list,
+ function_param_types,
function_param_decls,
type_quals,
template_param_infos);
@@ -5842,26 +6329,24 @@ SymbolFileDWARF::ParseType (const Symbol
// clang_type will get the function prototype clang type after this call
clang_type = ast.CreateFunctionType (return_clang_type,
- &function_param_types[0],
+ function_param_types.data(),
function_param_types.size(),
is_variadic,
type_quals);
+ bool ignore_containing_context = false;
+
if (type_name_cstr)
{
bool type_handled = false;
if (tag == DW_TAG_subprogram)
{
- ConstString class_name;
- ConstString class_name_no_category;
- if (ObjCLanguageRuntime::ParseMethodName (type_name_cstr, &class_name, NULL, NULL, &class_name_no_category))
- {
- // Use the class name with no category if there is one
- if (class_name_no_category)
- class_name = class_name_no_category;
-
+ ObjCLanguageRuntime::MethodName objc_method (type_name_cstr, true);
+ if (objc_method.IsValid(true))
+ {
SymbolContext empty_sc;
clang_type_t class_opaque_type = NULL;
+ ConstString class_name(objc_method.GetClassName());
if (class_name)
{
TypeList types;
@@ -5882,14 +6367,24 @@ SymbolFileDWARF::ParseType (const Symbol
if (accessibility == eAccessNone)
accessibility = eAccessPublic;
- clang::ObjCMethodDecl *objc_method_decl;
- objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
- type_name_cstr,
- clang_type,
- accessibility);
- LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die);
+ clang::ObjCMethodDecl *objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
+ type_name_cstr,
+ clang_type,
+ accessibility,
+ is_artificial);
type_handled = objc_method_decl != NULL;
- GetClangASTContext().SetMetadata((uintptr_t)objc_method_decl, MakeUserID(die->GetOffset()));
+ if (type_handled)
+ {
+ LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die);
+ GetClangASTContext().SetMetadataAsUserID (objc_method_decl, MakeUserID(die->GetOffset()));
+ }
+ else
+ {
+ GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: invalid Objective-C method 0x%4.4x (%s), please file a bug and attach the file at the start of this error message",
+ die->GetOffset(),
+ tag,
+ DW_TAG_value_to_name(tag));
+ }
}
}
else if (is_cxx_method)
@@ -5905,22 +6400,43 @@ SymbolFileDWARF::ParseType (const Symbol
// We uniqued the parent class of this function to another class
// so we now need to associate all dies under "decl_ctx_die" to
// DIEs in the DIE for "class_type"...
+ SymbolFileDWARF *class_symfile = NULL;
DWARFCompileUnitSP class_type_cu_sp;
- const DWARFDebugInfoEntry *class_type_die = DebugInfo()->GetDIEPtr(class_type->GetID(), &class_type_cu_sp);
+ const DWARFDebugInfoEntry *class_type_die = NULL;
+
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile)
+ {
+ class_symfile = debug_map_symfile->GetSymbolFileByOSOIndex(SymbolFileDWARFDebugMap::GetOSOIndexFromUserID(class_type->GetID()));
+ class_type_die = class_symfile->DebugInfo()->GetDIEPtr(class_type->GetID(), &class_type_cu_sp);
+ }
+ else
+ {
+ class_symfile = this;
+ class_type_die = DebugInfo()->GetDIEPtr(class_type->GetID(), &class_type_cu_sp);
+ }
if (class_type_die)
{
- if (CopyUniqueClassMethodTypes (class_type,
- class_type_cu_sp.get(),
- class_type_die,
- dwarf_cu,
- decl_ctx_die))
+ llvm::SmallVector<const DWARFDebugInfoEntry *, 0> failures;
+
+ CopyUniqueClassMethodTypes (class_symfile,
+ class_type,
+ class_type_cu_sp.get(),
+ class_type_die,
+ dwarf_cu,
+ decl_ctx_die,
+ failures);
+
+ // FIXME do something with these failures that's smarter than
+ // just dropping them on the ground. Unfortunately classes don't
+ // like having stuff added to them after their definitions are
+ // complete...
+
+ type_ptr = m_die_to_type[die];
+ if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
{
- type_ptr = m_die_to_type[die];
- if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
- {
- type_sp = type_ptr->shared_from_this();
- break;
- }
+ type_sp = type_ptr->shared_from_this();
+ break;
}
}
}
@@ -5943,7 +6459,7 @@ SymbolFileDWARF::ParseType (const Symbol
}
else
{
- GetObjectFile()->GetModule()->ReportWarning ("0x%8.8llx: DW_AT_specification(0x%8.8x) has no decl\n",
+ GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8x) has no decl\n",
MakeUserID(die->GetOffset()),
specification_die_offset);
}
@@ -5966,7 +6482,7 @@ SymbolFileDWARF::ParseType (const Symbol
}
else
{
- GetObjectFile()->GetModule()->ReportWarning ("0x%8.8llx: DW_AT_abstract_origin(0x%8.8x) has no decl\n",
+ GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8x) has no decl\n",
MakeUserID(die->GetOffset()),
abstract_origin_die_offset);
}
@@ -5995,12 +6511,11 @@ SymbolFileDWARF::ParseType (const Symbol
{
clang::CXXMethodDecl *cxx_method_decl;
// REMOVE THE CRASH DESCRIPTION BELOW
- Host::SetCrashDescriptionWithFormat ("SymbolFileDWARF::ParseType() is adding a method %s to class %s in DIE 0x%8.8llx from %s/%s",
+ Host::SetCrashDescriptionWithFormat ("SymbolFileDWARF::ParseType() is adding a method %s to class %s in DIE 0x%8.8" PRIx64 " from %s",
type_name_cstr,
class_type->GetName().GetCString(),
MakeUserID(die->GetOffset()),
- m_obj_file->GetFileSpec().GetDirectory().GetCString(),
- m_obj_file->GetFileSpec().GetFilename().GetCString());
+ m_obj_file->GetFileSpec().GetPath().c_str());
const bool is_attr_used = false;
@@ -6014,13 +6529,33 @@ SymbolFileDWARF::ParseType (const Symbol
is_explicit,
is_attr_used,
is_artificial);
- LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
+
+ type_handled = cxx_method_decl != NULL;
- Host::SetCrashDescription (NULL);
+ if (type_handled)
+ {
+ LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
- type_handled = cxx_method_decl != NULL;
-
- GetClangASTContext().SetMetadata((uintptr_t)cxx_method_decl, MakeUserID(die->GetOffset()));
+ Host::SetCrashDescription (NULL);
+
+
+ ClangASTMetadata metadata;
+ metadata.SetUserID(MakeUserID(die->GetOffset()));
+
+ if (!object_pointer_name.empty())
+ {
+ metadata.SetObjectPtrName(object_pointer_name.c_str());
+ if (log)
+ log->Printf ("Setting object pointer name: %s on method object %p.\n",
+ object_pointer_name.c_str(),
+ cxx_method_decl);
+ }
+ GetClangASTContext().SetMetadata (cxx_method_decl, metadata);
+ }
+ else
+ {
+ ignore_containing_context = true;
+ }
}
}
else
@@ -6061,7 +6596,7 @@ SymbolFileDWARF::ParseType (const Symbol
if (!type_handled)
{
// We just have a function that isn't part of a class
- clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (containing_decl_ctx,
+ clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (ignore_containing_context ? GetClangASTContext().GetTranslationUnitDecl() : containing_decl_ctx,
type_name_cstr,
clang_type,
storage,
@@ -6086,7 +6621,18 @@ SymbolFileDWARF::ParseType (const Symbol
&function_param_decls.front(),
function_param_decls.size());
- GetClangASTContext().SetMetadata((uintptr_t)function_decl, MakeUserID(die->GetOffset()));
+ ClangASTMetadata metadata;
+ metadata.SetUserID(MakeUserID(die->GetOffset()));
+
+ if (!object_pointer_name.empty())
+ {
+ metadata.SetObjectPtrName(object_pointer_name.c_str());
+ if (log)
+ log->Printf ("Setting object pointer name: %s on function object %p.",
+ object_pointer_name.c_str(),
+ function_decl);
+ }
+ GetClangASTContext().SetMetadata (function_decl, metadata);
}
}
type_sp.reset( new Type (MakeUserID(die->GetOffset()),
@@ -6112,6 +6658,7 @@ SymbolFileDWARF::ParseType (const Symbol
int64_t first_index = 0;
uint32_t byte_stride = 0;
uint32_t bit_stride = 0;
+ bool is_vector = false;
const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
if (num_attributes > 0)
@@ -6137,8 +6684,9 @@ SymbolFileDWARF::ParseType (const Symbol
case DW_AT_byte_size: break; // byte_size = form_value.Unsigned(); break;
case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
+ case DW_AT_GNU_vector: is_vector = form_value.Boolean(); break;
case DW_AT_accessibility: break; // accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
- case DW_AT_declaration: break; // is_forward_declaration = form_value.Unsigned() != 0; break;
+ case DW_AT_declaration: break; // is_forward_declaration = form_value.Boolean(); break;
case DW_AT_allocated:
case DW_AT_associated:
case DW_AT_data_location:
@@ -6154,7 +6702,7 @@ SymbolFileDWARF::ParseType (const Symbol
}
}
- DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
+ DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
Type *element_type = ResolveTypeUID(type_die_offset);
@@ -6173,10 +6721,10 @@ SymbolFileDWARF::ParseType (const Symbol
{
num_elements = *pos;
clang_type = ast.CreateArrayType (array_element_type,
- num_elements,
- num_elements * array_element_bit_stride);
+ num_elements,
+ is_vector);
array_element_type = clang_type;
- array_element_bit_stride = array_element_bit_stride * num_elements;
+ array_element_bit_stride = num_elements ? array_element_bit_stride * num_elements : array_element_bit_stride;
}
ConstString empty_name;
type_sp.reset( new Type (MakeUserID(die->GetOffset()),
@@ -6247,7 +6795,10 @@ SymbolFileDWARF::ParseType (const Symbol
break;
}
default:
- assert(false && "Unhandled type tag!");
+ GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: unhandled type tag 0x%4.4x (%s), please file a bug and attach the file at the start of this error message",
+ die->GetOffset(),
+ tag,
+ DW_TAG_value_to_name(tag));
break;
}
@@ -6333,7 +6884,7 @@ SymbolFileDWARF::ParseFunctionBlocks (co
{
assert(sc.comp_unit && sc.function);
size_t functions_added = 0;
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
+ DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (dwarf_cu)
{
dw_offset_t function_die_offset = sc.function->GetID();
@@ -6354,7 +6905,7 @@ SymbolFileDWARF::ParseTypes (const Symbo
// At least a compile unit must be valid
assert(sc.comp_unit);
size_t types_added = 0;
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
+ DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (dwarf_cu)
{
if (sc.function)
@@ -6388,18 +6939,17 @@ SymbolFileDWARF::ParseVariablesForContex
if (info == NULL)
return 0;
- uint32_t cu_idx = UINT32_MAX;
- DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
-
- if (dwarf_cu == NULL)
- return 0;
-
if (sc.function)
{
+ DWARFCompileUnit* dwarf_cu = info->GetCompileUnitContainingDIE(sc.function->GetID()).get();
+
+ if (dwarf_cu == NULL)
+ return 0;
+
const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
- dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
- if (func_lo_pc != DW_INVALID_ADDRESS)
+ dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
+ if (func_lo_pc != LLDB_INVALID_ADDRESS)
{
const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
@@ -6410,6 +6960,11 @@ SymbolFileDWARF::ParseVariablesForContex
}
else if (sc.comp_unit)
{
+ DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID()).get();
+
+ if (dwarf_cu == NULL)
+ return 0;
+
uint32_t vars_added = 0;
VariableListSP variables (sc.comp_unit->GetVariableList(false));
@@ -6514,6 +7069,7 @@ SymbolFileDWARF::ParseVariableDIE
bool is_external = false;
bool is_artificial = false;
bool location_is_const_value_data = false;
+ bool has_explicit_location = false;
//AccessType accessibility = eAccessNone;
for (i=0; i<num_attributes; ++i)
@@ -6528,14 +7084,56 @@ SymbolFileDWARF::ParseVariableDIE
case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
+ case DW_AT_linkage_name:
case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_type: type_uid = form_value.Reference(dwarf_cu); break;
- case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
+ case DW_AT_external: is_external = form_value.Boolean(); break;
case DW_AT_const_value:
- location_is_const_value_data = true;
- // Fall through...
+ // If we have already found a DW_AT_location attribute, ignore this attribute.
+ if (!has_explicit_location)
+ {
+ location_is_const_value_data = true;
+ // The constant value will be either a block, a data value or a string.
+ const DataExtractor& debug_info_data = get_debug_info_data();
+ if (DWARFFormValue::IsBlockForm(form_value.Form()))
+ {
+ // Retrieve the value as a block expression.
+ uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
+ uint32_t block_length = form_value.Unsigned();
+ location.CopyOpcodeData(debug_info_data, block_offset, block_length);
+ }
+ else if (DWARFFormValue::IsDataForm(form_value.Form()))
+ {
+ // Retrieve the value as a data expression.
+ const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
+ uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
+ uint32_t data_length = fixed_form_sizes[form_value.Form()];
+ location.CopyOpcodeData(debug_info_data, data_offset, data_length);
+ }
+ else
+ {
+ // Retrieve the value as a string expression.
+ if (form_value.Form() == DW_FORM_strp)
+ {
+ const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
+ uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
+ uint32_t data_length = fixed_form_sizes[form_value.Form()];
+ location.CopyOpcodeData(debug_info_data, data_offset, data_length);
+ }
+ else
+ {
+ const char *str = form_value.AsCString(&debug_info_data);
+ uint32_t string_offset = str - (const char *)debug_info_data.GetDataStart();
+ uint32_t string_length = strlen(str) + 1;
+ location.CopyOpcodeData(debug_info_data, string_offset, string_length);
+ }
+ }
+ }
+ break;
case DW_AT_location:
{
+ location_is_const_value_data = false;
+ has_explicit_location = true;
if (form_value.BlockData())
{
const DataExtractor& debug_info_data = get_debug_info_data();
@@ -6560,7 +7158,7 @@ SymbolFileDWARF::ParseVariableDIE
}
break;
- case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
+ case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
case DW_AT_declaration:
case DW_AT_description:
@@ -6577,104 +7175,97 @@ SymbolFileDWARF::ParseVariableDIE
}
}
- if (location.IsValid())
- {
- ValueType scope = eValueTypeInvalid;
-
- const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
- dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
- SymbolContextScope * symbol_context_scope = NULL;
+ ValueType scope = eValueTypeInvalid;
- // DWARF doesn't specify if a DW_TAG_variable is a local, global
- // or static variable, so we have to do a little digging by
- // looking at the location of a varaible to see if it contains
- // a DW_OP_addr opcode _somewhere_ in the definition. I say
- // somewhere because clang likes to combine small global variables
- // into the same symbol and have locations like:
- // DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
- // So if we don't have a DW_TAG_formal_parameter, we can look at
- // the location to see if it contains a DW_OP_addr opcode, and
- // then we can correctly classify our variables.
- if (tag == DW_TAG_formal_parameter)
- scope = eValueTypeVariableArgument;
- else
+ const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
+ dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
+ SymbolContextScope * symbol_context_scope = NULL;
+
+ // DWARF doesn't specify if a DW_TAG_variable is a local, global
+ // or static variable, so we have to do a little digging by
+ // looking at the location of a varaible to see if it contains
+ // a DW_OP_addr opcode _somewhere_ in the definition. I say
+ // somewhere because clang likes to combine small global variables
+ // into the same symbol and have locations like:
+ // DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
+ // So if we don't have a DW_TAG_formal_parameter, we can look at
+ // the location to see if it contains a DW_OP_addr opcode, and
+ // then we can correctly classify our variables.
+ if (tag == DW_TAG_formal_parameter)
+ scope = eValueTypeVariableArgument;
+ else
+ {
+ bool op_error = false;
+ // Check if the location has a DW_OP_addr with any address value...
+ lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
+ if (!location_is_const_value_data)
{
- bool op_error = false;
- // Check if the location has a DW_OP_addr with any address value...
- addr_t location_has_op_addr = false;
- if (!location_is_const_value_data)
- {
- location_has_op_addr = location.LocationContains_DW_OP_addr (LLDB_INVALID_ADDRESS, op_error);
- if (op_error)
- {
- StreamString strm;
- location.DumpLocationForAddress (&strm, eDescriptionLevelFull, 0, 0, NULL);
- GetObjectFile()->GetModule()->ReportError ("0x%8.8x: %s has an invalid location: %s", die->GetOffset(), DW_TAG_value_to_name(die->Tag()), strm.GetString().c_str());
- }
+ location_DW_OP_addr = location.GetLocation_DW_OP_addr (0, op_error);
+ if (op_error)
+ {
+ StreamString strm;
+ location.DumpLocationForAddress (&strm, eDescriptionLevelFull, 0, 0, NULL);
+ GetObjectFile()->GetModule()->ReportError ("0x%8.8x: %s has an invalid location: %s", die->GetOffset(), DW_TAG_value_to_name(die->Tag()), strm.GetString().c_str());
}
+ }
- if (location_has_op_addr)
- {
- if (is_external)
- {
- scope = eValueTypeVariableGlobal;
-
- if (m_debug_map_symfile)
- {
- // When leaving the DWARF in the .o files on darwin,
- // when we have a global variable that wasn't initialized,
- // the .o file might not have allocated a virtual
- // address for the global variable. In this case it will
- // have created a symbol for the global variable
- // that is undefined and external and the value will
- // be the byte size of the variable. When we do the
- // address map in SymbolFileDWARFDebugMap we rely on
- // having an address, we need to do some magic here
- // so we can get the correct address for our global
- // variable. The address for all of these entries
- // will be zero, and there will be an undefined symbol
- // in this object file, and the executable will have
- // a matching symbol with a good address. So here we
- // dig up the correct address and replace it in the
- // location for the variable, and set the variable's
- // symbol context scope to be that of the main executable
- // so the file address will resolve correctly.
- if (location.LocationContains_DW_OP_addr (0, op_error))
+ if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
+ {
+ if (is_external)
+ scope = eValueTypeVariableGlobal;
+ else
+ scope = eValueTypeVariableStatic;
+
+
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile ();
+
+ if (debug_map_symfile)
+ {
+ // When leaving the DWARF in the .o files on darwin,
+ // when we have a global variable that wasn't initialized,
+ // the .o file might not have allocated a virtual
+ // address for the global variable. In this case it will
+ // have created a symbol for the global variable
+ // that is undefined/data and external and the value will
+ // be the byte size of the variable. When we do the
+ // address map in SymbolFileDWARFDebugMap we rely on
+ // having an address, we need to do some magic here
+ // so we can get the correct address for our global
+ // variable. The address for all of these entries
+ // will be zero, and there will be an undefined symbol
+ // in this object file, and the executable will have
+ // a matching symbol with a good address. So here we
+ // dig up the correct address and replace it in the
+ // location for the variable, and set the variable's
+ // symbol context scope to be that of the main executable
+ // so the file address will resolve correctly.
+ bool linked_oso_file_addr = false;
+ if (is_external && location_DW_OP_addr == 0)
+ {
+
+ // we have a possible uninitialized extern global
+ ConstString const_name(mangled ? mangled : name);
+ ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile();
+ if (debug_map_objfile)
+ {
+ Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
+ if (debug_map_symtab)
{
-
- // we have a possible uninitialized extern global
- Symtab *symtab = m_obj_file->GetSymtab();
- if (symtab)
- {
- ConstString const_name(name);
- Symbol *undefined_symbol = symtab->FindFirstSymbolWithNameAndType (const_name,
- eSymbolTypeUndefined,
- Symtab::eDebugNo,
+ Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
+ eSymbolTypeData,
+ Symtab::eDebugYes,
Symtab::eVisibilityExtern);
-
- if (undefined_symbol)
+ if (exe_symbol)
+ {
+ if (exe_symbol->ValueIsAddress())
{
- ObjectFile *debug_map_objfile = m_debug_map_symfile->GetObjectFile();
- if (debug_map_objfile)
+ const addr_t exe_file_addr = exe_symbol->GetAddress().GetFileAddress();
+ if (exe_file_addr != LLDB_INVALID_ADDRESS)
{
- Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
- Symbol *defined_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
- eSymbolTypeData,
- Symtab::eDebugYes,
- Symtab::eVisibilityExtern);
- if (defined_symbol)
+ if (location.Update_DW_OP_addr (exe_file_addr))
{
- if (defined_symbol->ValueIsAddress())
- {
- const addr_t defined_addr = defined_symbol->GetAddress().GetFileAddress();
- if (defined_addr != LLDB_INVALID_ADDRESS)
- {
- if (location.Update_DW_OP_addr (defined_addr))
- {
- symbol_context_scope = defined_symbol;
- }
- }
- }
+ linked_oso_file_addr = true;
+ symbol_context_scope = exe_symbol;
}
}
}
@@ -6682,60 +7273,73 @@ SymbolFileDWARF::ParseVariableDIE
}
}
}
- else
+
+ if (!linked_oso_file_addr)
{
- scope = eValueTypeVariableStatic;
+ // The DW_OP_addr is not zero, but it contains a .o file address which
+ // needs to be linked up correctly.
+ const lldb::addr_t exe_file_addr = debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);
+ if (exe_file_addr != LLDB_INVALID_ADDRESS)
+ {
+ // Update the file address for this variable
+ location.Update_DW_OP_addr (exe_file_addr);
+ }
+ else
+ {
+ // Variable didn't make it into the final executable
+ return var_sp;
+ }
}
}
- else
- {
- scope = eValueTypeVariableLocal;
- }
}
+ else
+ {
+ scope = eValueTypeVariableLocal;
+ }
+ }
- if (symbol_context_scope == NULL)
+ if (symbol_context_scope == NULL)
+ {
+ switch (parent_tag)
{
- switch (parent_tag)
+ case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_lexical_block:
+ if (sc.function)
{
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine:
- case DW_TAG_lexical_block:
- if (sc.function)
- {
- symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
- if (symbol_context_scope == NULL)
- symbol_context_scope = sc.function;
- }
- break;
-
- default:
- symbol_context_scope = sc.comp_unit;
- break;
+ symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
+ if (symbol_context_scope == NULL)
+ symbol_context_scope = sc.function;
}
+ break;
+
+ default:
+ symbol_context_scope = sc.comp_unit;
+ break;
}
+ }
- if (symbol_context_scope)
- {
- var_sp.reset (new Variable (MakeUserID(die->GetOffset()),
- name,
- mangled,
- SymbolFileTypeSP (new SymbolFileType(*this, type_uid)),
- scope,
- symbol_context_scope,
- &decl,
- location,
- is_external,
- is_artificial));
-
- var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
- }
- else
- {
- // Not ready to parse this variable yet. It might be a global
- // or static variable that is in a function scope and the function
- // in the symbol context wasn't filled in yet
- return var_sp;
- }
+ if (symbol_context_scope)
+ {
+ var_sp.reset (new Variable (MakeUserID(die->GetOffset()),
+ name,
+ mangled,
+ SymbolFileTypeSP (new SymbolFileType(*this, type_uid)),
+ scope,
+ symbol_context_scope,
+ &decl,
+ location,
+ is_external,
+ is_artificial));
+
+ var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
+ }
+ else
+ {
+ // Not ready to parse this variable yet. It might be a global
+ // or static variable that is in a function scope and the function
+ // in the symbol context wasn't filled in yet
+ return var_sp;
}
}
// Cache var_sp even if NULL (the variable was just a specification or
@@ -6869,7 +7473,7 @@ SymbolFileDWARF::ParseVariables
}
else
{
- GetObjectFile()->GetModule()->ReportError ("parent 0x%8.8llx %s with no valid compile unit in symbol context for 0x%8.8llx %s.\n",
+ GetObjectFile()->GetModule()->ReportError ("parent 0x%8.8" PRIx64 " %s with no valid compile unit in symbol context for 0x%8.8" PRIx64 " %s.\n",
MakeUserID(sc_parent_die->GetOffset()),
DW_TAG_value_to_name (parent_tag),
MakeUserID(orig_die->GetOffset()),
@@ -6913,7 +7517,7 @@ SymbolFileDWARF::ParseVariables
break;
default:
- GetObjectFile()->GetModule()->ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8llx %s.\n",
+ GetObjectFile()->GetModule()->ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8" PRIx64 " %s.\n",
MakeUserID(orig_die->GetOffset()),
DW_TAG_value_to_name (orig_die->Tag()));
break;
@@ -6952,15 +7556,9 @@ SymbolFileDWARF::ParseVariables
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-const char *
+ConstString
SymbolFileDWARF::GetPluginName()
{
- return "SymbolFileDWARF";
-}
-
-const char *
-SymbolFileDWARF::GetShortPluginName()
-{
return GetPluginNameStatic();
}
@@ -6993,10 +7591,9 @@ SymbolFileDWARF::DumpIndexes ()
{
StreamFile s(stdout, false);
- s.Printf ("DWARF index for (%s) '%s/%s':",
+ s.Printf ("DWARF index for (%s) '%s':",
GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
- GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
- GetObjectFile()->GetFileSpec().GetFilename().AsCString());
+ GetObjectFile()->GetFileSpec().GetPath().c_str());
s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
@@ -7119,7 +7716,7 @@ SymbolFileDWARF::LayoutRecordType (const
llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
{
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find (record_decl);
bool success = false;
base_offsets.clear();
@@ -7129,6 +7726,8 @@ SymbolFileDWARF::LayoutRecordType (const
bit_size = pos->second.bit_size;
alignment = pos->second.alignment;
field_offsets.swap(pos->second.field_offsets);
+ base_offsets.swap (pos->second.base_offsets);
+ vbase_offsets.swap (pos->second.vbase_offsets);
m_record_decl_to_layout_map.erase(pos);
success = true;
}
@@ -7140,8 +7739,8 @@ SymbolFileDWARF::LayoutRecordType (const
}
if (log)
- GetObjectFile()->GetModule()->LogMessage (log.get(),
- "SymbolFileDWARF::LayoutRecordType (record_decl = %p, bit_size = %llu, alignment = %llu, field_offsets[%u],base_offsets[%u], vbase_offsets[%u]) success = %i",
+ GetObjectFile()->GetModule()->LogMessage (log,
+ "SymbolFileDWARF::LayoutRecordType (record_decl = %p, bit_size = %" PRIu64 ", alignment = %" PRIu64 ", field_offsets[%u],base_offsets[%u], vbase_offsets[%u]) success = %i",
record_decl,
bit_size,
alignment,
@@ -7153,4 +7752,20 @@ SymbolFileDWARF::LayoutRecordType (const
}
+SymbolFileDWARFDebugMap *
+SymbolFileDWARF::GetDebugMapSymfile ()
+{
+ if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired())
+ {
+ lldb::ModuleSP module_sp (m_debug_map_module_wp.lock());
+ if (module_sp)
+ {
+ SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
+ if (sym_vendor)
+ m_debug_map_symfile = (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile();
+ }
+ }
+ return m_debug_map_symfile;
+}
+
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Thu Jun 6 19:06:43 2013
@@ -13,7 +13,6 @@
// C Includes
// C++ Includes
#include <list>
-#include <memory>
#include <map>
#include <vector>
@@ -22,6 +21,7 @@
#include "clang/AST/ExternalASTSource.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "lldb/lldb-private.h"
#include "lldb/Core/ClangForward.h"
@@ -43,6 +43,7 @@
//----------------------------------------------------------------------
// Forward Declarations for this DWARF plugin
//----------------------------------------------------------------------
+class DebugMapModule;
class DWARFAbbreviationDeclaration;
class DWARFAbbreviationDeclarationSet;
class DWARFileUnit;
@@ -61,8 +62,9 @@ class SymbolFileDWARFDebugMap;
class SymbolFileDWARF : public lldb_private::SymbolFile, public lldb_private::UserID
{
public:
- friend class SymbolFileDWARFDebugMap;
-
+ friend class SymbolFileDWARFDebugMap;
+ friend class DebugMapModule;
+ friend class DWARFCompileUnit;
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
@@ -72,7 +74,7 @@ public:
static void
Terminate();
- static const char *
+ static lldb_private::ConstString
GetPluginNameStatic();
static const char *
@@ -95,6 +97,7 @@ public:
virtual uint32_t GetNumCompileUnits();
virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index);
+ virtual lldb::LanguageType ParseCompileUnitLanguage (const lldb_private::SymbolContext& sc);
virtual size_t ParseCompileUnitFunctions (const lldb_private::SymbolContext& sc);
virtual bool ParseCompileUnitLineTable (const lldb_private::SymbolContext& sc);
virtual bool ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc, lldb_private::FileSpecList& support_files);
@@ -164,26 +167,23 @@ public:
LayoutInfo () :
bit_size(0),
alignment(0),
- field_offsets()//,
- //base_offsets(), // We don't need to fill in the base classes, this can be done automatically
- //vbase_offsets() // We don't need to fill in the virtual base classes, this can be done automatically
+ field_offsets(),
+ base_offsets(),
+ vbase_offsets()
{
}
uint64_t bit_size;
uint64_t alignment;
llvm::DenseMap <const clang::FieldDecl *, uint64_t> field_offsets;
-// llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> base_offsets;
-// llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> vbase_offsets;
+ llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> base_offsets;
+ llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> vbase_offsets;
};
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
- virtual const char *
+ virtual lldb_private::ConstString
GetPluginName();
- virtual const char *
- GetShortPluginName();
-
virtual uint32_t
GetPluginVersion();
@@ -301,7 +301,7 @@ protected:
DISALLOW_COPY_AND_ASSIGN (SymbolFileDWARF);
lldb::CompUnitSP ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx);
- DWARFCompileUnit* GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid);
+ DWARFCompileUnit* GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit);
DWARFCompileUnit* GetNextUnparsedDWARFCompileUnit(DWARFCompileUnit* prev_cu);
lldb_private::CompileUnit* GetCompUnitForDWARFCompUnit(DWARFCompileUnit* dwarf_cu, uint32_t cu_idx = UINT32_MAX);
bool GetFunction (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry* func_die, lldb_private::SymbolContext& sc);
@@ -334,6 +334,10 @@ protected:
class DelayedAddObjCClassProperty;
typedef std::vector <DelayedAddObjCClassProperty> DelayedPropertyList;
+ bool ClassOrStructIsVirtual (
+ DWARFCompileUnit* dwarf_cu,
+ const DWARFDebugInfoEntry *parent_die);
+
size_t ParseChildMembers(
const lldb_private::SymbolContext& sc,
DWARFCompileUnit* dwarf_cu,
@@ -364,6 +368,7 @@ protected:
size_t ParseChildEnumerators(
const lldb_private::SymbolContext& sc,
lldb::clang_type_t enumerator_qual_type,
+ bool is_signed,
uint32_t enumerator_byte_size,
DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *enum_die);
@@ -440,10 +445,13 @@ protected:
void DumpIndexes();
- void SetDebugMapSymfile (SymbolFileDWARFDebugMap *debug_map_symfile)
+ void SetDebugMapModule (const lldb::ModuleSP &module_sp)
{
- m_debug_map_symfile = debug_map_symfile;
+ m_debug_map_module_wp = module_sp;
}
+
+ SymbolFileDWARFDebugMap *
+ GetDebugMapSymfile ();
const DWARFDebugInfoEntry *
FindBlockContainingSpecification (dw_offset_t func_die_offset,
@@ -526,12 +534,18 @@ protected:
const lldb_private::ConstString &selector);
bool
- CopyUniqueClassMethodTypes (lldb_private::Type *class_type,
+ CopyUniqueClassMethodTypes (SymbolFileDWARF *class_symfile,
+ lldb_private::Type *class_type,
DWARFCompileUnit* src_cu,
const DWARFDebugInfoEntry *src_class_die,
DWARFCompileUnit* dst_cu,
- const DWARFDebugInfoEntry *dst_class_die);
+ const DWARFDebugInfoEntry *dst_class_die,
+ llvm::SmallVectorImpl <const DWARFDebugInfoEntry *> &failures);
+
+ bool
+ FixupAddress (lldb_private::Address &addr);
+ lldb::ModuleWP m_debug_map_module_wp;
SymbolFileDWARFDebugMap * m_debug_map_symfile;
clang::TranslationUnitDecl * m_clang_tu_decl;
lldb_private::Flags m_flags;
@@ -549,15 +563,15 @@ protected:
lldb_private::DataExtractor m_data_apple_namespaces;
lldb_private::DataExtractor m_data_apple_objc;
- // The auto_ptr items below are generated on demand if and when someone accesses
+ // The unique pointer items below are generated on demand if and when someone accesses
// them through a non const version of this class.
- std::auto_ptr<DWARFDebugAbbrev> m_abbr;
- std::auto_ptr<DWARFDebugInfo> m_info;
- std::auto_ptr<DWARFDebugLine> m_line;
- std::auto_ptr<DWARFMappedHash::MemoryTable> m_apple_names_ap;
- std::auto_ptr<DWARFMappedHash::MemoryTable> m_apple_types_ap;
- std::auto_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_ap;
- std::auto_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_ap;
+ std::unique_ptr<DWARFDebugAbbrev> m_abbr;
+ std::unique_ptr<DWARFDebugInfo> m_info;
+ std::unique_ptr<DWARFDebugLine> m_line;
+ std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_names_ap;
+ std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_types_ap;
+ std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_ap;
+ std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_ap;
NameToDIE m_function_basename_index; // All concrete functions
NameToDIE m_function_fullname_index; // All concrete functions
NameToDIE m_function_method_index; // All inlined functions
@@ -571,7 +585,7 @@ protected:
m_using_apple_tables:1;
lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
- std::auto_ptr<DWARFDebugRanges> m_ranges;
+ std::unique_ptr<DWARFDebugRanges> m_ranges;
UniqueDWARFASTTypeMap m_unique_ast_type_map;
typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet;
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *> DIEToDeclContextMap;
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp Thu Jun 6 19:06:43 2013
@@ -13,10 +13,17 @@
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/Section.h"
+
+//#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
+#if defined(DEBUG_OSO_DMAP)
#include "lldb/Core/StreamFile.h"
+#endif
#include "lldb/Core/Timer.h"
#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/VariableList.h"
@@ -27,6 +34,223 @@
using namespace lldb;
using namespace lldb_private;
+// Subclass lldb_private::Module so we can intercept the "Module::GetObjectFile()"
+// (so we can fixup the object file sections) and also for "Module::GetSymbolVendor()"
+// (so we can fixup the symbol file id.
+
+
+
+
+const SymbolFileDWARFDebugMap::FileRangeMap &
+SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile)
+{
+ if (file_range_map_valid)
+ return file_range_map;
+
+ file_range_map_valid = true;
+
+ Module *oso_module = exe_symfile->GetModuleByCompUnitInfo (this);
+ if (!oso_module)
+ return file_range_map;
+
+ ObjectFile *oso_objfile = oso_module->GetObjectFile();
+ if (!oso_objfile)
+ return file_range_map;
+
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
+ if (log)
+ {
+ ConstString object_name (oso_module->GetObjectName());
+ log->Printf("%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
+ this,
+ oso_module->GetSpecificationDescription().c_str());
+ }
+
+
+ std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
+ if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos))
+ {
+ for (auto comp_unit_info : cu_infos)
+ {
+ Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
+ ModuleSP oso_module_sp (oso_objfile->GetModule());
+ Symtab *oso_symtab = oso_objfile->GetSymtab();
+
+ ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
+ //SectionList *oso_sections = oso_objfile->Sections();
+ // Now we need to make sections that map from zero based object
+ // file addresses to where things eneded up in the main executable.
+
+ assert (comp_unit_info->first_symbol_index != UINT32_MAX);
+ // End index is one past the last valid symbol index
+ const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
+ for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO
+ idx < oso_end_idx;
+ ++idx)
+ {
+ Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
+ if (exe_symbol)
+ {
+ if (exe_symbol->IsDebug() == false)
+ continue;
+
+ switch (exe_symbol->GetType())
+ {
+ default:
+ break;
+
+ case eSymbolTypeCode:
+ {
+ // For each N_FUN, or function that we run into in the debug map
+ // we make a new section that we add to the sections found in the
+ // .o file. This new section has the file address set to what the
+ // addresses are in the .o file, and the load address is adjusted
+ // to match where it ended up in the final executable! We do this
+ // before we parse any dwarf info so that when it goes get parsed
+ // all section/offset addresses that get registered will resolve
+ // correctly to the new addresses in the main executable.
+
+ // First we find the original symbol in the .o file's symbol table
+ Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(Mangled::ePreferMangled),
+ eSymbolTypeCode,
+ Symtab::eDebugNo,
+ Symtab::eVisibilityAny);
+ if (oso_fun_symbol)
+ {
+ // Add the inverse OSO file address to debug map entry mapping
+ exe_symfile->AddOSOFileRange (this,
+ exe_symbol->GetAddress().GetFileAddress(),
+ oso_fun_symbol->GetAddress().GetFileAddress(),
+ std::min<addr_t>(exe_symbol->GetByteSize(), oso_fun_symbol->GetByteSize()));
+
+ }
+ }
+ break;
+
+ case eSymbolTypeData:
+ {
+ // For each N_GSYM we remap the address for the global by making
+ // a new section that we add to the sections found in the .o file.
+ // This new section has the file address set to what the
+ // addresses are in the .o file, and the load address is adjusted
+ // to match where it ended up in the final executable! We do this
+ // before we parse any dwarf info so that when it goes get parsed
+ // all section/offset addresses that get registered will resolve
+ // correctly to the new addresses in the main executable. We
+ // initially set the section size to be 1 byte, but will need to
+ // fix up these addresses further after all globals have been
+ // parsed to span the gaps, or we can find the global variable
+ // sizes from the DWARF info as we are parsing.
+
+ // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
+ Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(Mangled::ePreferMangled),
+ eSymbolTypeData,
+ Symtab::eDebugNo,
+ Symtab::eVisibilityAny);
+
+ if (exe_symbol && oso_gsym_symbol &&
+ exe_symbol->ValueIsAddress() &&
+ oso_gsym_symbol->ValueIsAddress())
+ {
+ // Add the inverse OSO file address to debug map entry mapping
+ exe_symfile->AddOSOFileRange (this,
+ exe_symbol->GetAddress().GetFileAddress(),
+ oso_gsym_symbol->GetAddress().GetFileAddress(),
+ std::min<addr_t>(exe_symbol->GetByteSize(), oso_gsym_symbol->GetByteSize()));
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ exe_symfile->FinalizeOSOFileRanges (this);
+ // We don't need the symbols anymore for the .o files
+ oso_objfile->ClearSymtab();
+ }
+ }
+ return file_range_map;
+}
+
+
+class DebugMapModule : public Module
+{
+public:
+ DebugMapModule (const ModuleSP &exe_module_sp,
+ uint32_t cu_idx,
+ const FileSpec& file_spec,
+ const ArchSpec& arch,
+ const ConstString *object_name,
+ off_t object_offset,
+ const TimeValue *object_mod_time_ptr) :
+ Module (file_spec, arch, object_name, object_offset, object_mod_time_ptr),
+ m_exe_module_wp (exe_module_sp),
+ m_cu_idx (cu_idx)
+ {
+ }
+
+ virtual
+ ~DebugMapModule ()
+ {
+ }
+
+
+ virtual SymbolVendor*
+ GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL)
+ {
+ // Scope for locker
+ if (m_symfile_ap.get() || can_create == false)
+ return m_symfile_ap.get();
+
+ ModuleSP exe_module_sp (m_exe_module_wp.lock());
+ if (exe_module_sp)
+ {
+ // Now get the object file outside of a locking scope
+ ObjectFile *oso_objfile = GetObjectFile ();
+ if (oso_objfile)
+ {
+ Mutex::Locker locker (m_mutex);
+ SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create, feedback_strm);
+ if (symbol_vendor)
+ {
+ // Set a a pointer to this class to set our OSO DWARF file know
+ // that the DWARF is being used along with a debug map and that
+ // it will have the remapped sections that we do below.
+ SymbolFileDWARF *oso_symfile = SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(symbol_vendor->GetSymbolFile());
+
+ if (!oso_symfile)
+ return NULL;
+
+ ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
+ SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
+
+ if (exe_objfile && exe_sym_vendor)
+ {
+ if (oso_symfile->GetNumCompileUnits() == 1)
+ {
+ oso_symfile->SetDebugMapModule(exe_module_sp);
+ // Set the ID of the symbol file DWARF to the index of the OSO
+ // shifted left by 32 bits to provide a unique prefix for any
+ // UserID's that get created in the symbol file.
+ oso_symfile->SetID (((uint64_t)m_cu_idx + 1ull) << 32ull);
+ }
+ else
+ {
+ oso_symfile->SetID (UINT64_MAX);
+ }
+ }
+ return symbol_vendor;
+ }
+ }
+ }
+ return NULL;
+ }
+
+protected:
+ ModuleWP m_exe_module_wp;
+ const uint32_t m_cu_idx;
+};
+
void
SymbolFileDWARFDebugMap::Initialize()
{
@@ -42,10 +266,11 @@ SymbolFileDWARFDebugMap::Terminate()
}
-const char *
+lldb_private::ConstString
SymbolFileDWARFDebugMap::GetPluginNameStatic()
{
- return "dwarf-debugmap";
+ static ConstString g_name("dwarf-debugmap");
+ return g_name;
}
const char *
@@ -90,14 +315,12 @@ SymbolFileDWARFDebugMap::InitializeObjec
GetClangASTContext().SetExternalSource (ast_source_ap);
}
-
-
void
-SymbolFileDWARFDebugMap::InitOSO ()
+SymbolFileDWARFDebugMap::InitOSO()
{
if (m_flags.test(kHaveInitializedOSOs))
return;
-
+
m_flags.set(kHaveInitializedOSOs);
// In order to get the abilities of this plug-in, we look at the list of
// N_OSO entries (object files) from the symbol table and make sure that
@@ -107,12 +330,9 @@ SymbolFileDWARFDebugMap::InitOSO ()
Symtab* symtab = m_obj_file->GetSymtab();
if (symtab)
{
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
+ Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
std::vector<uint32_t> oso_indexes;
-// StreamFile s(stdout);
-// symtab->Dump(&s, NULL, eSortOrderNone);
-
// When a mach-o symbol is encoded, the n_type field is encoded in bits
// 23:16, and the n_desc field is encoded in bits 15:0.
//
@@ -132,30 +352,70 @@ SymbolFileDWARFDebugMap::InitOSO ()
symtab->SortSymbolIndexesByValue(m_func_indexes, true);
symtab->SortSymbolIndexesByValue(m_glob_indexes, true);
+ for (uint32_t sym_idx : m_func_indexes)
+ {
+ const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
+ lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress();
+ lldb::addr_t byte_size = symbol->GetByteSize();
+ DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
+ m_debug_map.Append(debug_map_entry);
+ }
+ for (uint32_t sym_idx : m_glob_indexes)
+ {
+ const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
+ lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress();
+ lldb::addr_t byte_size = symbol->GetByteSize();
+ DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
+ m_debug_map.Append(debug_map_entry);
+ }
+ m_debug_map.Sort();
+
m_compile_unit_infos.resize(oso_index_count);
-// s.Printf("%s N_OSO symbols:\n", __PRETTY_FUNCTION__);
-// symtab->Dump(&s, oso_indexes);
for (uint32_t i=0; i<oso_index_count; ++i)
{
- m_compile_unit_infos[i].so_symbol = symtab->SymbolAtIndex(oso_indexes[i] - 1);
- if (m_compile_unit_infos[i].so_symbol->GetSiblingIndex() == 0)
- m_compile_unit_infos[i].so_symbol = symtab->SymbolAtIndex(oso_indexes[i] - 2);
- m_compile_unit_infos[i].oso_symbol = symtab->SymbolAtIndex(oso_indexes[i]);
- uint32_t sibling_idx = m_compile_unit_infos[i].so_symbol->GetSiblingIndex();
- // The sibling index can't be less that or equal to the current index "i"
- if (sibling_idx <= i)
+ const uint32_t so_idx = oso_indexes[i] - 1;
+ const uint32_t oso_idx = oso_indexes[i];
+ const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
+ const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
+ if (so_symbol &&
+ oso_symbol &&
+ so_symbol->GetType() == eSymbolTypeSourceFile &&
+ oso_symbol->GetType() == eSymbolTypeObjectFile)
{
- m_obj_file->GetModule()->ReportError ("N_SO in symbol with UID %u has invalid sibling in debug map, please file a bug and attach the binary listed in this error", m_compile_unit_infos[i].so_symbol->GetID());
+ m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), false);
+ m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
+ TimeValue oso_mod_time;
+ oso_mod_time.OffsetWithSeconds(oso_symbol->GetAddress().GetOffset());
+ m_compile_unit_infos[i].oso_mod_time = oso_mod_time;
+ uint32_t sibling_idx = so_symbol->GetSiblingIndex();
+ // The sibling index can't be less that or equal to the current index "i"
+ if (sibling_idx <= i)
+ {
+ m_obj_file->GetModule()->ReportError ("N_SO in symbol with UID %u has invalid sibling in debug map, please file a bug and attach the binary listed in this error", so_symbol->GetID());
+ }
+ else
+ {
+ const Symbol* last_symbol = symtab->SymbolAtIndex (sibling_idx - 1);
+ m_compile_unit_infos[i].first_symbol_index = so_idx;
+ m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
+ m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
+ m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
+
+ if (log)
+ log->Printf("Initialized OSO 0x%8.8x: file=%s", i, oso_symbol->GetName().GetCString());
+ }
}
else
{
- m_compile_unit_infos[i].last_symbol = symtab->SymbolAtIndex (sibling_idx - 1);
- m_compile_unit_infos[i].first_symbol_index = symtab->GetIndexForSymbol(m_compile_unit_infos[i].so_symbol);
- m_compile_unit_infos[i].last_symbol_index = symtab->GetIndexForSymbol(m_compile_unit_infos[i].last_symbol);
-
- if (log)
- log->Printf("Initialized OSO 0x%8.8x: file=%s", i, m_compile_unit_infos[i].oso_symbol->GetName().GetCString());
+ if (oso_symbol == NULL)
+ m_obj_file->GetModule()->ReportError ("N_OSO symbol[%u] can't be found, please file a bug and attach the binary listed in this error", oso_idx);
+ else if (so_symbol == NULL)
+ m_obj_file->GetModule()->ReportError ("N_SO not found for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_idx);
+ else if (so_symbol->GetType() != eSymbolTypeSourceFile)
+ m_obj_file->GetModule()->ReportError ("N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", so_symbol->GetType(), oso_idx);
+ else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
+ m_obj_file->GetModule()->ReportError ("N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_symbol->GetType(), oso_idx);
}
}
}
@@ -174,23 +434,62 @@ SymbolFileDWARFDebugMap::GetModuleByOSOI
Module *
SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info)
{
- if (comp_unit_info->oso_module_sp.get() == NULL && comp_unit_info->symbol_file_supported)
+ if (!comp_unit_info->oso_sp)
{
- Symbol *oso_symbol = comp_unit_info->oso_symbol;
- if (oso_symbol)
+ auto pos = m_oso_map.find (comp_unit_info->oso_path);
+ if (pos != m_oso_map.end())
+ {
+ comp_unit_info->oso_sp = pos->second;
+ }
+ else
{
- FileSpec oso_file_spec(oso_symbol->GetMangled().GetName().AsCString(), true);
+ ObjectFile *obj_file = GetObjectFile();
+ comp_unit_info->oso_sp.reset (new OSOInfo());
+ m_oso_map[comp_unit_info->oso_path] = comp_unit_info->oso_sp;
+ const char *oso_path = comp_unit_info->oso_path.GetCString();
+ FileSpec oso_file (oso_path, false);
+ ConstString oso_object;
+ if (oso_file.Exists())
+ {
+ TimeValue oso_mod_time (oso_file.GetModificationTime());
+ if (oso_mod_time != comp_unit_info->oso_mod_time)
+ {
+ obj_file->GetModule()->ReportError ("debug map object file '%s' has changed (actual time is 0x%" PRIx64 ", debug map time is 0x%" PRIx64 ") since this executable was linked, file will be ignored",
+ oso_file.GetPath().c_str(),
+ oso_mod_time.GetAsSecondsSinceJan1_1970(),
+ comp_unit_info->oso_mod_time.GetAsSecondsSinceJan1_1970());
+ return NULL;
+ }
+
+ }
+ else
+ {
+ const bool must_exist = true;
+
+ if (!ObjectFile::SplitArchivePathWithObject (oso_path,
+ oso_file,
+ oso_object,
+ must_exist))
+ {
+ return NULL;
+ }
+ }
// Always create a new module for .o files. Why? Because we
// use the debug map, to add new sections to each .o file and
// even though a .o file might not have changed, the sections
// that get added to the .o file can change.
- comp_unit_info->oso_module_sp.reset (new Module (oso_file_spec,
- m_obj_file->GetModule()->GetArchitecture(),
- NULL,
- 0));
+ comp_unit_info->oso_sp->module_sp.reset (new DebugMapModule (obj_file->GetModule(),
+ GetCompUnitInfoIndex(comp_unit_info),
+ oso_file,
+ m_obj_file->GetModule()->GetArchitecture(),
+ oso_object ? &oso_object : NULL,
+ 0,
+ oso_object ? &comp_unit_info->oso_mod_time : NULL));
}
}
- return comp_unit_info->oso_module_sp.get();
+ if (comp_unit_info->oso_sp)
+ return comp_unit_info->oso_sp->module_sp.get();
+ return NULL;
}
@@ -199,19 +498,11 @@ SymbolFileDWARFDebugMap::GetFileSpecForS
{
if (oso_idx < m_compile_unit_infos.size())
{
- if (!m_compile_unit_infos[oso_idx].so_file)
+ if (m_compile_unit_infos[oso_idx].so_file)
{
-
- if (m_compile_unit_infos[oso_idx].so_symbol == NULL)
- return false;
-
- std::string so_path (m_compile_unit_infos[oso_idx].so_symbol->GetMangled().GetName().AsCString());
- if (m_compile_unit_infos[oso_idx].so_symbol[1].GetType() == eSymbolTypeSourceFile)
- so_path += m_compile_unit_infos[oso_idx].so_symbol[1].GetMangled().GetName().AsCString();
- m_compile_unit_infos[oso_idx].so_file.SetFile(so_path.c_str(), true);
+ file_spec = m_compile_unit_infos[oso_idx].so_file;
+ return true;
}
- file_spec = m_compile_unit_infos[oso_idx].so_file;
- return true;
}
return false;
}
@@ -268,184 +559,23 @@ SymbolFileDWARFDebugMap::GetSymbolFileBy
}
SymbolFileDWARF *
+SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file)
+{
+ if (sym_file && sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic())
+ return (SymbolFileDWARF *)sym_file;
+ return NULL;
+}
+
+SymbolFileDWARF *
SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
{
- if (comp_unit_info->oso_symbol_vendor == NULL && comp_unit_info->symbol_file_supported)
+ Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
+ if (oso_module)
{
- ObjectFile *oso_objfile = GetObjectFileByCompUnitInfo (comp_unit_info);
-
- if (oso_objfile)
- {
- comp_unit_info->oso_symbol_vendor = oso_objfile->GetModule()->GetSymbolVendor();
-// SymbolFileDWARF *oso_dwarf = new SymbolFileDWARF(oso_objfile);
-// comp_unit_info->oso_dwarf_sp.reset (oso_dwarf);
- if (comp_unit_info->oso_symbol_vendor)
- {
- // Set a a pointer to this class to set our OSO DWARF file know
- // that the DWARF is being used along with a debug map and that
- // it will have the remapped sections that we do below.
- SymbolFileDWARF *oso_symfile = (SymbolFileDWARF *)comp_unit_info->oso_symbol_vendor->GetSymbolFile();
-
- if (!oso_symfile)
- return NULL;
-
- if (oso_symfile->GetNumCompileUnits() != 1)
- {
- oso_symfile->GetObjectFile()->GetModule()->ReportError ("DWARF for object file '%s' contains multiple translation units!",
- oso_symfile->GetObjectFile()->GetFileSpec().GetFilename().AsCString());
- comp_unit_info->symbol_file_supported = false;
- comp_unit_info->oso_module_sp.reset();
- comp_unit_info->oso_compile_unit_sp.reset();
- comp_unit_info->oso_symbol_vendor = NULL;
- return NULL;
- }
-
- oso_symfile->SetDebugMapSymfile(this);
- // Set the ID of the symbol file DWARF to the index of the OSO
- // shifted left by 32 bits to provide a unique prefix for any
- // UserID's that get created in the symbol file.
- oso_symfile->SetID (((uint64_t)GetCompUnitInfoIndex(comp_unit_info) + 1ull) << 32ull);
- comp_unit_info->debug_map_sections_sp.reset(new SectionList);
-
- Symtab *exe_symtab = m_obj_file->GetSymtab();
- ModuleSP oso_module_sp (oso_objfile->GetModule());
- Symtab *oso_symtab = oso_objfile->GetSymtab();
-//#define DEBUG_OSO_DMAP // Do not check in with this defined...
-#if defined(DEBUG_OSO_DMAP)
- StreamFile s(stdout);
- s << "OSO symtab:\n";
- oso_symtab->Dump(&s, NULL);
- s << "OSO sections before:\n";
- oso_objfile->GetSectionList()->Dump(&s, NULL, true);
-#endif
-
- ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
- //SectionList *oso_sections = oso_objfile->Sections();
- // Now we need to make sections that map from zero based object
- // file addresses to where things eneded up in the main executable.
- uint32_t oso_start_idx = exe_symtab->GetIndexForSymbol (comp_unit_info->oso_symbol);
- assert (oso_start_idx != UINT32_MAX);
- oso_start_idx += 1;
- const uint32_t oso_end_idx = comp_unit_info->so_symbol->GetSiblingIndex();
- uint32_t sect_id = 0x10000;
- for (uint32_t idx = oso_start_idx; idx < oso_end_idx; ++idx)
- {
- Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
- if (exe_symbol)
- {
- if (exe_symbol->IsDebug() == false)
- continue;
-
- switch (exe_symbol->GetType())
- {
- default:
- break;
-
- case eSymbolTypeCode:
- {
- // For each N_FUN, or function that we run into in the debug map
- // we make a new section that we add to the sections found in the
- // .o file. This new section has the file address set to what the
- // addresses are in the .o file, and the load address is adjusted
- // to match where it ended up in the final executable! We do this
- // before we parse any dwarf info so that when it goes get parsed
- // all section/offset addresses that get registered will resolve
- // correctly to the new addresses in the main executable.
-
- // First we find the original symbol in the .o file's symbol table
- Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny);
- if (oso_fun_symbol)
- {
- // If we found the symbol, then we
- SectionSP exe_fun_section (exe_symbol->GetAddress().GetSection());
- SectionSP oso_fun_section (oso_fun_symbol->GetAddress().GetSection());
- if (oso_fun_section)
- {
- // Now we create a section that we will add as a child of the
- // section in which the .o symbol (the N_FUN) exists.
-
- // We use the exe_symbol size because the one in the .o file
- // will just be a symbol with no size, and the exe_symbol
- // size will reflect any size changes (ppc has been known to
- // shrink function sizes when it gets rid of jump islands that
- // aren't needed anymore).
- SectionSP oso_fun_section_sp (new Section (oso_fun_symbol->GetAddress().GetSection(),
- oso_module_sp, // Module (the .o file)
- sect_id++, // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs
- exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated!
- eSectionTypeDebug,
- oso_fun_symbol->GetAddress().GetOffset(), // File VM address offset in the current section
- exe_symbol->GetByteSize(), // File size (we need the size from the executable)
- 0, 0, 0));
-
- oso_fun_section_sp->SetLinkedLocation (exe_fun_section,
- exe_symbol->GetAddress().GetFileAddress() - exe_fun_section->GetFileAddress());
- oso_fun_section->GetChildren().AddSection(oso_fun_section_sp);
- comp_unit_info->debug_map_sections_sp->AddSection(oso_fun_section_sp);
- }
- }
- }
- break;
-
- case eSymbolTypeData:
- {
- // For each N_GSYM we remap the address for the global by making
- // a new section that we add to the sections found in the .o file.
- // This new section has the file address set to what the
- // addresses are in the .o file, and the load address is adjusted
- // to match where it ended up in the final executable! We do this
- // before we parse any dwarf info so that when it goes get parsed
- // all section/offset addresses that get registered will resolve
- // correctly to the new addresses in the main executable. We
- // initially set the section size to be 1 byte, but will need to
- // fix up these addresses further after all globals have been
- // parsed to span the gaps, or we can find the global variable
- // sizes from the DWARF info as we are parsing.
-
- // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
- Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(),
- eSymbolTypeData,
- Symtab::eDebugNo,
- Symtab::eVisibilityAny);
-
- if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() && oso_gsym_symbol->ValueIsAddress())
- {
- // If we found the symbol, then we
- SectionSP exe_gsym_section (exe_symbol->GetAddress().GetSection());
- SectionSP oso_gsym_section (oso_gsym_symbol->GetAddress().GetSection());
- if (oso_gsym_section)
- {
- SectionSP oso_gsym_section_sp (new Section (oso_gsym_symbol->GetAddress().GetSection(),
- oso_module_sp, // Module (the .o file)
- sect_id++, // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs
- exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated!
- eSectionTypeDebug,
- oso_gsym_symbol->GetAddress().GetOffset(), // File VM address offset in the current section
- 1, // We don't know the size of the global, just do the main address for now.
- 0, 0, 0));
-
- oso_gsym_section_sp->SetLinkedLocation (exe_gsym_section,
- exe_symbol->GetAddress().GetFileAddress() - exe_gsym_section->GetFileAddress());
- oso_gsym_section->GetChildren().AddSection(oso_gsym_section_sp);
- comp_unit_info->debug_map_sections_sp->AddSection(oso_gsym_section_sp);
- }
- }
- }
- break;
- }
- }
- }
- oso_objfile->GetSectionList()->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
- comp_unit_info->debug_map_sections_sp->Finalize();
-#if defined(DEBUG_OSO_DMAP)
- s << "OSO sections after:\n";
- oso_objfile->GetSectionList()->Dump(&s, NULL, true);
-#endif
- }
- }
+ SymbolVendor *sym_vendor = oso_module->GetSymbolVendor();
+ if (sym_vendor)
+ return GetSymbolFileAsSymbolFileDWARF (sym_vendor->GetSymbolFile());
}
- if (comp_unit_info->oso_symbol_vendor)
- return (SymbolFileDWARF *)comp_unit_info->oso_symbol_vendor->GetSymbolFile();
return NULL;
}
@@ -468,16 +598,19 @@ SymbolFileDWARFDebugMap::CalculateAbilit
SymbolFile::VariableTypes |
SymbolFile::LineTables;
- for (uint32_t oso_idx=0; oso_idx<oso_index_count; ++oso_idx)
- {
- SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
- if (oso_dwarf)
- {
- uint32_t oso_abilities = oso_dwarf->GetAbilities();
- if ((oso_abilities & dwarf_abilities) == dwarf_abilities)
- return oso_abilities;
- }
- }
+ InitOSO();
+ if (!m_compile_unit_infos.empty())
+ return dwarf_abilities;
+// for (uint32_t oso_idx=0; oso_idx<oso_index_count; ++oso_idx)
+// {
+// SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
+// if (oso_dwarf)
+// {
+// uint32_t oso_abilities = oso_dwarf->GetAbilities();
+// if ((oso_abilities & dwarf_abilities) == dwarf_abilities)
+// return oso_abilities;
+// }
+// }
}
return 0;
}
@@ -498,40 +631,30 @@ SymbolFileDWARFDebugMap::ParseCompileUni
if (cu_idx < cu_count)
{
- if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == NULL &&
- m_compile_unit_infos[cu_idx].symbol_file_supported)
+ Module *oso_module = GetModuleByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
+ if (oso_module)
{
- SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (cu_idx);
- if (oso_dwarf)
- {
- // There is only one compile unit for N_OSO entry right now, so
- // it will always exist at index zero.
- m_compile_unit_infos[cu_idx].oso_compile_unit_sp = m_compile_unit_infos[cu_idx].oso_symbol_vendor->GetCompileUnitAtIndex (0);
- }
-
- if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == NULL)
+ FileSpec so_file_spec;
+ if (GetFileSpecForSO (cu_idx, so_file_spec))
{
- // We weren't able to get the DWARF for this N_OSO entry (the
- // .o file may be missing or not at the specified path), make
- // one up as best we can from the debug map. We set the uid
- // of the compile unit to the symbol index with the MSBit set
- // so that it doesn't collide with any uid values from the DWARF
- Symbol *so_symbol = m_compile_unit_infos[cu_idx].so_symbol;
- if (so_symbol)
+ // User zero as the ID to match the compile unit at offset
+ // zero in each .o file since each .o file can only have
+ // one compile unit for now.
+ lldb::user_id_t cu_id = 0;
+ m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
+ NULL,
+ so_file_spec,
+ cu_id,
+ eLanguageTypeUnknown));
+
+ if (m_compile_unit_infos[cu_idx].compile_unit_sp)
{
- m_compile_unit_infos[cu_idx].oso_compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
- NULL,
- so_symbol->GetMangled().GetName().AsCString(),
- cu_idx,
- eLanguageTypeUnknown));
-
// Let our symbol vendor know about this compile unit
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx,
- m_compile_unit_infos[cu_idx].oso_compile_unit_sp);
+ m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp);
}
}
}
- comp_unit_sp = m_compile_unit_infos[cu_idx].oso_compile_unit_sp;
+ comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp;
}
return comp_unit_sp;
@@ -543,12 +666,34 @@ SymbolFileDWARFDebugMap::GetCompUnitInfo
const uint32_t cu_count = GetNumCompileUnits();
for (uint32_t i=0; i<cu_count; ++i)
{
- if (sc.comp_unit == m_compile_unit_infos[i].oso_compile_unit_sp.get())
+ if (sc.comp_unit == m_compile_unit_infos[i].compile_unit_sp.get())
return &m_compile_unit_infos[i];
}
return NULL;
}
+
+size_t
+SymbolFileDWARFDebugMap::GetCompUnitInfosForModule (const lldb_private::Module *module, std::vector<CompileUnitInfo *>& cu_infos)
+{
+ const uint32_t cu_count = GetNumCompileUnits();
+ for (uint32_t i=0; i<cu_count; ++i)
+ {
+ if (module == GetModuleByCompUnitInfo (&m_compile_unit_infos[i]))
+ cu_infos.push_back (&m_compile_unit_infos[i]);
+ }
+ return cu_infos.size();
+}
+
+lldb::LanguageType
+SymbolFileDWARFDebugMap::ParseCompileUnitLanguage (const SymbolContext& sc)
+{
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseCompileUnitLanguage (sc);
+ return eLanguageTypeUnknown;
+}
+
size_t
SymbolFileDWARFDebugMap::ParseCompileUnitFunctions (const SymbolContext& sc)
{
@@ -602,7 +747,7 @@ SymbolFileDWARFDebugMap::ParseVariablesF
{
SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
if (oso_dwarf)
- return oso_dwarf->ParseTypes (sc);
+ return oso_dwarf->ParseVariablesForContext (sc);
return 0;
}
@@ -614,7 +759,7 @@ SymbolFileDWARFDebugMap::ResolveTypeUID(
const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
if (oso_dwarf)
- oso_dwarf->ResolveTypeUID (type_uid);
+ return oso_dwarf->ResolveTypeUID (type_uid);
return NULL;
}
@@ -633,30 +778,31 @@ SymbolFileDWARFDebugMap::ResolveSymbolCo
if (symtab)
{
const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
- sc.symbol = symtab->FindSymbolContainingFileAddress (exe_file_addr, &m_func_indexes[0], m_func_indexes.size());
- if (sc.symbol != NULL)
+ const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains (exe_file_addr);
+ if (debug_map_entry)
{
- resolved_flags |= eSymbolContextSymbol;
- uint32_t oso_idx = 0;
- CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx);
- if (comp_unit_info)
- {
- SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
- ObjectFile *oso_objfile = GetObjectFileByOSOIndex (oso_idx);
- if (oso_dwarf && oso_objfile)
- {
- SectionList *oso_section_list = oso_objfile->GetSectionList();
+ sc.symbol = symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
- SectionSP oso_symbol_section_sp (oso_section_list->FindSectionContainingLinkedFileAddress (exe_file_addr, UINT32_MAX));
+ if (sc.symbol != NULL)
+ {
+ resolved_flags |= eSymbolContextSymbol;
- if (oso_symbol_section_sp)
+ uint32_t oso_idx = 0;
+ CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx);
+ if (comp_unit_info)
+ {
+ comp_unit_info->GetFileRangeMap(this);
+ Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
+ if (oso_module)
{
- const addr_t linked_file_addr = oso_symbol_section_sp->GetLinkedFileAddress();
- Address oso_so_addr (oso_symbol_section_sp, exe_file_addr - linked_file_addr);
- if (oso_so_addr.IsSectionOffset())
- resolved_flags |= oso_dwarf->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
+ lldb::addr_t oso_file_addr = exe_file_addr - debug_map_entry->GetRangeBase() + debug_map_entry->data.GetOSOFileAddress();
+ Address oso_so_addr;
+ if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr))
+ {
+ resolved_flags |= oso_module->GetSymbolVendor()->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
+ }
}
}
}
@@ -669,24 +815,31 @@ SymbolFileDWARFDebugMap::ResolveSymbolCo
uint32_t
SymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
{
- uint32_t initial = sc_list.GetSize();
+ const uint32_t initial = sc_list.GetSize();
const uint32_t cu_count = GetNumCompileUnits();
- FileSpec so_file_spec;
for (uint32_t i=0; i<cu_count; ++i)
{
- if (GetFileSpecForSO (i, so_file_spec))
+ // If we are checking for inlines, then we need to look through all
+ // compile units no matter if "file_spec" matches.
+ bool resolve = check_inlines;
+
+ if (!resolve)
{
- // By passing false to the comparison we will be able to match
- // and files given a filename only. If both file_spec and
- // so_file_spec have directories, we will still do a full match.
- if (FileSpec::Compare (file_spec, so_file_spec, false) == 0)
+ FileSpec so_file_spec;
+ if (GetFileSpecForSO (i, so_file_spec))
{
- SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i);
- if (oso_dwarf)
- oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
+ // Match the full path if the incoming file_spec has a directory (not just a basename)
+ const bool full_match = file_spec.GetDirectory();
+ resolve = FileSpec::Equal (file_spec, so_file_spec, full_match);
}
}
+ if (resolve)
+ {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i);
+ if (oso_dwarf)
+ oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
+ }
}
return sc_list.GetSize() - initial;
}
@@ -825,10 +978,10 @@ SymbolFileDWARFDebugMap::SymbolContainsS
{
const user_id_t symbol_id = *symbol_idx_ptr;
- if (symbol_id < comp_unit_info->so_symbol->GetID())
+ if (symbol_id < comp_unit_info->first_symbol_id)
return -1;
- if (symbol_id <= comp_unit_info->last_symbol->GetID())
+ if (symbol_id <= comp_unit_info->last_symbol_id)
return 0;
return 1;
@@ -1095,15 +1248,9 @@ SymbolFileDWARFDebugMap::FindNamespace (
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-const char *
+lldb_private::ConstString
SymbolFileDWARFDebugMap::GetPluginName()
{
- return "SymbolFileDWARFDebugMap";
-}
-
-const char *
-SymbolFileDWARFDebugMap::GetShortPluginName()
-{
return GetPluginNameStatic();
}
@@ -1113,23 +1260,67 @@ SymbolFileDWARFDebugMap::GetPluginVersio
return 1;
}
-void
-SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp)
+lldb::CompUnitSP
+SymbolFileDWARFDebugMap::GetCompileUnit (SymbolFileDWARF *oso_dwarf)
{
- const uint32_t cu_count = GetNumCompileUnits();
- for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
+ if (oso_dwarf)
{
- if (m_compile_unit_infos[cu_idx].oso_symbol_vendor &&
- m_compile_unit_infos[cu_idx].oso_symbol_vendor->GetSymbolFile() == oso_dwarf)
+ const uint32_t cu_count = GetNumCompileUnits();
+ for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
{
- if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp)
+ SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
+ if (oso_symfile == oso_dwarf)
{
- assert (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == cu_sp.get());
+ if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
+ m_compile_unit_infos[cu_idx].compile_unit_sp = ParseCompileUnitAtIndex (cu_idx);
+
+ return m_compile_unit_infos[cu_idx].compile_unit_sp;
}
- else
+ }
+ }
+ assert(!"this shouldn't happen");
+ return lldb::CompUnitSP();
+}
+
+SymbolFileDWARFDebugMap::CompileUnitInfo *
+SymbolFileDWARFDebugMap::GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf)
+{
+ if (oso_dwarf)
+ {
+ const uint32_t cu_count = GetNumCompileUnits();
+ for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
+ {
+ SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
+ if (oso_symfile == oso_dwarf)
{
- m_compile_unit_infos[cu_idx].oso_compile_unit_sp = cu_sp;
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
+ return &m_compile_unit_infos[cu_idx];
+ }
+ }
+ }
+ return NULL;
+}
+
+
+void
+SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp)
+{
+ if (oso_dwarf)
+ {
+ const uint32_t cu_count = GetNumCompileUnits();
+ for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
+ {
+ SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
+ if (oso_symfile == oso_dwarf)
+ {
+ if (m_compile_unit_infos[cu_idx].compile_unit_sp)
+ {
+ assert (m_compile_unit_infos[cu_idx].compile_unit_sp.get() == cu_sp.get());
+ }
+ else
+ {
+ m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp;
+ m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
+ }
}
}
}
@@ -1217,4 +1408,101 @@ SymbolFileDWARFDebugMap::GetClangDeclCon
return NULL;
}
+bool
+SymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info,
+ lldb::addr_t exe_file_addr,
+ lldb::addr_t oso_file_addr,
+ lldb::addr_t oso_byte_size)
+{
+ assert (cu_info);// REMOVE THIS PRIOR TO CHECKIN
+ const uint32_t debug_map_idx = m_debug_map.FindEntryIndexThatContains(exe_file_addr);
+ if (debug_map_idx != UINT32_MAX)
+ {
+ DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(exe_file_addr);
+ assert (debug_map_entry);// REMOVE THIS PRIOR TO CHECKIN
+ debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
+ cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, oso_byte_size, exe_file_addr));
+ return true;
+ }
+ return false;
+}
+
+void
+SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (CompileUnitInfo *cu_info)
+{
+ cu_info->file_range_map.Sort();
+#if defined(DEBUG_OSO_DMAP)
+ const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this);
+ const size_t n = oso_file_range_map.GetSize();
+ printf ("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n",
+ cu_info,
+ cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str());
+ for (size_t i=0; i<n; ++i)
+ {
+ const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i);
+ printf ("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n",
+ entry.GetRangeBase(), entry.GetRangeEnd(),
+ entry.data, entry.data + entry.GetByteSize());
+ }
+#endif
+}
+
+lldb::addr_t
+SymbolFileDWARFDebugMap::LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr)
+{
+ CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_symfile);
+ if (cu_info)
+ {
+ const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
+ if (oso_range_entry)
+ {
+ const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
+ if (debug_map_entry)
+ {
+ const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
+ const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
+ return exe_file_addr;
+ }
+ }
+ }
+ return LLDB_INVALID_ADDRESS;
+}
+
+bool
+SymbolFileDWARFDebugMap::LinkOSOAddress (Address &addr)
+{
+ // Make sure this address hasn't been fixed already
+ Module *exe_module = GetObjectFile()->GetModule().get();
+ Module *addr_module = addr.GetModule().get();
+ if (addr_module == exe_module)
+ return true; // Address is already in terms of the main executable module
+
+ CompileUnitInfo *cu_info = GetCompileUnitInfo (GetSymbolFileAsSymbolFileDWARF(addr_module->GetSymbolVendor()->GetSymbolFile()));
+ if (cu_info)
+ {
+ const lldb::addr_t oso_file_addr = addr.GetFileAddress();
+ const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
+ if (oso_range_entry)
+ {
+ const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
+ if (debug_map_entry)
+ {
+ const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
+ const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
+ return exe_module->ResolveFileAddress(exe_file_addr, addr);
+ }
+ }
+ }
+ return true;
+}
+
+LineTable *
+SymbolFileDWARFDebugMap::LinkOSOLineTable (SymbolFileDWARF *oso_dwarf, LineTable *line_table)
+{
+ CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_dwarf);
+ if (cu_info)
+ return line_table->LinkLineTable(cu_info->GetFileRangeMap(this));
+ return NULL;
+}
+
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h Thu Jun 6 19:06:43 2013
@@ -16,6 +16,7 @@
#include "clang/AST/CharUnits.h"
+#include "lldb/Core/RangeMap.h"
#include "lldb/Symbol/SymbolFile.h"
#include "UniqueDWARFASTType.h"
@@ -24,10 +25,12 @@ class SymbolFileDWARF;
class DWARFCompileUnit;
class DWARFDebugInfoEntry;
class DWARFDeclContext;
+class DebugMapModule;
class SymbolFileDWARFDebugMap : public lldb_private::SymbolFile
{
public:
+
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
@@ -37,7 +40,7 @@ public:
static void
Terminate();
- static const char *
+ static lldb_private::ConstString
GetPluginNameStatic();
static const char *
@@ -62,6 +65,7 @@ public:
virtual uint32_t GetNumCompileUnits ();
virtual lldb::CompUnitSP ParseCompileUnitAtIndex (uint32_t index);
+ virtual lldb::LanguageType ParseCompileUnitLanguage (const lldb_private::SymbolContext& sc);
virtual size_t ParseCompileUnitFunctions (const lldb_private::SymbolContext& sc);
virtual bool ParseCompileUnitLineTable (const lldb_private::SymbolContext& sc);
virtual bool ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc, lldb_private::FileSpecList &support_files);
@@ -108,12 +112,9 @@ public:
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
- virtual const char *
+ virtual lldb_private::ConstString
GetPluginName();
- virtual const char *
- GetShortPluginName();
-
virtual uint32_t
GetPluginVersion();
@@ -125,6 +126,20 @@ protected:
};
friend class SymbolFileDWARF;
+ friend class DebugMapModule;
+ struct OSOInfo
+ {
+ lldb::ModuleSP module_sp;
+
+ OSOInfo() :
+ module_sp ()
+ {
+ }
+ };
+
+ typedef std::shared_ptr<OSOInfo> OSOInfoSP;
+
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t> FileRangeMap;
//------------------------------------------------------------------
// Class specific types
@@ -132,35 +147,35 @@ protected:
struct CompileUnitInfo
{
lldb_private::FileSpec so_file;
- lldb_private::Symbol *so_symbol;
- lldb_private::Symbol *oso_symbol;
- lldb_private::Symbol *last_symbol;
+ lldb_private::ConstString oso_path;
+ lldb_private::TimeValue oso_mod_time;
+ OSOInfoSP oso_sp;
+ lldb::CompUnitSP compile_unit_sp;
uint32_t first_symbol_index;
uint32_t last_symbol_index;
- lldb::ModuleSP oso_module_sp;
- lldb::CompUnitSP oso_compile_unit_sp;
- lldb_private::SymbolVendor *oso_symbol_vendor;
- std::vector<uint32_t> function_indexes;
- std::vector<uint32_t> static_indexes;
- STD_SHARED_PTR(lldb_private::SectionList) debug_map_sections_sp;
- bool symbol_file_supported;
+ uint32_t first_symbol_id;
+ uint32_t last_symbol_id;
+ FileRangeMap file_range_map;
+ bool file_range_map_valid;
+
CompileUnitInfo() :
so_file (),
- so_symbol (NULL),
- oso_symbol (NULL),
- last_symbol (NULL),
+ oso_path (),
+ oso_mod_time (),
+ oso_sp (),
+ compile_unit_sp (),
first_symbol_index (UINT32_MAX),
last_symbol_index (UINT32_MAX),
- oso_module_sp (),
- oso_compile_unit_sp (),
- oso_symbol_vendor (NULL),
- function_indexes (),
- static_indexes (),
- debug_map_sections_sp (),
- symbol_file_supported (true)
+ first_symbol_id (UINT32_MAX),
+ last_symbol_id (UINT32_MAX),
+ file_range_map (),
+ file_range_map_valid (false)
{
}
+
+ const FileRangeMap &
+ GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile);
};
//------------------------------------------------------------------
@@ -174,12 +189,20 @@ protected:
{
return (uint32_t)((uid >> 32ull) - 1ull);
}
+
+ static SymbolFileDWARF *
+ GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file);
+
bool
GetFileSpecForSO (uint32_t oso_idx, lldb_private::FileSpec &file_spec);
CompileUnitInfo *
GetCompUnitInfo (const lldb_private::SymbolContext& sc);
+ size_t
+ GetCompUnitInfosForModule (const lldb_private::Module *oso_module,
+ std::vector<CompileUnitInfo *>& cu_infos);
+
lldb_private::Module *
GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info);
@@ -227,6 +250,12 @@ protected:
void
SetCompileUnit (SymbolFileDWARF *oso_dwarf, const lldb::CompUnitSP &cu_sp);
+ lldb::CompUnitSP
+ GetCompileUnit (SymbolFileDWARF *oso_dwarf);
+
+ CompileUnitInfo *
+ GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf);
+
lldb::TypeSP
FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx);
@@ -244,6 +273,58 @@ protected:
{
return m_unique_ast_type_map;
}
+
+
+ //------------------------------------------------------------------
+ // OSOEntry
+ //------------------------------------------------------------------
+ class OSOEntry
+ {
+ public:
+
+ OSOEntry () :
+ m_exe_sym_idx (UINT32_MAX),
+ m_oso_file_addr (LLDB_INVALID_ADDRESS)
+ {
+ }
+
+ OSOEntry (uint32_t exe_sym_idx,
+ lldb::addr_t oso_file_addr) :
+ m_exe_sym_idx (exe_sym_idx),
+ m_oso_file_addr (oso_file_addr)
+ {
+ }
+
+ uint32_t
+ GetExeSymbolIndex () const
+ {
+ return m_exe_sym_idx;
+ }
+
+ bool
+ operator < (const OSOEntry &rhs) const
+ {
+ return m_exe_sym_idx < rhs.m_exe_sym_idx;
+ }
+
+ lldb::addr_t
+ GetOSOFileAddress () const
+ {
+ return m_oso_file_addr;
+ }
+
+ void
+ SetOSOFileAddress (lldb::addr_t oso_file_addr)
+ {
+ m_oso_file_addr = oso_file_addr;
+ }
+ protected:
+ uint32_t m_exe_sym_idx;
+ lldb::addr_t m_oso_file_addr;
+ };
+
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, OSOEntry> DebugMap;
+
//------------------------------------------------------------------
// Member Variables
//------------------------------------------------------------------
@@ -251,8 +332,80 @@ protected:
std::vector<CompileUnitInfo> m_compile_unit_infos;
std::vector<uint32_t> m_func_indexes; // Sorted by address
std::vector<uint32_t> m_glob_indexes;
+ std::map<lldb_private::ConstString, OSOInfoSP> m_oso_map;
UniqueDWARFASTTypeMap m_unique_ast_type_map;
lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
+ DebugMap m_debug_map;
+
+ //------------------------------------------------------------------
+ // When an object file from the debug map gets parsed in
+ // SymbolFileDWARF, it needs to tell the debug map about the object
+ // files addresses by calling this function once for each N_FUN,
+ // N_GSYM and N_STSYM and after all entries in the debug map have
+ // been matched up, FinalizeOSOFileRanges() should be called.
+ //------------------------------------------------------------------
+ bool
+ AddOSOFileRange (CompileUnitInfo *cu_info,
+ lldb::addr_t exe_file_addr,
+ lldb::addr_t oso_file_addr,
+ lldb::addr_t oso_byte_size);
+
+ //------------------------------------------------------------------
+ // Called after calling AddOSOFileRange() for each object file debug
+ // map entry to finalize the info for the unlinked compile unit.
+ //------------------------------------------------------------------
+ void
+ FinalizeOSOFileRanges (CompileUnitInfo *cu_info);
+
+ //------------------------------------------------------------------
+ /// Convert \a addr from a .o file address, to an executable address.
+ ///
+ /// @param[in] addr
+ /// A section offset address from a .o file
+ ///
+ /// @return
+ /// Returns true if \a addr was converted to be an executable
+ /// section/offset address, false otherwise.
+ //------------------------------------------------------------------
+ bool
+ LinkOSOAddress (lldb_private::Address &addr);
+
+ //------------------------------------------------------------------
+ /// Convert a .o file "file address" to an executable "file address".
+ ///
+ /// @param[in] oso_symfile
+ /// The DWARF symbol file that contains \a oso_file_addr
+ ///
+ /// @param[in] oso_file_addr
+ /// A .o file "file address" to convert.
+ ///
+ /// @return
+ /// LLDB_INVALID_ADDRESS if \a oso_file_addr is not in the
+ /// linked executable, otherwise a valid "file address" from the
+ /// linked executable that contains the debug map.
+ //------------------------------------------------------------------
+ lldb::addr_t
+ LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr);
+
+ //------------------------------------------------------------------
+ /// Given a line table full of lines with "file adresses" that are
+ /// for a .o file represented by \a oso_symfile, link a new line table
+ /// and return it.
+ ///
+ /// @param[in] oso_symfile
+ /// The DWARF symbol file that produced the \a line_table
+ ///
+ /// @param[in] addr
+ /// A section offset address from a .o file
+ ///
+ /// @return
+ /// Returns a valid line table full of linked addresses, or NULL
+ /// if none of the line table adresses exist in the main
+ /// executable.
+ //------------------------------------------------------------------
+ lldb_private::LineTable *
+ LinkOSOLineTable (SymbolFileDWARF *oso_symfile,
+ lldb_private::LineTable *line_table);
};
#endif // #ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp Thu Jun 6 19:06:43 2013
@@ -12,13 +12,15 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Timer.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/Symtab.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Symbol.h"
-#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/SymbolContext.h"
-#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/Symtab.h"
+#include "lldb/Symbol/TypeList.h"
using namespace lldb;
using namespace lldb_private;
@@ -38,10 +40,11 @@ SymbolFileSymtab::Terminate()
}
-const char *
+lldb_private::ConstString
SymbolFileSymtab::GetPluginNameStatic()
{
- return "symbol-file.symtab";
+ static ConstString g_name("symtab");
+ return g_name;
}
const char *
@@ -157,6 +160,13 @@ SymbolFileSymtab::ParseCompileUnitAtInde
return cu_sp;
}
+lldb::LanguageType
+SymbolFileSymtab::ParseCompileUnitLanguage (const SymbolContext& sc)
+{
+ return eLanguageTypeUnknown;
+}
+
+
size_t
SymbolFileSymtab::ParseCompileUnitFunctions (const SymbolContext &sc)
{
@@ -372,77 +382,15 @@ SymbolFileSymtab::FindTypes (const lldb_
uint32_t max_matches,
lldb_private::TypeList& types)
{
- if (!append)
- types.Clear();
-
- if (!m_objc_class_name_to_index.IsEmpty())
- {
- TypeMap::iterator iter = m_objc_class_types.find(name);
-
- if (iter != m_objc_class_types.end())
- {
- types.Insert(iter->second);
- return 1;
- }
-
- const Symtab::NameToIndexMap::Entry *match = m_objc_class_name_to_index.FindFirstValueForName(name.GetCString());
-
- if (match == NULL)
- return 0;
-
- const bool isForwardDecl = false;
- const bool isInternal = true;
-
- ClangASTContext &ast = GetClangASTContext();
-
- lldb::clang_type_t objc_object_type = ast.CreateObjCClass (name.AsCString(),
- ast.GetTranslationUnitDecl(),
- isForwardDecl,
- isInternal,
- 0xffaaffaaffaaffaall);
-
- Declaration decl;
-
- lldb::TypeSP type(new Type (match->value,
- this,
- name,
- 0, // byte_size - don't change this from 0, we currently use that to identify these "synthetic" ObjC class types.
- NULL, // SymbolContextScope*
- 0, // encoding_uid
- Type::eEncodingInvalid,
- decl,
- objc_object_type,
- Type::eResolveStateFull));
-
- m_objc_class_types[name] = type;
-
- types.Insert(type);
-
- return 1;
- }
-
return 0;
}
-//
-//uint32_t
-//SymbolFileSymtab::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types)
-//{
-// return 0;
-//}
-
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-const char *
+lldb_private::ConstString
SymbolFileSymtab::GetPluginName()
{
- return "SymbolFileSymtab";
-}
-
-const char *
-SymbolFileSymtab::GetShortPluginName()
-{
return GetPluginNameStatic();
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h Thu Jun 6 19:06:43 2013
@@ -26,7 +26,7 @@ public:
static void
Terminate();
- static const char *
+ static lldb_private::ConstString
GetPluginNameStatic();
static const char *
@@ -54,6 +54,9 @@ public:
virtual lldb::CompUnitSP
ParseCompileUnitAtIndex(uint32_t index);
+ virtual lldb::LanguageType
+ ParseCompileUnitLanguage (const lldb_private::SymbolContext& sc);
+
virtual size_t
ParseCompileUnitFunctions (const lldb_private::SymbolContext& sc);
@@ -110,12 +113,9 @@ public:
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
- virtual const char *
+ virtual lldb_private::ConstString
GetPluginName();
- virtual const char *
- GetShortPluginName();
-
virtual uint32_t
GetPluginVersion();
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp Thu Jun 6 19:06:43 2013
@@ -16,9 +16,12 @@
#include <AvailabilityMacros.h>
#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
+#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
+#include "lldb/Host/Host.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -42,14 +45,40 @@ SymbolVendorMacOSX::~SymbolVendorMacOSX(
static bool
-UUIDsMatch(Module *module, ObjectFile *ofile)
+UUIDsMatch(Module *module, ObjectFile *ofile, lldb_private::Stream *feedback_strm)
{
if (module && ofile)
{
// Make sure the UUIDs match
lldb_private::UUID dsym_uuid;
- if (ofile->GetUUID(&dsym_uuid))
- return dsym_uuid == module->GetUUID();
+
+ if (!ofile->GetUUID(&dsym_uuid))
+ {
+ if (feedback_strm)
+ {
+ feedback_strm->PutCString("warning: failed to get the uuid for object file: '");
+ ofile->GetFileSpec().Dump(feedback_strm);
+ feedback_strm->PutCString("\n");
+ }
+ return false;
+ }
+
+ if (dsym_uuid == module->GetUUID())
+ return true;
+
+ // Emit some warning messages since the UUIDs do not match!
+ if (feedback_strm)
+ {
+ feedback_strm->PutCString("warning: UUID mismatch detected between modules:\n ");
+ module->GetUUID().Dump(feedback_strm);
+ feedback_strm->PutChar(' ');
+ module->GetFileSpec().Dump(feedback_strm);
+ feedback_strm->PutCString("\n ");
+ dsym_uuid.Dump(feedback_strm);
+ feedback_strm->PutChar(' ');
+ ofile->GetFileSpec().Dump(feedback_strm);
+ feedback_strm->EOL();
+ }
}
return false;
}
@@ -78,6 +107,16 @@ ReplaceDSYMSectionsWithExecutableSection
// and in the dSYM with those from the executable. If we fail to
// replace the one in the dSYM, then add the executable section to
// the dSYM.
+ SectionSP dsym_sect_sp(dsym_section_list->FindSectionByID(exec_sect_sp->GetID()));
+ if (dsym_sect_sp.get() && dsym_sect_sp->GetName() != exec_sect_sp->GetName())
+ {
+ // The sections in a dSYM are normally a superset of the sections in an executable.
+ // If we find a section # in the exectuable & dSYM that don't have the same name,
+ // something has changed since the dSYM was written. The mach_kernel DSTROOT binary
+ // has a CTF segment added, for instance, and it's easiest to simply not add that to
+ // the dSYM - none of the nlist entries are going to have references to that section.
+ continue;
+ }
if (dsym_section_list->ReplaceSection(exec_sect_sp->GetID(), exec_sect_sp, 0) == false)
dsym_section_list->AddSection(exec_sect_sp);
}
@@ -102,10 +141,11 @@ SymbolVendorMacOSX::Terminate()
}
-const char *
+lldb_private::ConstString
SymbolVendorMacOSX::GetPluginNameStatic()
{
- return "symbol-vendor.macosx";
+ static ConstString g_name("macosx");
+ return g_name;
}
const char *
@@ -124,15 +164,14 @@ SymbolVendorMacOSX::GetPluginDescription
// also allow for finding separate debug information files.
//----------------------------------------------------------------------
SymbolVendor*
-SymbolVendorMacOSX::CreateInstance (const lldb::ModuleSP &module_sp)
+SymbolVendorMacOSX::CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm)
{
if (!module_sp)
return NULL;
Timer scoped_timer (__PRETTY_FUNCTION__,
- "SymbolVendorMacOSX::CreateInstance (module = %s/%s)",
- module_sp->GetFileSpec().GetDirectory().AsCString(),
- module_sp->GetFileSpec().GetFilename().AsCString());
+ "SymbolVendorMacOSX::CreateInstance (module = %s)",
+ module_sp->GetFileSpec().GetPath().c_str());
SymbolVendorMacOSX* symbol_vendor = new SymbolVendorMacOSX(module_sp);
if (symbol_vendor)
{
@@ -144,9 +183,8 @@ SymbolVendorMacOSX::CreateInstance (cons
if (obj_file)
{
Timer scoped_timer2 ("SymbolVendorMacOSX::CreateInstance () locate dSYM",
- "SymbolVendorMacOSX::CreateInstance (module = %s/%s) locate dSYM",
- module_sp->GetFileSpec().GetDirectory().AsCString(),
- module_sp->GetFileSpec().GetFilename().AsCString());
+ "SymbolVendorMacOSX::CreateInstance (module = %s) locate dSYM",
+ module_sp->GetFileSpec().GetPath().c_str());
// First check to see if the module has a symbol file in mind already.
// If it does, then we MUST use that.
@@ -157,24 +195,23 @@ SymbolVendorMacOSX::CreateInstance (cons
{
// No symbol file was specified in the module, lets try and find
// one ourselves.
- const FileSpec &file_spec = obj_file->GetFileSpec();
- if (file_spec)
- {
- ModuleSpec module_spec(file_spec, module_sp->GetArchitecture());
- module_spec.GetUUID() = module_sp->GetUUID();
- dsym_fspec = Symbols::LocateExecutableSymbolFile (module_spec);
- if (module_spec.GetSourceMappingList().GetSize())
- {
- module_sp->GetSourceMappingList().Append (module_spec.GetSourceMappingList (), true);
- }
- }
+ FileSpec file_spec = obj_file->GetFileSpec();
+ if (!file_spec)
+ file_spec = module_sp->GetFileSpec();
+
+ ModuleSpec module_spec(file_spec, module_sp->GetArchitecture());
+ module_spec.GetUUID() = module_sp->GetUUID();
+ dsym_fspec = Symbols::LocateExecutableSymbolFile (module_spec);
+ if (module_spec.GetSourceMappingList().GetSize())
+ module_sp->GetSourceMappingList().Append (module_spec.GetSourceMappingList (), true);
}
if (dsym_fspec)
{
DataBufferSP dsym_file_data_sp;
- dsym_objfile_sp = ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(), dsym_file_data_sp);
- if (UUIDsMatch(module_sp.get(), dsym_objfile_sp.get()))
+ lldb::offset_t dsym_file_data_offset = 0;
+ dsym_objfile_sp = ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(), dsym_file_data_sp, dsym_file_data_offset);
+ if (UUIDsMatch(module_sp.get(), dsym_objfile_sp.get(), feedback_strm))
{
char dsym_path[PATH_MAX];
if (module_sp->GetSourceMappingList().IsEmpty() && dsym_fspec.GetPath(dsym_path, sizeof(dsym_path)))
@@ -182,16 +219,15 @@ SymbolVendorMacOSX::CreateInstance (cons
lldb_private::UUID dsym_uuid;
if (dsym_objfile_sp->GetUUID(&dsym_uuid))
{
- char uuid_cstr_buf[64];
- const char *uuid_cstr = dsym_uuid.GetAsCString (uuid_cstr_buf, sizeof(uuid_cstr_buf));
- if (uuid_cstr)
+ std::string uuid_str = dsym_uuid.GetAsString ();
+ if (!uuid_str.empty())
{
char *resources = strstr (dsym_path, "/Contents/Resources/");
if (resources)
{
char dsym_uuid_plist_path[PATH_MAX];
resources[strlen("/Contents/Resources/")] = '\0';
- snprintf(dsym_uuid_plist_path, sizeof(dsym_uuid_plist_path), "%s%s.plist", dsym_path, uuid_cstr);
+ snprintf(dsym_uuid_plist_path, sizeof(dsym_uuid_plist_path), "%s%s.plist", dsym_path, uuid_str.c_str());
FileSpec dsym_uuid_plist_spec(dsym_uuid_plist_path, false);
if (dsym_uuid_plist_spec.Exists())
{
@@ -297,15 +333,9 @@ SymbolVendorMacOSX::CreateInstance (cons
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-const char *
+ConstString
SymbolVendorMacOSX::GetPluginName()
{
- return "SymbolVendorMacOSX";
-}
-
-const char *
-SymbolVendorMacOSX::GetShortPluginName()
-{
return GetPluginNameStatic();
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h Thu Jun 6 19:06:43 2013
@@ -25,14 +25,14 @@ public:
static void
Terminate();
- static const char *
+ static lldb_private::ConstString
GetPluginNameStatic();
static const char *
GetPluginDescriptionStatic();
static lldb_private::SymbolVendor*
- CreateInstance (const lldb::ModuleSP &module_sp);
+ CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm);
//------------------------------------------------------------------
// Constructors and Destructors
@@ -45,12 +45,9 @@ public:
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
- virtual const char *
+ virtual lldb_private::ConstString
GetPluginName();
- virtual const char *
- GetShortPluginName();
-
virtual uint32_t
GetPluginVersion();
Modified: lldb/branches/lldb-platform-work/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp Thu Jun 6 19:06:43 2013
@@ -9,11 +9,10 @@
#include "UnwindAssemblyInstEmulation.h"
-#include "llvm-c/EnhancedDisassembly.h"
-
#include "lldb/Core/Address.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
@@ -56,10 +55,11 @@ UnwindAssemblyInstEmulation::GetNonCallS
thread.CalculateExecutionContext(exe_ctx);
DisassemblerSP disasm_sp (Disassembler::DisassembleRange (m_arch,
NULL,
+ NULL,
exe_ctx,
range));
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
if (disasm_sp)
{
@@ -107,8 +107,13 @@ UnwindAssemblyInstEmulation::GetNonCallS
// copy of the CFI at that point into prologue_completed_row for possible
// use later.
int instructions_since_last_prologue_insn = 0; // # of insns since last CFI was update
- bool prologue_complete = false; // true if we have finished prologue setup
+
bool reinstate_prologue_next_instruction = false; // Next iteration, re-install the prologue row of CFI
+
+ bool last_instruction_restored_return_addr_reg = false; // re-install the prologue row of CFI if the next instruction is a branch immediate
+
+ bool return_address_register_has_been_saved = false; // if we've seen the ra register get saved yet
+
UnwindPlan::RowSP prologue_completed_row; // copy of prologue row of CFI
// cache the pc register number (in whatever register numbering this UnwindPlan uses) for
@@ -117,11 +122,22 @@ UnwindAssemblyInstEmulation::GetNonCallS
RegisterInfo pc_reg_info;
if (m_inst_emulator_ap->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc_reg_info))
pc_reg_num = pc_reg_info.kinds[unwind_plan.GetRegisterKind()];
+ else
+ pc_reg_num = LLDB_INVALID_REGNUM;
+ // cache the return address register number (in whatever register numbering this UnwindPlan uses) for
+ // quick reference during instruction parsing.
+ uint32_t ra_reg_num = LLDB_INVALID_REGNUM;
+ RegisterInfo ra_reg_info;
+ if (m_inst_emulator_ap->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, ra_reg_info))
+ ra_reg_num = ra_reg_info.kinds[unwind_plan.GetRegisterKind()];
+ else
+ ra_reg_num = LLDB_INVALID_REGNUM;
for (size_t idx=0; idx<num_instructions; ++idx)
{
m_curr_row_modified = false;
+ m_curr_insn_restored_a_register = false;
inst = inst_list.GetInstructionAtIndex (idx).get();
if (inst)
{
@@ -151,14 +167,33 @@ UnwindAssemblyInstEmulation::GetNonCallS
*newrow = *m_curr_row.get();
m_curr_row.reset(newrow);
- instructions_since_last_prologue_insn = 0;
+ // If m_curr_insn_restored_a_register == true, we're looking at an epilogue instruction.
+ // Set instructions_since_last_prologue_insn to a very high number so we don't append
+ // any of these epilogue instructions to our prologue_complete row.
+ if (m_curr_insn_restored_a_register == false && instructions_since_last_prologue_insn < 8)
+ instructions_since_last_prologue_insn = 0;
+ else
+ instructions_since_last_prologue_insn = 99;
+
+ UnwindPlan::Row::RegisterLocation pc_regloc;
+ UnwindPlan::Row::RegisterLocation ra_regloc;
+
+ // While parsing the instructions of this function, if we've ever
+ // seen the return address register (aka lr on arm) in a non-IsSame() state,
+ // it has been saved on the stack. If it's evern back to IsSame(), we've
+ // executed an epilogue.
+ if (ra_reg_num != LLDB_INVALID_REGNUM
+ && m_curr_row->GetRegisterInfo (ra_reg_num, ra_regloc)
+ && !ra_regloc.IsSame())
+ {
+ return_address_register_has_been_saved = true;
+ }
// If the caller's pc is "same", we've just executed an epilogue and we return to the caller
// after this instruction completes executing.
// If there are any instructions past this, there must have been flow control over this
// epilogue so we'll reinstate the original prologue setup instructions.
- UnwindPlan::Row::RegisterLocation pc_regloc;
- if (prologue_complete
+ if (prologue_completed_row.get()
&& pc_reg_num != LLDB_INVALID_REGNUM
&& m_curr_row->GetRegisterInfo (pc_reg_num, pc_regloc)
&& pc_regloc.IsSame())
@@ -167,13 +202,26 @@ UnwindAssemblyInstEmulation::GetNonCallS
log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- pc is <same>, restore prologue instructions.");
reinstate_prologue_next_instruction = true;
}
+ else if (prologue_completed_row.get()
+ && return_address_register_has_been_saved
+ && ra_reg_num != LLDB_INVALID_REGNUM
+ && m_curr_row->GetRegisterInfo (ra_reg_num, ra_regloc)
+ && ra_regloc.IsSame())
+ {
+ if (log && log->GetVerbose())
+ log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- lr is <same>, restore prologue instruction if the next instruction is a branch immediate.");
+ last_instruction_restored_return_addr_reg = true;
+ }
}
else
{
// If the previous instruction was a return-to-caller (epilogue), and we're still executing
// instructions in this function, there must be a code path that jumps over that epilogue.
+ // Also detect the case where we epilogue & branch imm to another function (tail-call opt)
+ // instead of a normal pop lr-into-pc exit.
// Reinstate the frame setup from the prologue.
- if (reinstate_prologue_next_instruction)
+ if (reinstate_prologue_next_instruction
+ || (m_curr_insn_is_branch_immediate && last_instruction_restored_return_addr_reg))
{
if (log && log->GetVerbose())
log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- Reinstating prologue instruction set");
@@ -188,18 +236,29 @@ UnwindAssemblyInstEmulation::GetNonCallS
m_curr_row.reset(newrow);
reinstate_prologue_next_instruction = false;
+ last_instruction_restored_return_addr_reg = false;
+ m_curr_insn_is_branch_immediate = false;
}
- // If we haven't seen any prologue instructions for a while (4 instructions in a row),
- // the function prologue has probably completed. Save a copy of that Row.
- if (prologue_complete == false && instructions_since_last_prologue_insn++ > 3)
+ // clear both of these if either one wasn't set
+ if (last_instruction_restored_return_addr_reg)
+ {
+ last_instruction_restored_return_addr_reg = false;
+ }
+ if (m_curr_insn_is_branch_immediate)
+ {
+ m_curr_insn_is_branch_immediate = false;
+ }
+
+ // Stop updating the prologue instructions if we've seen 8 non-prologue instructions
+ // in a row.
+ if (instructions_since_last_prologue_insn++ < 8)
{
- prologue_complete = true;
UnwindPlan::Row *newrow = new UnwindPlan::Row;
*newrow = *m_curr_row.get();
prologue_completed_row.reset(newrow);
if (log && log->GetVerbose())
- log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- prologue has been set up, saving a copy.");
+ log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- saving a copy of the current row as the prologue row.");
}
}
}
@@ -211,7 +270,7 @@ UnwindAssemblyInstEmulation::GetNonCallS
{
StreamString strm;
lldb::addr_t base_addr = range.GetBaseAddress().GetLoadAddress(thread.CalculateTarget().get());
- strm.Printf ("Resulting unwind rows for [0x%llx - 0x%llx):", base_addr, base_addr + range.GetByteSize());
+ strm.Printf ("Resulting unwind rows for [0x%" PRIx64 " - 0x%" PRIx64 "):", base_addr, base_addr + range.GetByteSize());
unwind_plan.Dump(strm, &thread, base_addr);
log->PutCString (strm.GetData());
}
@@ -239,7 +298,7 @@ UnwindAssemblyInstEmulation::FirstNonPro
UnwindAssembly *
UnwindAssemblyInstEmulation::CreateInstance (const ArchSpec &arch)
{
- std::auto_ptr<EmulateInstruction> inst_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypePrologueEpilogue, NULL));
+ std::unique_ptr<EmulateInstruction> inst_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypePrologueEpilogue, NULL));
// Make sure that all prologue instructions are handled
if (inst_emulator_ap.get())
return new UnwindAssemblyInstEmulation (arch, inst_emulator_ap.release());
@@ -250,20 +309,12 @@ UnwindAssemblyInstEmulation::CreateInsta
//------------------------------------------------------------------
// PluginInterface protocol in UnwindAssemblyParser_x86
//------------------------------------------------------------------
-
-const char *
+ConstString
UnwindAssemblyInstEmulation::GetPluginName()
{
- return "UnwindAssemblyInstEmulation";
-}
-
-const char *
-UnwindAssemblyInstEmulation::GetShortPluginName()
-{
- return "unwindassembly.inst-emulation";
+ return GetPluginNameStatic();
}
-
uint32_t
UnwindAssemblyInstEmulation::GetPluginVersion()
{
@@ -285,10 +336,11 @@ UnwindAssemblyInstEmulation::Terminate()
}
-const char *
+ConstString
UnwindAssemblyInstEmulation::GetPluginNameStatic()
{
- return "UnwindAssemblyInstEmulation";
+ static ConstString g_name("inst-emulation");
+ return g_name;
}
const char *
@@ -338,15 +390,15 @@ UnwindAssemblyInstEmulation::ReadMemory
void *dst,
size_t dst_len)
{
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
if (log && log->GetVerbose ())
{
StreamString strm;
- strm.Printf ("UnwindAssemblyInstEmulation::ReadMemory (addr = 0x%16.16llx, dst = %p, dst_len = %zu, context = ",
+ strm.Printf ("UnwindAssemblyInstEmulation::ReadMemory (addr = 0x%16.16" PRIx64 ", dst = %p, dst_len = %" PRIu64 ", context = ",
addr,
dst,
- dst_len);
+ (uint64_t)dst_len);
context.Dump(strm, instruction);
log->PutCString (strm.GetData ());
}
@@ -379,7 +431,7 @@ UnwindAssemblyInstEmulation::WriteMemory
instruction->GetArchitecture ().GetByteOrder(),
instruction->GetArchitecture ().GetAddressByteSize());
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
if (log && log->GetVerbose ())
{
@@ -486,7 +538,7 @@ UnwindAssemblyInstEmulation::ReadRegiste
{
bool synthetic = GetRegisterValue (*reg_info, reg_value);
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
if (log && log->GetVerbose ())
{
@@ -516,7 +568,7 @@ UnwindAssemblyInstEmulation::WriteRegist
const RegisterInfo *reg_info,
const RegisterValue ®_value)
{
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
if (log && log->GetVerbose ())
{
@@ -534,7 +586,6 @@ UnwindAssemblyInstEmulation::WriteRegist
switch (context.type)
{
- default:
case EmulateInstruction::eContextInvalid:
case EmulateInstruction::eContextReadOpcode:
case EmulateInstruction::eContextImmediate:
@@ -543,7 +594,6 @@ UnwindAssemblyInstEmulation::WriteRegist
case EmulateInstruction::eContextAdjustPC:
case EmulateInstruction::eContextRegisterStore:
case EmulateInstruction::eContextRegisterLoad:
- case EmulateInstruction::eContextRelativeBranchImmediate:
case EmulateInstruction::eContextAbsoluteBranchRegister:
case EmulateInstruction::eContextSupervisorCall:
case EmulateInstruction::eContextTableBranchReadMemory:
@@ -567,6 +617,15 @@ UnwindAssemblyInstEmulation::WriteRegist
// }
break;
+ case EmulateInstruction::eContextRelativeBranchImmediate:
+ {
+
+ {
+ m_curr_insn_is_branch_immediate = true;
+ }
+ }
+ break;
+
case EmulateInstruction::eContextPopRegisterOffStack:
{
const uint32_t reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
@@ -574,6 +633,7 @@ UnwindAssemblyInstEmulation::WriteRegist
{
m_curr_row->SetRegisterLocationToSame (reg_num, must_replace);
m_curr_row_modified = true;
+ m_curr_insn_restored_a_register = true;
}
}
break;
Modified: lldb/branches/lldb-platform-work/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h Thu Jun 6 19:06:43 2013
@@ -53,18 +53,15 @@ public:
static void
Terminate();
- static const char *
+ static lldb_private::ConstString
GetPluginNameStatic();
static const char *
GetPluginDescriptionStatic();
- virtual const char *
+ virtual lldb_private::ConstString
GetPluginName();
- virtual const char *
- GetShortPluginName();
-
virtual uint32_t
GetPluginVersion();
@@ -134,11 +131,13 @@ private:
m_thread_ptr (NULL),
m_unwind_plan_ptr (NULL),
m_curr_row (),
- m_curr_row_modified (false),
m_cfa_reg_info (),
m_fp_is_cfa (false),
m_register_values (),
- m_pushed_regs()
+ m_pushed_regs(),
+ m_curr_row_modified (false),
+ m_curr_insn_is_branch_immediate (false),
+ m_curr_insn_restored_a_register (false)
{
if (m_inst_emulator_ap.get())
{
@@ -158,12 +157,11 @@ private:
GetRegisterValue (const lldb_private::RegisterInfo ®_info,
lldb_private::RegisterValue ®_value);
- std::auto_ptr<lldb_private::EmulateInstruction> m_inst_emulator_ap;
+ std::unique_ptr<lldb_private::EmulateInstruction> m_inst_emulator_ap;
lldb_private::AddressRange* m_range_ptr;
lldb_private::Thread* m_thread_ptr;
lldb_private::UnwindPlan* m_unwind_plan_ptr;
lldb_private::UnwindPlan::RowSP m_curr_row;
- bool m_curr_row_modified;
typedef std::map<uint64_t, uint64_t> PushedRegisterToAddrMap;
uint64_t m_initial_sp;
lldb_private::RegisterInfo m_cfa_reg_info;
@@ -171,6 +169,17 @@ private:
typedef std::map<uint64_t, lldb_private::RegisterValue> RegisterValueMap;
RegisterValueMap m_register_values;
PushedRegisterToAddrMap m_pushed_regs;
+
+ // While processing the instruction stream, we need to communicate some state change
+ // information up to the higher level loop that makes decisions about how to push
+ // the unwind instructions for the UnwindPlan we're constructing.
+
+ // The instruction we're processing updated the UnwindPlan::Row contents
+ bool m_curr_row_modified;
+ // The instruction we're examining is a branch immediate instruction
+ bool m_curr_insn_is_branch_immediate;
+ // The instruction we're processing restored a caller's reg value (e.g. in an epilogue)
+ bool m_curr_insn_restored_a_register;
};
#endif // liblldb_UnwindAssemblyInstEmulation_h_
Modified: lldb/branches/lldb-platform-work/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp Thu Jun 6 19:06:43 2013
@@ -9,7 +9,7 @@
#include "UnwindAssembly-x86.h"
-#include "llvm-c/EnhancedDisassembly.h"
+#include "llvm-c/Disassembler.h"
#include "llvm/Support/TargetSelect.h"
#include "lldb/Core/Address.h"
@@ -117,7 +117,9 @@ static int x86_64_register_map_initializ
class AssemblyParse_x86 {
public:
- AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, AddressRange func);
+ AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, ArchSpec &arch, AddressRange func);
+
+ ~AssemblyParse_x86 ();
bool get_non_call_site_unwind_plan (UnwindPlan &unwind_plan);
@@ -157,11 +159,13 @@ private:
int m_wordsize;
int m_cpu;
+ ArchSpec m_arch;
+ ::LLVMDisasmContextRef m_disasm_context;
DISALLOW_COPY_AND_ASSIGN (AssemblyParse_x86);
};
-AssemblyParse_x86::AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, AddressRange func) :
+AssemblyParse_x86::AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, ArchSpec &arch, AddressRange func) :
m_exe_ctx (exe_ctx),
m_func_bounds(func),
m_cur_insn (),
@@ -172,7 +176,8 @@ AssemblyParse_x86::AssemblyParse_x86 (co
m_lldb_sp_regnum (LLDB_INVALID_REGNUM),
m_lldb_fp_regnum (LLDB_INVALID_REGNUM),
m_wordsize (-1),
- m_cpu(cpu)
+ m_cpu(cpu),
+ m_arch(arch)
{
int *initialized_flag = NULL;
if (cpu == k_i386)
@@ -236,8 +241,18 @@ AssemblyParse_x86::AssemblyParse_x86 (co
if (machine_regno_to_lldb_regno (m_machine_ip_regnum, lldb_regno))
m_lldb_ip_regnum = lldb_regno;
}
+
+ m_disasm_context = ::LLVMCreateDisasm(m_arch.GetTriple().getTriple().c_str(),
+ (void*)this,
+ /*TagType=*/1,
+ NULL,
+ NULL);
}
+AssemblyParse_x86::~AssemblyParse_x86 ()
+{
+ ::LLVMDisasmDispose(m_disasm_context);
+}
// This function expects an x86 native register number (i.e. the bits stripped out of the
// actual instruction), not an lldb register number.
@@ -451,79 +466,34 @@ AssemblyParse_x86::machine_regno_to_lldb
return false;
}
-struct edis_byte_read_token
-{
- Address *address;
- Target *target;
-};
-
-
-static int
-read_byte_for_edis (uint8_t *buf, uint64_t offset_address, void *arg)
-{
- if (arg == 0)
- return -1;
- struct edis_byte_read_token *tok = (edis_byte_read_token *) arg;
- Address *base_address = tok->address;
- Target *target = tok->target;
-
- Address read_addr = *base_address;
- read_addr.SetOffset (offset_address);
-
- uint8_t onebyte_buf[1];
- Error error;
- const bool prefer_file_cache = true;
- if (target->ReadMemory (read_addr, prefer_file_cache, onebyte_buf, 1, error) != -1)
- {
- *buf = onebyte_buf[0];
- return 0;
- }
- return -1;
-}
-
-
bool
AssemblyParse_x86::instruction_length (Address addr, int &length)
{
- const char *triple;
+ const uint32_t max_op_byte_size = m_arch.GetMaximumOpcodeByteSize();
+ llvm::SmallVector <uint8_t, 32> opcode_data;
+ opcode_data.resize (max_op_byte_size);
if (!addr.IsValid())
return false;
- // FIXME should probably pass down the ArchSpec and work from that to make a portable triple
- if (m_cpu == k_i386)
- triple = "i386-unknown-unknown";
- else
- triple = "x86_64-unknown-unknown";
-
- // Initialize the LLVM objects needed to use the disassembler.
- static struct InitializeLLVM {
- InitializeLLVM() {
- llvm::InitializeAllTargetInfos();
- llvm::InitializeAllTargetMCs();
- llvm::InitializeAllAsmParsers();
- llvm::InitializeAllDisassemblers();
- }
- } InitializeLLVM;
-
- EDDisassemblerRef disasm;
- EDInstRef cur_insn;
-
- if (EDGetDisassembler (&disasm, triple, kEDAssemblySyntaxX86ATT) != 0)
+ const bool prefer_file_cache = true;
+ Error error;
+ Target *target = m_exe_ctx.GetTargetPtr();
+ if (target->ReadMemory (addr, prefer_file_cache, opcode_data.data(), max_op_byte_size, error) == -1)
{
return false;
}
+
+ char out_string[512];
+ const addr_t pc = addr.GetFileAddress();
+ const size_t inst_size = ::LLVMDisasmInstruction (m_disasm_context,
+ opcode_data.data(),
+ max_op_byte_size,
+ pc, // PC value
+ out_string,
+ sizeof(out_string));
- uint64_t addr_offset = addr.GetOffset();
- struct edis_byte_read_token arg;
- arg.address = &addr;
- arg.target = m_exe_ctx.GetTargetPtr();
- if (EDCreateInsts (&cur_insn, 1, disasm, read_byte_for_edis, addr_offset, &arg) != 1)
- {
- return false;
- }
- length = EDInstByteSize (cur_insn);
- EDReleaseInst (cur_insn);
+ length = inst_size;
return true;
}
@@ -768,6 +738,8 @@ loopnext:
}
unwind_plan.SetSourceName ("assembly insn profiling");
+ unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
return true;
}
@@ -852,6 +824,9 @@ AssemblyParse_x86::get_fast_unwind_plan
row.reset(newrow);
unwind_plan.SetPlanValidAddressRange (func);
+ unwind_plan.SetSourceName ("fast unwind assembly profiling");
+ unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
return true;
}
@@ -907,7 +882,8 @@ AssemblyParse_x86::find_first_non_prolog
UnwindAssembly_x86::UnwindAssembly_x86 (const ArchSpec &arch, int cpu) :
lldb_private::UnwindAssembly(arch),
- m_cpu(cpu)
+ m_cpu(cpu),
+ m_arch(arch)
{
}
@@ -920,7 +896,7 @@ bool
UnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan)
{
ExecutionContext exe_ctx (thread.shared_from_this());
- AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, func);
+ AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
return asm_parse.get_non_call_site_unwind_plan (unwind_plan);
}
@@ -928,14 +904,14 @@ bool
UnwindAssembly_x86::GetFastUnwindPlan (AddressRange& func, Thread& thread, UnwindPlan &unwind_plan)
{
ExecutionContext exe_ctx (thread.shared_from_this());
- AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, func);
+ AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
return asm_parse.get_fast_unwind_plan (func, unwind_plan);
}
bool
UnwindAssembly_x86::FirstNonPrologueInsn (AddressRange& func, const ExecutionContext &exe_ctx, Address& first_non_prologue_insn)
{
- AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, func);
+ AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
return asm_parse.find_first_non_prologue_insn (first_non_prologue_insn);
}
@@ -955,16 +931,10 @@ UnwindAssembly_x86::CreateInstance (cons
// PluginInterface protocol in UnwindAssemblyParser_x86
//------------------------------------------------------------------
-const char *
+ConstString
UnwindAssembly_x86::GetPluginName()
{
- return "UnwindAssembly_x86";
-}
-
-const char *
-UnwindAssembly_x86::GetShortPluginName()
-{
- return "unwindassembly.x86";
+ return GetPluginNameStatic();
}
@@ -989,10 +959,11 @@ UnwindAssembly_x86::Terminate()
}
-const char *
+lldb_private::ConstString
UnwindAssembly_x86::GetPluginNameStatic()
{
- return "UnwindAssembly_x86";
+ static ConstString g_name("x86");
+ return g_name;
}
const char *
Modified: lldb/branches/lldb-platform-work/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h Thu Jun 6 19:06:43 2013
@@ -10,6 +10,8 @@
#ifndef liblldb_UnwindAssembly_x86_h_
#define liblldb_UnwindAssembly_x86_h_
+#include "llvm-c/Disassembler.h"
+
#include "lldb/lldb-private.h"
#include "lldb/Target/UnwindAssembly.h"
@@ -48,18 +50,15 @@ public:
static void
Terminate();
- static const char *
+ static lldb_private::ConstString
GetPluginNameStatic();
static const char *
GetPluginDescriptionStatic();
- virtual const char *
+ virtual lldb_private::ConstString
GetPluginName();
- virtual const char *
- GetShortPluginName();
-
virtual uint32_t
GetPluginVersion();
@@ -67,6 +66,7 @@ private:
UnwindAssembly_x86 (const lldb_private::ArchSpec &arch, int cpu);
int m_cpu;
+ lldb_private::ArchSpec m_arch;
};
Modified: lldb/branches/lldb-platform-work/source/Symbol/Block.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/Block.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/Block.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/Block.cpp Thu Jun 6 19:06:43 2013
@@ -89,7 +89,7 @@ Block::Dump(Stream *s, addr_t base_addr,
const Block* parent_block = GetParent();
if (parent_block)
{
- s->Printf(", parent = {0x%8.8llx}", parent_block->GetID());
+ s->Printf(", parent = {0x%8.8" PRIx64 "}", parent_block->GetID());
}
if (m_inlineInfoSP.get() != NULL)
{
@@ -194,7 +194,7 @@ Block::DumpSymbolContext(Stream *s)
Function *function = CalculateSymbolContextFunction();
if (function)
function->DumpSymbolContext(s);
- s->Printf(", Block{0x%8.8llx}", GetID());
+ s->Printf(", Block{0x%8.8" PRIx64 "}", GetID());
}
void
@@ -317,6 +317,16 @@ Block::GetRangeContainingAddress (const
return false;
}
+bool
+Block::GetRangeContainingLoadAddress (lldb::addr_t load_addr, Target &target, AddressRange &range)
+{
+ Address load_address;
+ load_address.SetLoadAddress(load_addr, &target);
+ AddressRange containing_range;
+ return GetRangeContainingAddress(load_address, containing_range);
+}
+
+
uint32_t
Block::GetRangeIndexContainingAddress (const Address& addr)
{
@@ -385,7 +395,7 @@ Block::AddRange (const Range& range)
Block *parent_block = GetParent ();
if (parent_block && !parent_block->Contains(range))
{
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
if (log)
{
ModuleSP module_sp (m_parent_scope->CalculateSymbolContextModule());
@@ -398,9 +408,8 @@ Block::AddRange (const Range& range)
const Declaration &func_decl = func_type->GetDeclaration();
if (func_decl.GetLine())
{
- log->Printf ("warning: %s/%s:%u block {0x%8.8llx} has range[%u] [0x%llx - 0x%llx) which is not contained in parent block {0x%8.8llx} in function {0x%8.8llx} from %s/%s",
- func_decl.GetFile().GetDirectory().GetCString(),
- func_decl.GetFile().GetFilename().GetCString(),
+ log->Printf ("warning: %s:%u block {0x%8.8" PRIx64 "} has range[%u] [0x%" PRIx64 " - 0x%" PRIx64 ") which is not contained in parent block {0x%8.8" PRIx64 "} in function {0x%8.8" PRIx64 "} from %s",
+ func_decl.GetFile().GetPath().c_str(),
func_decl.GetLine(),
GetID(),
(uint32_t)m_ranges.GetSize(),
@@ -408,20 +417,18 @@ Block::AddRange (const Range& range)
block_end_addr,
parent_block->GetID(),
function->GetID(),
- module_sp->GetFileSpec().GetDirectory().GetCString(),
- module_sp->GetFileSpec().GetFilename().GetCString());
+ module_sp->GetFileSpec().GetPath().c_str());
}
else
{
- log->Printf ("warning: block {0x%8.8llx} has range[%u] [0x%llx - 0x%llx) which is not contained in parent block {0x%8.8llx} in function {0x%8.8llx} from %s/%s",
+ log->Printf ("warning: block {0x%8.8" PRIx64 "} has range[%u] [0x%" PRIx64 " - 0x%" PRIx64 ") which is not contained in parent block {0x%8.8" PRIx64 "} in function {0x%8.8" PRIx64 "} from %s",
GetID(),
(uint32_t)m_ranges.GetSize(),
block_start_addr,
block_end_addr,
parent_block->GetID(),
function->GetID(),
- module_sp->GetFileSpec().GetDirectory().GetCString(),
- module_sp->GetFileSpec().GetFilename().GetCString());
+ module_sp->GetFileSpec().GetPath().c_str());
}
}
parent_block->AddRange (range);
Modified: lldb/branches/lldb-platform-work/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/ClangASTContext.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/ClangASTContext.cpp Thu Jun 6 19:06:43 2013
@@ -34,6 +34,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTImporter.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
@@ -84,6 +85,8 @@ GetCompleteQualType (clang::ASTContext *
switch (type_class)
{
case clang::Type::ConstantArray:
+ case clang::Type::IncompleteArray:
+ case clang::Type::VariableArray:
{
const clang::ArrayType *array_type = dyn_cast<clang::ArrayType>(qual_type.getTypePtr());
@@ -167,6 +170,9 @@ GetCompleteQualType (clang::ASTContext *
case clang::Type::Elaborated:
return GetCompleteQualType (ast, cast<ElaboratedType>(qual_type)->getNamedType(), allow_completion);
+ case clang::Type::Paren:
+ return GetCompleteQualType (ast, cast<ParenType>(qual_type)->desugar(), allow_completion);
+
default:
break;
}
@@ -193,7 +199,6 @@ ConvertAccessTypeToObjCIvarAccessControl
{
switch (access)
{
- default: break;
case eAccessNone: return ObjCIvarDecl::None;
case eAccessPublic: return ObjCIvarDecl::Public;
case eAccessPrivate: return ObjCIvarDecl::Private;
@@ -257,15 +262,17 @@ ParseLangArgs
}
const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
- Opts.BCPLComment = Std.hasBCPLComments();
+ Opts.LineComment = Std.hasLineComments();
Opts.C99 = Std.isC99();
Opts.CPlusPlus = Std.isCPlusPlus();
- Opts.CPlusPlus0x = Std.isCPlusPlus0x();
+ Opts.CPlusPlus11 = Std.isCPlusPlus11();
Opts.Digraphs = Std.hasDigraphs();
Opts.GNUMode = Std.isGNUMode();
Opts.GNUInline = !Std.isC99();
Opts.HexFloats = Std.hasHexFloats();
Opts.ImplicitInt = Std.hasImplicitInt();
+
+ Opts.WChar = true;
// OpenCL has some additional defaults.
if (LangStd == LangStandard::lang_opencl) {
@@ -298,7 +305,7 @@ ParseLangArgs
// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
// "default");
// if (Vis == "default")
- Opts.setVisibilityMode(DefaultVisibility);
+ Opts.setValueVisibilityMode(DefaultVisibility);
// else if (Vis == "hidden")
// Opts.setVisibilityMode(LangOptions::Hidden);
// else if (Vis == "protected")
@@ -358,7 +365,7 @@ ParseLangArgs
// inlining enabled.
//
// FIXME: This is affected by other options (-fno-inline).
- Opts.NoInline = !Opt;
+ Opts.NoInlineDefine = !Opt;
// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
// switch (SSP) {
@@ -379,7 +386,7 @@ ClangASTContext::ClangASTContext (const
m_language_options_ap(),
m_source_manager_ap(),
m_diagnostics_engine_ap(),
- m_target_options_ap(),
+ m_target_options_rp(),
m_target_info_ap(),
m_identifier_table_ap(),
m_selector_table_ap(),
@@ -402,7 +409,7 @@ ClangASTContext::~ClangASTContext()
m_selector_table_ap.reset();
m_identifier_table_ap.reset();
m_target_info_ap.reset();
- m_target_options_ap.reset();
+ m_target_options_rp.reset();
m_diagnostics_engine_ap.reset();
m_source_manager_ap.reset();
m_language_options_ap.reset();
@@ -417,7 +424,7 @@ ClangASTContext::Clear()
m_language_options_ap.reset();
m_source_manager_ap.reset();
m_diagnostics_engine_ap.reset();
- m_target_options_ap.reset();
+ m_target_options_rp.reset();
m_target_info_ap.reset();
m_identifier_table_ap.reset();
m_selector_table_ap.reset();
@@ -565,7 +572,7 @@ ClangASTContext::getDiagnosticsEngine()
if (m_diagnostics_engine_ap.get() == NULL)
{
llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
- m_diagnostics_engine_ap.reset(new DiagnosticsEngine(diag_id_sp));
+ m_diagnostics_engine_ap.reset(new DiagnosticsEngine(diag_id_sp, new DiagnosticOptions()));
}
return m_diagnostics_engine_ap.get();
}
@@ -594,7 +601,7 @@ public:
return new NullDiagnosticConsumer ();
}
private:
- LogSP m_log;
+ Log * m_log;
};
DiagnosticConsumer *
@@ -609,13 +616,14 @@ ClangASTContext::getDiagnosticConsumer()
TargetOptions *
ClangASTContext::getTargetOptions()
{
- if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
+ if (m_target_options_rp.getPtr() == NULL && !m_target_triple.empty())
{
- m_target_options_ap.reset (new TargetOptions());
- if (m_target_options_ap.get())
- m_target_options_ap->Triple = m_target_triple;
+ m_target_options_rp.reset ();
+ m_target_options_rp = new TargetOptions();
+ if (m_target_options_rp.getPtr() != NULL)
+ m_target_options_rp->Triple = m_target_triple;
}
- return m_target_options_ap.get();
+ return m_target_options_rp.getPtr();
}
@@ -624,7 +632,7 @@ ClangASTContext::getTargetInfo()
{
// target_triple should be something like "x86_64-apple-macosx"
if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
- m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnosticsEngine(), *getTargetOptions()));
+ m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnosticsEngine(), getTargetOptions()));
return m_target_info_ap.get();
}
@@ -706,8 +714,6 @@ ClangASTContext::GetBuiltinTypeForEncodi
if (bit_size && !(bit_size & 0x7u))
return ast->getExtVectorType (ast->UnsignedCharTy, bit_size/8).getAsOpaquePtr();
break;
- default:
- break;
}
return NULL;
@@ -943,6 +949,12 @@ ClangASTContext::GetBuiltInType_objc_id(
return getASTContext()->getObjCIdType().getAsOpaquePtr();
}
+lldb::clang_type_t
+ClangASTContext::GetBuiltInType_objc_id(clang::ASTContext *ast)
+{
+ return ast->getObjCIdType().getAsOpaquePtr();
+}
+
clang_type_t
ClangASTContext::GetBuiltInType_objc_Class()
{
@@ -1125,7 +1137,12 @@ ClangASTContext::GetTypeForDecl (ObjCInt
#pragma mark Structure, Unions, Classes
clang_type_t
-ClangASTContext::CreateRecordType (DeclContext *decl_ctx, AccessType access_type, const char *name, int kind, LanguageType language, uint64_t metadata)
+ClangASTContext::CreateRecordType (DeclContext *decl_ctx,
+ AccessType access_type,
+ const char *name,
+ int kind,
+ LanguageType language,
+ ClangASTMetadata *metadata)
{
ASTContext *ast = getASTContext();
assert (ast != NULL);
@@ -1154,20 +1171,24 @@ ClangASTContext::CreateRecordType (DeclC
name && name[0] ? &ast->Idents.get(name) : NULL);
if (decl)
- SetMetadata(ast, (uintptr_t)decl, metadata);
-
- if (decl_ctx)
{
+ if (metadata)
+ SetMetadata(ast, decl, *metadata);
+
if (access_type != eAccessNone)
decl->setAccess (ConvertAccessTypeToAccessSpecifier (access_type));
- decl_ctx->addDecl (decl);
+
+ if (decl_ctx)
+ decl_ctx->addDecl (decl);
+
+ return ast->getTagDeclType(decl).getAsOpaquePtr();
}
- return ast->getTagDeclType(decl).getAsOpaquePtr();
+ return NULL;
}
static TemplateParameterList *
CreateTemplateParameterList (ASTContext *ast,
- const ClangASTContext::TemplateParameterInfos &template_param_infos,
+ const ClangASTContext::TemplateParameterInfos &template_param_infos,
llvm::SmallVector<NamedDecl *, 8> &template_param_decls)
{
const bool parameter_pack = false;
@@ -1177,7 +1198,11 @@ CreateTemplateParameterList (ASTContext
for (size_t i=0; i<num_template_params; ++i)
{
const char *name = template_param_infos.names[i];
- if (template_param_infos.args[i].getAsIntegral())
+
+ IdentifierInfo *identifier_info = NULL;
+ if (name && name[0])
+ identifier_info = &ast->Idents.get(name);
+ if (template_param_infos.args[i].getKind() == TemplateArgument::Integral)
{
template_param_decls.push_back (NonTypeTemplateParmDecl::Create (*ast,
ast->getTranslationUnitDecl(), // Is this the right decl context?, SourceLocation StartLoc,
@@ -1185,7 +1210,7 @@ CreateTemplateParameterList (ASTContext
SourceLocation(),
depth,
i,
- &ast->Idents.get(name),
+ identifier_info,
template_param_infos.args[i].getIntegralType(),
parameter_pack,
NULL));
@@ -1199,7 +1224,7 @@ CreateTemplateParameterList (ASTContext
SourceLocation(),
depth,
i,
- &ast->Idents.get(name),
+ identifier_info,
is_typename,
parameter_pack));
}
@@ -1278,9 +1303,10 @@ ClangASTContext::CreateClassTemplateDecl
DeclarationName decl_name (&identifier_info);
clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
- for (clang::DeclContext::lookup_iterator pos = result.first, end = result.second; pos != end; ++pos)
+
+ for (NamedDecl *decl : result)
{
- class_template_decl = dyn_cast<clang::ClassTemplateDecl>(*pos);
+ class_template_decl = dyn_cast<clang::ClassTemplateDecl>(decl);
if (class_template_decl)
return class_template_decl;
}
@@ -1307,8 +1333,8 @@ ClangASTContext::CreateClassTemplateDecl
// With templated classes, we say that a class is templated with
// specializations, but that the bare class has no functions.
- template_cxx_decl->startDefinition();
- template_cxx_decl->completeDefinition();
+ //template_cxx_decl->startDefinition();
+ //template_cxx_decl->completeDefinition();
class_template_decl = ClassTemplateDecl::Create (*ast,
decl_ctx, // What decl context do we use here? TU? The actual decl context?
@@ -1354,6 +1380,8 @@ ClangASTContext::CreateClassTemplateSpec
template_param_infos.args.size(),
NULL);
+ class_template_specialization_decl->setSpecializationKind(TSK_ExplicitSpecialization);
+
return class_template_specialization_decl;
}
@@ -1429,6 +1457,9 @@ ClangASTContext::SetHasExternalStorage (
case clang::Type::Elaborated:
return ClangASTContext::SetHasExternalStorage (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), has_extern);
+ case clang::Type::Paren:
+ return ClangASTContext::SetHasExternalStorage (cast<ParenType>(qual_type)->desugar().getAsOpaquePtr(), has_extern);
+
default:
break;
}
@@ -1744,6 +1775,9 @@ ClangASTContext::AddMethodToCXXRecordTyp
CXXDestructorDecl *cxx_dtor_decl(NULL);
CXXConstructorDecl *cxx_ctor_decl(NULL);
+ if (is_artificial)
+ return NULL; // skip everything artificial
+
if (name[0] == '~')
{
cxx_dtor_decl = CXXDestructorDecl::Create (*ast,
@@ -1772,8 +1806,9 @@ ClangASTContext::AddMethodToCXXRecordTyp
}
else
{
-
+ clang::StorageClass SC = is_static ? SC_Static : SC_None;
OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
+
if (IsOperator (name, op_kind))
{
if (op_kind != NUM_OVERLOADED_OPERATORS)
@@ -1791,8 +1826,7 @@ ClangASTContext::AddMethodToCXXRecordTyp
DeclarationNameInfo (ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
method_qual_type,
NULL, // TypeSourceInfo *
- is_static,
- SC_None,
+ SC,
is_inline,
false /*is_constexpr*/,
SourceLocation());
@@ -1821,8 +1855,7 @@ ClangASTContext::AddMethodToCXXRecordTyp
DeclarationNameInfo (decl_name, SourceLocation()),
method_qual_type,
NULL, // TypeSourceInfo *
- is_static,
- SC_None,
+ SC,
is_inline,
false /*is_constexpr*/,
SourceLocation());
@@ -1853,7 +1886,6 @@ ClangASTContext::AddMethodToCXXRecordTyp
method_function_prototype->getArgType(param_index),
NULL,
SC_None,
- SC_None,
NULL));
}
@@ -1948,15 +1980,15 @@ ClangASTContext::AddFieldToRecordType
bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
}
field = FieldDecl::Create (*ast,
- record_decl,
- SourceLocation(),
- SourceLocation(),
- name ? &identifier_table->get(name) : NULL, // Identifier
- QualType::getFromOpaquePtr(field_type), // Field type
- NULL, // TInfo *
- bit_width, // BitWidth
- false, // Mutable
- false); // HasInit
+ record_decl,
+ SourceLocation(),
+ SourceLocation(),
+ name ? &identifier_table->get(name) : NULL, // Identifier
+ QualType::getFromOpaquePtr(field_type), // Field type
+ NULL, // TInfo *
+ bit_width, // BitWidth
+ false, // Mutable
+ ICIS_NoInit); // HasInit
if (!name) {
// Determine whether this field corresponds to an anonymous
@@ -1971,10 +2003,10 @@ ClangASTContext::AddFieldToRecordType
}
}
- field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
-
if (field)
{
+ field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
+
record_decl->addDecl(field);
#ifdef LLDB_CONFIGURATION_DEBUG
@@ -1989,18 +2021,63 @@ ClangASTContext::AddFieldToRecordType
{
bool is_synthesized = false;
field = ClangASTContext::AddObjCClassIVar (ast,
- record_clang_type,
- name,
- field_type,
- access,
- bitfield_bit_size,
- is_synthesized);
+ record_clang_type,
+ name,
+ field_type,
+ access,
+ bitfield_bit_size,
+ is_synthesized);
}
}
}
return field;
}
+clang::VarDecl *
+ClangASTContext::AddVariableToRecordType (clang::ASTContext *ast,
+ lldb::clang_type_t record_opaque_type,
+ const char *name,
+ lldb::clang_type_t var_type,
+ AccessType access)
+{
+ clang::VarDecl *var_decl = NULL;
+
+ if (record_opaque_type == NULL || var_type == NULL)
+ return NULL;
+
+ IdentifierTable *identifier_table = &ast->Idents;
+
+ assert (ast != NULL);
+ assert (identifier_table != NULL);
+
+ const RecordType *record_type = dyn_cast<RecordType>(QualType::getFromOpaquePtr(record_opaque_type).getTypePtr());
+
+ if (record_type)
+ {
+ RecordDecl *record_decl = record_type->getDecl();
+
+ var_decl = VarDecl::Create (*ast, // ASTContext &
+ record_decl, // DeclContext *
+ SourceLocation(), // SourceLocation StartLoc
+ SourceLocation(), // SourceLocation IdLoc
+ name ? &identifier_table->get(name) : NULL, // IdentifierInfo *
+ QualType::getFromOpaquePtr(var_type), // Variable QualType
+ NULL, // TypeSourceInfo *
+ SC_Static); // StorageClass
+ if (var_decl)
+ {
+ var_decl->setAccess(ConvertAccessTypeToAccessSpecifier (access));
+ record_decl->addDecl(var_decl);
+
+#ifdef LLDB_CONFIGURATION_DEBUG
+ VerifyDecl(var_decl);
+#endif
+ }
+ }
+ return var_decl;
+}
+
+
static clang::AccessSpecifier UnifyAccessSpecifiers (clang::AccessSpecifier lhs,
clang::AccessSpecifier rhs)
{
@@ -2044,14 +2121,14 @@ ClangASTContext::BuildIndirectFields (cl
typedef llvm::SmallVector <IndirectFieldDecl *, 1> IndirectFieldVector;
IndirectFieldVector indirect_fields;
-
- for (RecordDecl::field_iterator fi = record_decl->field_begin(), fe = record_decl->field_end();
- fi != fe;
- ++fi)
+ RecordDecl::field_iterator field_pos;
+ RecordDecl::field_iterator field_end_pos = record_decl->field_end();
+ RecordDecl::field_iterator last_field_pos = field_end_pos;
+ for (field_pos = record_decl->field_begin(); field_pos != field_end_pos; last_field_pos = field_pos++)
{
- if (fi->isAnonymousStructOrUnion())
+ if (field_pos->isAnonymousStructOrUnion())
{
- QualType field_qual_type = fi->getType();
+ QualType field_qual_type = field_pos->getType();
const RecordType *field_record_type = field_qual_type->getAs<RecordType>();
@@ -2070,7 +2147,7 @@ ClangASTContext::BuildIndirectFields (cl
if (FieldDecl *nested_field_decl = dyn_cast<FieldDecl>(*di))
{
NamedDecl **chain = new (*ast) NamedDecl*[2];
- chain[0] = *fi;
+ chain[0] = *field_pos;
chain[1] = nested_field_decl;
IndirectFieldDecl *indirect_field = IndirectFieldDecl::Create(*ast,
record_decl,
@@ -2080,7 +2157,7 @@ ClangASTContext::BuildIndirectFields (cl
chain,
2);
- indirect_field->setAccess(UnifyAccessSpecifiers(fi->getAccess(),
+ indirect_field->setAccess(UnifyAccessSpecifiers(field_pos->getAccess(),
nested_field_decl->getAccess()));
indirect_fields.push_back(indirect_field);
@@ -2089,7 +2166,7 @@ ClangASTContext::BuildIndirectFields (cl
{
int nested_chain_size = nested_indirect_field_decl->getChainingSize();
NamedDecl **chain = new (*ast) NamedDecl*[nested_chain_size + 1];
- chain[0] = *fi;
+ chain[0] = *field_pos;
int chain_index = 1;
for (IndirectFieldDecl::chain_iterator nci = nested_indirect_field_decl->chain_begin(),
@@ -2109,7 +2186,7 @@ ClangASTContext::BuildIndirectFields (cl
chain,
nested_chain_size + 1);
- indirect_field->setAccess(UnifyAccessSpecifiers(fi->getAccess(),
+ indirect_field->setAccess(UnifyAccessSpecifiers(field_pos->getAccess(),
nested_indirect_field_decl->getAccess()));
indirect_fields.push_back(indirect_field);
@@ -2118,6 +2195,14 @@ ClangASTContext::BuildIndirectFields (cl
}
}
+ // Check the last field to see if it has an incomplete array type as its
+ // last member and if it does, the tell the record decl about it
+ if (last_field_pos != field_end_pos)
+ {
+ if (last_field_pos->getType()->isIncompleteArrayType())
+ record_decl->hasFlexibleArrayMember();
+ }
+
for (IndirectFieldVector::iterator ifi = indirect_fields.begin(), ife = indirect_fields.end();
ifi < ife;
++ifi)
@@ -2223,7 +2308,7 @@ ClangASTContext::CreateBaseClassSpecifie
is_virtual,
base_of_class,
ConvertAccessTypeToAccessSpecifier (access),
- getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)),
+ getASTContext()->getTrivialTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)),
SourceLocation());
return NULL;
}
@@ -2261,7 +2346,7 @@ ClangASTContext::CreateObjCClass
DeclContext *decl_ctx,
bool isForwardDecl,
bool isInternal,
- uint64_t metadata
+ ClangASTMetadata *metadata
)
{
ASTContext *ast = getASTContext();
@@ -2284,8 +2369,8 @@ ClangASTContext::CreateObjCClass
/*isForwardDecl,*/
isInternal);
- if (decl)
- SetMetadata(ast, (uintptr_t)decl, metadata);
+ if (decl && metadata)
+ SetMetadata(ast, decl, *metadata);
return ast->getObjCInterfaceType(decl).getAsOpaquePtr();
}
@@ -2365,7 +2450,7 @@ ClangASTContext::AddObjCClassIVar
class_interface_decl,
SourceLocation(),
SourceLocation(),
- &identifier_table->get(name), // Identifier
+ name ? &identifier_table->get(name) : NULL, // Identifier
QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
NULL, // TypeSourceInfo *
ConvertAccessTypeToObjCIvarAccessControl (access),
@@ -2399,7 +2484,7 @@ ClangASTContext::AddObjCClassProperty
const char *property_setter_name,
const char *property_getter_name,
uint32_t property_attributes,
- uint64_t metadata
+ ClangASTMetadata *metadata
)
{
if (class_opaque_type == NULL || property_name == NULL || property_name[0] == '\0')
@@ -2431,9 +2516,9 @@ ClangASTContext::AddObjCClassProperty
{
clang::TypeSourceInfo *prop_type_source;
if (ivar_decl)
- prop_type_source = ast->CreateTypeSourceInfo (ivar_decl->getType());
+ prop_type_source = ast->getTrivialTypeSourceInfo (ivar_decl->getType());
else
- prop_type_source = ast->CreateTypeSourceInfo (QualType::getFromOpaquePtr(property_opaque_type));
+ prop_type_source = ast->getTrivialTypeSourceInfo (QualType::getFromOpaquePtr(property_opaque_type));
ObjCPropertyDecl *property_decl = ObjCPropertyDecl::Create(*ast,
class_interface_decl,
@@ -2446,7 +2531,8 @@ ClangASTContext::AddObjCClassProperty
if (property_decl)
{
- SetMetadata(ast, (uintptr_t)property_decl, metadata);
+ if (metadata)
+ SetMetadata(ast, property_decl, *metadata);
class_interface_decl->addDecl (property_decl);
@@ -2525,8 +2611,8 @@ ClangASTContext::AddObjCClassProperty
impControl,
HasRelatedResultType);
- if (getter)
- SetMetadata(ast, (uintptr_t)getter, metadata);
+ if (getter && metadata)
+ SetMetadata(ast, getter, *metadata);
getter->setMethodParams(*ast, ArrayRef<ParmVarDecl*>(), ArrayRef<SourceLocation>());
@@ -2560,8 +2646,8 @@ ClangASTContext::AddObjCClassProperty
impControl,
HasRelatedResultType);
- if (setter)
- SetMetadata(ast, (uintptr_t)setter, metadata);
+ if (setter && metadata)
+ SetMetadata(ast, setter, *metadata);
llvm::SmallVector<ParmVarDecl *, 1> params;
@@ -2572,7 +2658,6 @@ ClangASTContext::AddObjCClassProperty
NULL, // anonymous
QualType::getFromOpaquePtr(property_opaque_type_to_access),
NULL,
- SC_Auto,
SC_Auto,
NULL));
@@ -2622,14 +2707,12 @@ ClangASTContext::ObjCDeclHasIVars (ObjCI
}
ObjCMethodDecl *
-ClangASTContext::AddMethodToObjCObjectType
-(
- ASTContext *ast,
- clang_type_t class_opaque_type,
- const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
- clang_type_t method_opaque_type,
- lldb::AccessType access
-)
+ClangASTContext::AddMethodToObjCObjectType (ASTContext *ast,
+ clang_type_t class_opaque_type,
+ const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
+ clang_type_t method_opaque_type,
+ lldb::AccessType access,
+ bool is_artificial)
{
if (class_opaque_type == NULL || method_opaque_type == NULL)
return NULL;
@@ -2660,8 +2743,6 @@ ClangASTContext::AddMethodToObjCObjectTy
return NULL;
selector_start++;
- if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
- return NULL;
llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
size_t len = 0;
@@ -2709,6 +2790,9 @@ ClangASTContext::AddMethodToObjCObjectTy
ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
const unsigned num_args = method_function_prototype->getNumArgs();
+
+ if (num_args != num_selectors_with_args)
+ return NULL; // some debug information is corrupt. We are not going to deal with it.
ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast,
SourceLocation(), // beginLoc,
@@ -2720,7 +2804,7 @@ ClangASTContext::AddMethodToObjCObjectTy
name[0] == '-',
is_variadic,
is_synthesized,
- true, // is_implicitly_declared
+ true, // is_implicitly_declared; we force this to true because we don't have source locations
is_defined,
imp_control,
false /*has_related_result_type*/);
@@ -2742,7 +2826,6 @@ ClangASTContext::AddMethodToObjCObjectTy
NULL, // anonymous
method_function_prototype->getArgType(param_index),
NULL,
- SC_Auto,
SC_Auto,
NULL));
}
@@ -2784,6 +2867,13 @@ ClangASTContext::GetNumTemplateArguments
case clang::Type::Typedef:
return ClangASTContext::GetNumTemplateArguments (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+
+ case clang::Type::Elaborated:
+ return ClangASTContext::GetNumTemplateArguments (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+
+ case clang::Type::Paren:
+ return ClangASTContext::GetNumTemplateArguments(ast, cast<ParenType>(qual_type)->desugar().getAsOpaquePtr());
+
default:
break;
}
@@ -2857,6 +2947,13 @@ ClangASTContext::GetTemplateArgument (cl
case clang::Type::Typedef:
return ClangASTContext::GetTemplateArgument (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), arg_idx, kind);
+
+ case clang::Type::Elaborated:
+ return ClangASTContext::GetTemplateArgument (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), arg_idx, kind);
+
+ case clang::Type::Paren:
+ return ClangASTContext::GetTemplateArgument(ast, cast<ParenType>(qual_type)->desugar().getAsOpaquePtr(), arg_idx, kind);
+
default:
break;
}
@@ -2885,48 +2982,78 @@ ClangASTContext::GetTypeInfo
switch (type_class)
{
case clang::Type::Builtin:
- switch (cast<clang::BuiltinType>(qual_type)->getKind())
{
- case clang::BuiltinType::ObjCId:
- case clang::BuiltinType::ObjCClass:
- if (ast && pointee_or_element_clang_type)
- *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
- return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
+ const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
+
+ uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
+ switch (builtin_type->getKind())
+ {
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ if (ast && pointee_or_element_clang_type)
+ *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
+ builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
break;
- case clang::BuiltinType::Bool:
- case clang::BuiltinType::Char_U:
- case clang::BuiltinType::UChar:
- case clang::BuiltinType::WChar_U:
- case clang::BuiltinType::Char16:
- case clang::BuiltinType::Char32:
- case clang::BuiltinType::UShort:
- case clang::BuiltinType::UInt:
- case clang::BuiltinType::ULong:
- case clang::BuiltinType::ULongLong:
- case clang::BuiltinType::UInt128:
- case clang::BuiltinType::Char_S:
- case clang::BuiltinType::SChar:
- case clang::BuiltinType::WChar_S:
- case clang::BuiltinType::Short:
- case clang::BuiltinType::Int:
- case clang::BuiltinType::Long:
- case clang::BuiltinType::LongLong:
- case clang::BuiltinType::Int128:
- case clang::BuiltinType::Float:
- case clang::BuiltinType::Double:
- case clang::BuiltinType::LongDouble:
- return eTypeIsBuiltIn | eTypeHasValue | eTypeIsScalar;
- default:
- break;
+
+ case clang::BuiltinType::ObjCSel:
+ case clang::BuiltinType::Bool:
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::WChar_U:
+ case clang::BuiltinType::Char16:
+ case clang::BuiltinType::Char32:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::ULongLong:
+ case clang::BuiltinType::UInt128:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::Int128:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+ builtin_type_flags |= eTypeIsScalar;
+ if (builtin_type->isInteger())
+ {
+ builtin_type_flags |= eTypeIsInteger;
+ if (builtin_type->isSignedInteger())
+ builtin_type_flags |= eTypeIsSigned;
+ }
+ else if (builtin_type->isFloatingPoint())
+ builtin_type_flags |= eTypeIsFloat;
+ break;
+ default:
+ break;
+ }
+ return builtin_type_flags;
}
- return eTypeIsBuiltIn | eTypeHasValue;
- case clang::Type::BlockPointer:
+ case clang::Type::BlockPointer:
if (pointee_or_element_clang_type)
*pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
- case clang::Type::Complex: return eTypeIsBuiltIn | eTypeHasValue;
+ case clang::Type::Complex:
+ {
+ uint32_t complex_type_flags = eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex;
+ const ComplexType *complex_type = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal());
+ if (complex_type)
+ {
+ QualType complex_element_type (complex_type->getElementType());
+ if (complex_element_type->isIntegerType())
+ complex_type_flags |= eTypeIsFloat;
+ else if (complex_element_type->isFloatingType())
+ complex_type_flags |= eTypeIsInteger;
+ }
+ return complex_type_flags;
+ }
+ break;
case clang::Type::ConstantArray:
case clang::Type::DependentSizedArray:
@@ -2950,7 +3077,12 @@ ClangASTContext::GetTypeInfo
return ClangASTContext::GetTypeInfo (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
ast,
pointee_or_element_clang_type);
- case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
+
+ case clang::Type::Paren:
+ return ClangASTContext::GetTypeInfo(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ ast,
+ pointee_or_element_clang_type);
+
case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
case clang::Type::InjectedClassName: return 0;
@@ -2994,7 +3126,21 @@ ClangASTContext::GetTypeInfo
case clang::Type::TypeOfExpr: return 0;
case clang::Type::TypeOf: return 0;
case clang::Type::UnresolvedUsing: return 0;
- case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
+
+ case clang::Type::ExtVector:
+ case clang::Type::Vector:
+ {
+ uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector;
+ const VectorType *vector_type = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal());
+ if (vector_type)
+ {
+ if (vector_type->isIntegerType())
+ vector_type_flags |= eTypeIsFloat;
+ else if (vector_type->isFloatingType())
+ vector_type_flags |= eTypeIsInteger;
+ }
+ return vector_type_flags;
+ }
default: return 0;
}
return 0;
@@ -3027,7 +3173,8 @@ ClangASTContext::IsAggregateType (clang_
return ClangASTContext::IsAggregateType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
case clang::Type::Typedef:
return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
-
+ case clang::Type::Paren:
+ return ClangASTContext::IsAggregateType (cast<ParenType>(qual_type)->desugar().getAsOpaquePtr());
default:
break;
}
@@ -3149,6 +3296,11 @@ ClangASTContext::GetNumChildren (clang::
}
break;
+ case clang::Type::Vector:
+ case clang::Type::ExtVector:
+ num_children = cast<VectorType>(qual_type.getTypePtr())->getNumElements();
+ break;
+
case clang::Type::ConstantArray:
num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
break;
@@ -3200,6 +3352,12 @@ ClangASTContext::GetNumChildren (clang::
omit_empty_base_classes);
break;
+ case clang::Type::Paren:
+ num_children = ClangASTContext::GetNumChildren(ast,
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ omit_empty_base_classes);
+
+ break;
default:
break;
}
@@ -3250,6 +3408,9 @@ ClangASTContext::GetNumDirectBaseClasses
count = ClangASTContext::GetNumDirectBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
break;
+ case clang::Type::Paren:
+ return ClangASTContext::GetNumDirectBaseClasses(ast, cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
+
default:
break;
}
@@ -3285,6 +3446,10 @@ ClangASTContext::GetNumVirtualBaseClasse
count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
break;
+ case clang::Type::Paren:
+ count = ClangASTContext::GetNumVirtualBaseClasses(ast, cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
+ break;
+
default:
break;
}
@@ -3329,6 +3494,10 @@ ClangASTContext::GetNumFields (clang::AS
count = ClangASTContext::GetNumFields (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
break;
+ case clang::Type::Paren:
+ count = ClangASTContext::GetNumFields(ast, cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
+ break;
+
case clang::Type::ObjCObject:
case clang::Type::ObjCInterface:
if (GetCompleteQualType (ast, qual_type))
@@ -3353,7 +3522,7 @@ ClangASTContext::GetNumFields (clang::AS
clang_type_t
ClangASTContext::GetDirectBaseClassAtIndex (clang::ASTContext *ast,
clang_type_t clang_type,
- uint32_t idx,
+ size_t idx,
uint32_t *bit_offset_ptr)
{
if (clang_type == NULL)
@@ -3429,6 +3598,12 @@ ClangASTContext::GetDirectBaseClassAtInd
idx,
bit_offset_ptr);
+ case clang::Type::Paren:
+ return ClangASTContext::GetDirectBaseClassAtIndex (ast,
+ cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ idx,
+ bit_offset_ptr);
+
default:
break;
}
@@ -3438,7 +3613,7 @@ ClangASTContext::GetDirectBaseClassAtInd
clang_type_t
ClangASTContext::GetVirtualBaseClassAtIndex (clang::ASTContext *ast,
clang_type_t clang_type,
- uint32_t idx,
+ size_t idx,
uint32_t *bit_offset_ptr)
{
if (clang_type == NULL)
@@ -3488,6 +3663,12 @@ ClangASTContext::GetVirtualBaseClassAtIn
idx,
bit_offset_ptr);
+ case clang::Type::Paren:
+ return ClangASTContext::GetVirtualBaseClassAtIndex (ast,
+ cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ idx,
+ bit_offset_ptr);
+
default:
break;
}
@@ -3497,7 +3678,7 @@ ClangASTContext::GetVirtualBaseClassAtIn
clang_type_t
ClangASTContext::GetFieldAtIndex (clang::ASTContext *ast,
clang_type_t clang_type,
- uint32_t idx,
+ size_t idx,
std::string& name,
uint64_t *bit_offset_ptr,
uint32_t *bitfield_bit_size_ptr,
@@ -3638,12 +3819,111 @@ ClangASTContext::GetFieldAtIndex (clang:
bitfield_bit_size_ptr,
is_bitfield_ptr);
+ case clang::Type::Paren:
+ return ClangASTContext::GetFieldAtIndex (ast,
+ cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ idx,
+ name,
+ bit_offset_ptr,
+ bitfield_bit_size_ptr,
+ is_bitfield_ptr);
+
default:
break;
}
return NULL;
}
+size_t
+ClangASTContext::GetIndexOfFieldWithName (clang::ASTContext *ast,
+ lldb::clang_type_t clang_type,
+ const char* name,
+ lldb::clang_type_t* field_clang_type,
+ uint64_t *bit_offset_ptr,
+ uint32_t *bitfield_bit_size_ptr,
+ bool *is_bitfield_ptr)
+{
+ auto count = ClangASTContext::GetNumFields(ast, clang_type);
+ lldb::clang_type_t field_clang_type_internal;
+ std::string field_name;
+ for (auto index = 0; index < count; index++)
+ {
+ field_clang_type_internal = ClangASTContext::GetFieldAtIndex(ast, clang_type, index, field_name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr);
+ if ( strcmp(field_name.c_str(), name) == 0 )
+ {
+ if (field_clang_type)
+ *field_clang_type = field_clang_type_internal;
+ return index;
+ }
+ }
+ return UINT32_MAX;
+}
+
+lldb::BasicType
+ClangASTContext::GetLLDBBasicTypeEnumeration (clang_type_t clang_type)
+{
+ if (clang_type)
+ {
+ QualType qual_type(QualType::getFromOpaquePtr(clang_type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ if (type_class == clang::Type::Builtin)
+ {
+ switch (cast<clang::BuiltinType>(qual_type)->getKind())
+ {
+ case clang::BuiltinType::Void: return eBasicTypeVoid;
+ case clang::BuiltinType::Bool: return eBasicTypeBool;
+ case clang::BuiltinType::Char_S: return eBasicTypeSignedChar;
+ case clang::BuiltinType::Char_U: return eBasicTypeUnsignedChar;
+ case clang::BuiltinType::Char16: return eBasicTypeChar16;
+ case clang::BuiltinType::Char32: return eBasicTypeChar32;
+ case clang::BuiltinType::UChar: return eBasicTypeUnsignedChar;
+ case clang::BuiltinType::SChar: return eBasicTypeSignedChar;
+ case clang::BuiltinType::WChar_S: return eBasicTypeSignedWChar;
+ case clang::BuiltinType::WChar_U: return eBasicTypeUnsignedWChar;
+ case clang::BuiltinType::Short: return eBasicTypeShort;
+ case clang::BuiltinType::UShort: return eBasicTypeUnsignedShort;
+ case clang::BuiltinType::Int: return eBasicTypeInt;
+ case clang::BuiltinType::UInt: return eBasicTypeUnsignedInt;
+ case clang::BuiltinType::Long: return eBasicTypeLong;
+ case clang::BuiltinType::ULong: return eBasicTypeUnsignedLong;
+ case clang::BuiltinType::LongLong: return eBasicTypeLongLong;
+ case clang::BuiltinType::ULongLong: return eBasicTypeUnsignedLongLong;
+ case clang::BuiltinType::Int128: return eBasicTypeInt128;
+ case clang::BuiltinType::UInt128: return eBasicTypeUnsignedInt128;
+
+ case clang::BuiltinType::Half: return eBasicTypeHalf;
+ case clang::BuiltinType::Float: return eBasicTypeFloat;
+ case clang::BuiltinType::Double: return eBasicTypeDouble;
+ case clang::BuiltinType::LongDouble:return eBasicTypeLongDouble;
+
+ case clang::BuiltinType::NullPtr: return eBasicTypeNullPtr;
+ case clang::BuiltinType::ObjCId: return eBasicTypeObjCID;
+ case clang::BuiltinType::ObjCClass: return eBasicTypeObjCClass;
+ case clang::BuiltinType::ObjCSel: return eBasicTypeObjCSel;
+ case clang::BuiltinType::Dependent:
+ case clang::BuiltinType::Overload:
+ case clang::BuiltinType::BoundMember:
+ case clang::BuiltinType::PseudoObject:
+ case clang::BuiltinType::UnknownAny:
+ case clang::BuiltinType::BuiltinFn:
+ case clang::BuiltinType::ARCUnbridgedCast:
+ case clang::BuiltinType::OCLEvent:
+ case clang::BuiltinType::OCLImage1d:
+ case clang::BuiltinType::OCLImage1dArray:
+ case clang::BuiltinType::OCLImage1dBuffer:
+ case clang::BuiltinType::OCLImage2d:
+ case clang::BuiltinType::OCLImage2dArray:
+ case clang::BuiltinType::OCLImage3d:
+ case clang::BuiltinType::OCLSampler:
+ return eBasicTypeOther;
+ }
+ }
+ }
+
+ return eBasicTypeInvalid;
+}
+
+
// If a pointer to a pointee type (the clang_type arg) says that it has no
// children, then we either need to trust it, or override it and return a
@@ -3666,6 +3946,14 @@ ClangASTContext::GetNumPointeeChildren (
case clang::BuiltinType::UnknownAny:
case clang::BuiltinType::Void:
case clang::BuiltinType::NullPtr:
+ case clang::BuiltinType::OCLEvent:
+ case clang::BuiltinType::OCLImage1d:
+ case clang::BuiltinType::OCLImage1dArray:
+ case clang::BuiltinType::OCLImage1dBuffer:
+ case clang::BuiltinType::OCLImage2d:
+ case clang::BuiltinType::OCLImage2dArray:
+ case clang::BuiltinType::OCLImage3d:
+ case clang::BuiltinType::OCLSampler:
return 0;
case clang::BuiltinType::Bool:
case clang::BuiltinType::Char_U:
@@ -3698,6 +3986,7 @@ ClangASTContext::GetNumPointeeChildren (
case clang::BuiltinType::Half:
case clang::BuiltinType::ARCUnbridgedCast:
case clang::BuiltinType::PseudoObject:
+ case clang::BuiltinType::BuiltinFn:
return 1;
}
break;
@@ -3718,7 +4007,7 @@ ClangASTContext::GetNumPointeeChildren (
case clang::Type::FunctionProto: return 0; // When we function pointers, they have no children...
case clang::Type::FunctionNoProto: return 0; // When we function pointers, they have no children...
case clang::Type::UnresolvedUsing: return 0;
- case clang::Type::Paren: return 0;
+ case clang::Type::Paren: return ClangASTContext::GetNumPointeeChildren (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
case clang::Type::Typedef: return ClangASTContext::GetNumPointeeChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
case clang::Type::Elaborated: return ClangASTContext::GetNumPointeeChildren (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
case clang::Type::TypeOfExpr: return 0;
@@ -3747,7 +4036,7 @@ ClangASTContext::GetChildClangTypeAtInde
ExecutionContext *exe_ctx,
const char *parent_name,
clang_type_t parent_clang_type,
- uint32_t idx,
+ size_t idx,
bool transparent_pointers,
bool omit_empty_base_classes,
bool ignore_array_bounds,
@@ -3787,7 +4076,7 @@ ClangASTContext::GetChildClangTypeAtInde
ASTContext *ast,
const char *parent_name,
clang_type_t parent_clang_type,
- uint32_t idx,
+ size_t idx,
bool transparent_pointers,
bool omit_empty_base_classes,
bool ignore_array_bounds,
@@ -3803,17 +4092,19 @@ ClangASTContext::GetChildClangTypeAtInde
if (parent_clang_type == NULL)
return NULL;
- if (idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes))
+ QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
+ const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
+ child_bitfield_bit_size = 0;
+ child_bitfield_bit_offset = 0;
+ child_is_base_class = false;
+
+ const bool idx_is_valid = idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes);
+ uint32_t bit_offset;
+ switch (parent_type_class)
{
- uint32_t bit_offset;
- child_bitfield_bit_size = 0;
- child_bitfield_bit_offset = 0;
- child_is_base_class = false;
- QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
- const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
- switch (parent_type_class)
+ case clang::Type::Builtin:
+ if (idx_is_valid)
{
- case clang::Type::Builtin:
switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
{
case clang::BuiltinType::ObjCId:
@@ -3825,270 +4116,296 @@ ClangASTContext::GetChildClangTypeAtInde
default:
break;
}
- break;
+ }
+ break;
- case clang::Type::Record:
- if (GetCompleteQualType (ast, parent_qual_type))
- {
- const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
- const RecordDecl *record_decl = record_type->getDecl();
- assert(record_decl);
- const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
- uint32_t child_idx = 0;
+ case clang::Type::Record:
+ if (idx_is_valid && GetCompleteQualType (ast, parent_qual_type))
+ {
+ const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
+ const RecordDecl *record_decl = record_type->getDecl();
+ assert(record_decl);
+ const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
+ uint32_t child_idx = 0;
- const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
- if (cxx_record_decl)
+ const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+ if (cxx_record_decl)
+ {
+ // We might have base classes to print out first
+ CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end;
+ ++base_class)
{
- // We might have base classes to print out first
- CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
- for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
- base_class != base_class_end;
- ++base_class)
+ const CXXRecordDecl *base_class_decl = NULL;
+
+ // Skip empty base classes
+ if (omit_empty_base_classes)
{
- const CXXRecordDecl *base_class_decl = NULL;
+ base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+ if (RecordHasFields(base_class_decl) == false)
+ continue;
+ }
- // Skip empty base classes
- if (omit_empty_base_classes)
- {
+ if (idx == child_idx)
+ {
+ if (base_class_decl == NULL)
base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
- if (RecordHasFields(base_class_decl) == false)
- continue;
- }
-
- if (idx == child_idx)
- {
- if (base_class_decl == NULL)
- base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
- if (base_class->isVirtual())
- bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
- else
- bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
+ if (base_class->isVirtual())
+ bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
+ else
+ bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
- // Base classes should be a multiple of 8 bits in size
- child_byte_offset = bit_offset/8;
-
- child_name = ClangASTType::GetTypeNameForQualType(ast, base_class->getType());
+ // Base classes should be a multiple of 8 bits in size
+ child_byte_offset = bit_offset/8;
+
+ child_name = ClangASTType::GetTypeNameForQualType(ast, base_class->getType());
- uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType());
+ uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType());
- // Base classes bit sizes should be a multiple of 8 bits in size
- assert (clang_type_info_bit_size % 8 == 0);
- child_byte_size = clang_type_info_bit_size / 8;
- child_is_base_class = true;
- return base_class->getType().getAsOpaquePtr();
- }
- // We don't increment the child index in the for loop since we might
- // be skipping empty base classes
- ++child_idx;
+ // Base classes bit sizes should be a multiple of 8 bits in size
+ assert (clang_type_info_bit_size % 8 == 0);
+ child_byte_size = clang_type_info_bit_size / 8;
+ child_is_base_class = true;
+ return base_class->getType().getAsOpaquePtr();
}
+ // We don't increment the child index in the for loop since we might
+ // be skipping empty base classes
+ ++child_idx;
}
- // Make sure index is in range...
- uint32_t field_idx = 0;
- RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
+ }
+ // Make sure index is in range...
+ uint32_t field_idx = 0;
+ RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
+ {
+ if (idx == child_idx)
{
- if (idx == child_idx)
- {
- // Print the member type if requested
- // Print the member name and equal sign
- child_name.assign(field->getNameAsString().c_str());
+ // Print the member type if requested
+ // Print the member name and equal sign
+ child_name.assign(field->getNameAsString().c_str());
- // Figure out the type byte size (field_type_info.first) and
- // alignment (field_type_info.second) from the AST context.
- std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType());
- assert(field_idx < record_layout.getFieldCount());
+ // Figure out the type byte size (field_type_info.first) and
+ // alignment (field_type_info.second) from the AST context.
+ std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType());
+ assert(field_idx < record_layout.getFieldCount());
- child_byte_size = field_type_info.first / 8;
+ child_byte_size = field_type_info.first / 8;
- // Figure out the field offset within the current struct/union/class type
- bit_offset = record_layout.getFieldOffset (field_idx);
- child_byte_offset = bit_offset / 8;
- if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size))
- child_bitfield_bit_offset = bit_offset % 8;
+ // Figure out the field offset within the current struct/union/class type
+ bit_offset = record_layout.getFieldOffset (field_idx);
+ child_byte_offset = bit_offset / 8;
+ if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size))
+ child_bitfield_bit_offset = bit_offset % 8;
- return field->getType().getAsOpaquePtr();
- }
+ return field->getType().getAsOpaquePtr();
}
}
- break;
+ }
+ break;
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (GetCompleteQualType (ast, parent_qual_type))
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (idx_is_valid && GetCompleteQualType (ast, parent_qual_type))
+ {
+ const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
+ assert (objc_class_type);
+ if (objc_class_type)
{
- const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
- assert (objc_class_type);
- if (objc_class_type)
+ uint32_t child_idx = 0;
+ ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+
+ if (class_interface_decl)
{
- uint32_t child_idx = 0;
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl)
+
+ const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
+ ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+ if (superclass_interface_decl)
{
-
- const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
- ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
- if (superclass_interface_decl)
+ if (omit_empty_base_classes)
{
- if (omit_empty_base_classes)
+ if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
{
- if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
+ if (idx == 0)
{
- if (idx == 0)
- {
- QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
-
-
- child_name.assign(superclass_interface_decl->getNameAsString().c_str());
+ QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
+
- std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
+ child_name.assign(superclass_interface_decl->getNameAsString().c_str());
- child_byte_size = ivar_type_info.first / 8;
- child_byte_offset = 0;
- child_is_base_class = true;
+ std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
- return ivar_qual_type.getAsOpaquePtr();
- }
+ child_byte_size = ivar_type_info.first / 8;
+ child_byte_offset = 0;
+ child_is_base_class = true;
- ++child_idx;
+ return ivar_qual_type.getAsOpaquePtr();
}
- }
- else
+
++child_idx;
+ }
}
-
- const uint32_t superclass_idx = child_idx;
+ else
+ ++child_idx;
+ }
+
+ const uint32_t superclass_idx = child_idx;
- if (idx < (child_idx + class_interface_decl->ivar_size()))
+ if (idx < (child_idx + class_interface_decl->ivar_size()))
+ {
+ ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
+
+ for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
{
- ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
-
- for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
+ if (child_idx == idx)
{
- if (child_idx == idx)
+ ObjCIvarDecl* ivar_decl = *ivar_pos;
+
+ QualType ivar_qual_type(ivar_decl->getType());
+
+ child_name.assign(ivar_decl->getNameAsString().c_str());
+
+ std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
+
+ child_byte_size = ivar_type_info.first / 8;
+
+ // Figure out the field offset within the current struct/union/class type
+ // For ObjC objects, we can't trust the bit offset we get from the Clang AST, since
+ // that doesn't account for the space taken up by unbacked properties, or from
+ // the changing size of base classes that are newer than this class.
+ // So if we have a process around that we can ask about this object, do so.
+ child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
+ Process *process = NULL;
+ if (exe_ctx)
+ process = exe_ctx->GetProcessPtr();
+ if (process)
{
- ObjCIvarDecl* ivar_decl = *ivar_pos;
-
- QualType ivar_qual_type(ivar_decl->getType());
-
- child_name.assign(ivar_decl->getNameAsString().c_str());
-
- std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
-
- child_byte_size = ivar_type_info.first / 8;
-
- // Figure out the field offset within the current struct/union/class type
- // For ObjC objects, we can't trust the bit offset we get from the Clang AST, since
- // that doesn't account for the space taken up by unbacked properties, or from
- // the changing size of base classes that are newer than this class.
- // So if we have a process around that we can ask about this object, do so.
- child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
- Process *process = NULL;
- if (exe_ctx)
- process = exe_ctx->GetProcessPtr();
- if (process)
+ ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
+ if (objc_runtime != NULL)
{
- ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
- if (objc_runtime != NULL)
- {
- ClangASTType parent_ast_type (ast, parent_qual_type.getAsOpaquePtr());
- child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str());
- }
+ ClangASTType parent_ast_type (ast, parent_qual_type.getAsOpaquePtr());
+ child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str());
}
-
- // Setting this to UINT32_MAX to make sure we don't compute it twice...
- bit_offset = UINT32_MAX;
-
- if (child_byte_offset == LLDB_INVALID_IVAR_OFFSET)
- {
+ }
+
+ // Setting this to UINT32_MAX to make sure we don't compute it twice...
+ bit_offset = UINT32_MAX;
+
+ if (child_byte_offset == LLDB_INVALID_IVAR_OFFSET)
+ {
+ bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
+ child_byte_offset = bit_offset / 8;
+ }
+
+ // Note, the ObjC Ivar Byte offset is just that, it doesn't account for the bit offset
+ // of a bitfield within its containing object. So regardless of where we get the byte
+ // offset from, we still need to get the bit offset for bitfields from the layout.
+
+ if (ClangASTContext::FieldIsBitfield (ast, ivar_decl, child_bitfield_bit_size))
+ {
+ if (bit_offset == UINT32_MAX)
bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
- child_byte_offset = bit_offset / 8;
- }
-
- // Note, the ObjC Ivar Byte offset is just that, it doesn't account for the bit offset
- // of a bitfield within its containing object. So regardless of where we get the byte
- // offset from, we still need to get the bit offset for bitfields from the layout.
-
- if (ClangASTContext::FieldIsBitfield (ast, ivar_decl, child_bitfield_bit_size))
- {
- if (bit_offset == UINT32_MAX)
- bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
-
- child_bitfield_bit_offset = bit_offset % 8;
- }
- return ivar_qual_type.getAsOpaquePtr();
+
+ child_bitfield_bit_offset = bit_offset % 8;
}
- ++child_idx;
+ return ivar_qual_type.getAsOpaquePtr();
}
+ ++child_idx;
}
}
}
}
- break;
-
- case clang::Type::ObjCObjectPointer:
- {
- const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
- QualType pointee_type = pointer_type->getPointeeType();
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ if (idx_is_valid)
+ {
+ const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
+ QualType pointee_type = pointer_type->getPointeeType();
- if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+ if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+ {
+ child_is_deref_of_parent = false;
+ bool tmp_child_is_deref_of_parent = false;
+ return GetChildClangTypeAtIndex (exe_ctx,
+ ast,
+ parent_name,
+ pointer_type->getPointeeType().getAsOpaquePtr(),
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ ignore_array_bounds,
+ child_name,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ tmp_child_is_deref_of_parent);
+ }
+ else
+ {
+ child_is_deref_of_parent = true;
+ if (parent_name)
{
- child_is_deref_of_parent = false;
- bool tmp_child_is_deref_of_parent = false;
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- pointer_type->getPointeeType().getAsOpaquePtr(),
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- tmp_child_is_deref_of_parent);
+ child_name.assign(1, '*');
+ child_name += parent_name;
}
- else
+
+ // We have a pointer to an simple type
+ if (idx == 0 && GetCompleteQualType(ast, pointee_type))
{
- child_is_deref_of_parent = true;
- if (parent_name)
- {
- child_name.assign(1, '*');
- child_name += parent_name;
- }
+ std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
+ assert(clang_type_info.first % 8 == 0);
+ child_byte_size = clang_type_info.first / 8;
+ child_byte_offset = 0;
+ return pointee_type.getAsOpaquePtr();
+ }
+ }
+ }
+ break;
- // We have a pointer to an simple type
- if (idx == 0 && GetCompleteQualType(ast, pointee_type))
+ case clang::Type::Vector:
+ case clang::Type::ExtVector:
+ if (idx_is_valid)
+ {
+ const VectorType *array = cast<VectorType>(parent_qual_type.getTypePtr());
+ if (array)
+ {
+ if (GetCompleteQualType (ast, array->getElementType()))
{
- std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
- assert(clang_type_info.first % 8 == 0);
- child_byte_size = clang_type_info.first / 8;
- child_byte_offset = 0;
- return pointee_type.getAsOpaquePtr();
+ std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
+
+ char element_name[64];
+ ::snprintf (element_name, sizeof (element_name), "[%zu]", idx);
+
+ child_name.assign(element_name);
+ assert(field_type_info.first % 8 == 0);
+ child_byte_size = field_type_info.first / 8;
+ child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
+ return array->getElementType().getAsOpaquePtr();
}
}
}
break;
case clang::Type::ConstantArray:
+ case clang::Type::IncompleteArray:
+ if (ignore_array_bounds || idx_is_valid)
{
- const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
- const uint64_t element_count = array->getSize().getLimitedValue();
-
- if (ignore_array_bounds || idx < element_count)
+ const ArrayType *array = cast<ArrayType>(parent_qual_type.getTypePtr());
+ if (array)
{
if (GetCompleteQualType (ast, array->getElementType()))
{
std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
-
+
char element_name[64];
- ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
-
+ ::snprintf (element_name, sizeof (element_name), "[%zu]", idx);
+
child_name.assign(element_name);
assert(field_type_info.first % 8 == 0);
child_byte_size = field_type_info.first / 8;
@@ -4098,144 +4415,164 @@ ClangASTContext::GetChildClangTypeAtInde
}
}
break;
+
- case clang::Type::Pointer:
+ case clang::Type::Pointer:
+ if (idx_is_valid)
+ {
+ const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
+ QualType pointee_type = pointer_type->getPointeeType();
+
+ // Don't dereference "void *" pointers
+ if (pointee_type->isVoidType())
+ return NULL;
+
+ if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+ {
+ child_is_deref_of_parent = false;
+ bool tmp_child_is_deref_of_parent = false;
+ return GetChildClangTypeAtIndex (exe_ctx,
+ ast,
+ parent_name,
+ pointer_type->getPointeeType().getAsOpaquePtr(),
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ ignore_array_bounds,
+ child_name,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ tmp_child_is_deref_of_parent);
+ }
+ else
{
- const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
- QualType pointee_type = pointer_type->getPointeeType();
-
- // Don't dereference "void *" pointers
- if (pointee_type->isVoidType())
- return NULL;
+ child_is_deref_of_parent = true;
- if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+ if (parent_name)
{
- child_is_deref_of_parent = false;
- bool tmp_child_is_deref_of_parent = false;
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- pointer_type->getPointeeType().getAsOpaquePtr(),
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- tmp_child_is_deref_of_parent);
+ child_name.assign(1, '*');
+ child_name += parent_name;
}
- else
- {
- child_is_deref_of_parent = true;
-
- if (parent_name)
- {
- child_name.assign(1, '*');
- child_name += parent_name;
- }
- // We have a pointer to an simple type
- if (idx == 0)
- {
- std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
- assert(clang_type_info.first % 8 == 0);
- child_byte_size = clang_type_info.first / 8;
- child_byte_offset = 0;
- return pointee_type.getAsOpaquePtr();
- }
+ // We have a pointer to an simple type
+ if (idx == 0)
+ {
+ std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
+ assert(clang_type_info.first % 8 == 0);
+ child_byte_size = clang_type_info.first / 8;
+ child_byte_offset = 0;
+ return pointee_type.getAsOpaquePtr();
}
}
- break;
+ }
+ break;
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ if (idx_is_valid)
+ {
+ const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
+ QualType pointee_type(reference_type->getPointeeType());
+ clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
+ if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
+ {
+ child_is_deref_of_parent = false;
+ bool tmp_child_is_deref_of_parent = false;
+ return GetChildClangTypeAtIndex (exe_ctx,
+ ast,
+ parent_name,
+ pointee_clang_type,
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ ignore_array_bounds,
+ child_name,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ tmp_child_is_deref_of_parent);
+ }
+ else
{
- const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
- QualType pointee_type(reference_type->getPointeeType());
- clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
- if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
- {
- child_is_deref_of_parent = false;
- bool tmp_child_is_deref_of_parent = false;
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- pointee_clang_type,
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- tmp_child_is_deref_of_parent);
- }
- else
+ if (parent_name)
{
- if (parent_name)
- {
- child_name.assign(1, '&');
- child_name += parent_name;
- }
+ child_name.assign(1, '&');
+ child_name += parent_name;
+ }
- // We have a pointer to an simple type
- if (idx == 0)
- {
- std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
- assert(clang_type_info.first % 8 == 0);
- child_byte_size = clang_type_info.first / 8;
- child_byte_offset = 0;
- return pointee_type.getAsOpaquePtr();
- }
+ // We have a pointer to an simple type
+ if (idx == 0)
+ {
+ std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
+ assert(clang_type_info.first % 8 == 0);
+ child_byte_size = clang_type_info.first / 8;
+ child_byte_offset = 0;
+ return pointee_type.getAsOpaquePtr();
}
}
- break;
+ }
+ break;
- case clang::Type::Typedef:
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- child_is_deref_of_parent);
- break;
-
- case clang::Type::Elaborated:
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- cast<ElaboratedType>(parent_qual_type)->getNamedType().getAsOpaquePtr(),
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- child_is_deref_of_parent);
+ case clang::Type::Typedef:
+ return GetChildClangTypeAtIndex (exe_ctx,
+ ast,
+ parent_name,
+ cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ ignore_array_bounds,
+ child_name,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ child_is_deref_of_parent);
+ break;
- default:
- break;
- }
+ case clang::Type::Elaborated:
+ return GetChildClangTypeAtIndex (exe_ctx,
+ ast,
+ parent_name,
+ cast<ElaboratedType>(parent_qual_type)->getNamedType().getAsOpaquePtr(),
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ ignore_array_bounds,
+ child_name,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ child_is_deref_of_parent);
+
+ case clang::Type::Paren:
+ return GetChildClangTypeAtIndex (exe_ctx,
+ ast,
+ parent_name,
+ llvm::cast<clang::ParenType>(parent_qual_type)->desugar().getAsOpaquePtr(),
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ ignore_array_bounds,
+ child_name,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ child_is_deref_of_parent);
+
+
+ default:
+ break;
}
return NULL;
}
@@ -4492,14 +4829,9 @@ ClangASTContext::GetIndexOfChildMemberWi
parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
}
}
- DeclContext::lookup_iterator named_decl_pos;
- for (named_decl_pos = path->Decls.first;
- named_decl_pos != path->Decls.second && parent_record_decl;
- ++named_decl_pos)
+ for (NamedDecl *path_decl : path->Decls)
{
- //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
-
- child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
+ child_idx = GetIndexForRecordChild (parent_record_decl, path_decl, omit_empty_base_classes);
if (child_idx == UINT32_MAX)
{
child_indexes.clear();
@@ -4682,6 +5014,20 @@ ClangASTContext::GetIndexOfChildMemberWi
omit_empty_base_classes,
child_indexes);
+ case clang::Type::Elaborated:
+ return GetIndexOfChildMemberWithName (ast,
+ cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
+ name,
+ omit_empty_base_classes,
+ child_indexes);
+
+ case clang::Type::Paren:
+ return GetIndexOfChildMemberWithName (ast,
+ cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ name,
+ omit_empty_base_classes,
+ child_indexes);
+
default:
break;
}
@@ -4772,7 +5118,7 @@ ClangASTContext::GetIndexOfChildWithName
ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
- for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
+ for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
{
const ObjCIvarDecl* ivar_decl = *ivar_pos;
@@ -4889,6 +5235,18 @@ ClangASTContext::GetIndexOfChildWithName
}
break;
+ case clang::Type::Elaborated:
+ return GetIndexOfChildWithName (ast,
+ cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
+ name,
+ omit_empty_base_classes);
+
+ case clang::Type::Paren:
+ return GetIndexOfChildWithName (ast,
+ cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ name,
+ omit_empty_base_classes);
+
case clang::Type::Typedef:
return GetIndexOfChildWithName (ast,
cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
@@ -4965,6 +5323,7 @@ ClangASTContext::GetDeclContextForType (
case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
case clang::Type::Elaborated: return ClangASTContext::GetDeclContextForType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+ case clang::Type::Paren: return ClangASTContext::GetDeclContextForType (cast<ParenType>(qual_type)->desugar().getAsOpaquePtr());
case clang::Type::TypeOfExpr: break;
case clang::Type::TypeOf: break;
case clang::Type::Decltype: break;
@@ -4976,7 +5335,6 @@ ClangASTContext::GetDeclContextForType (
case clang::Type::SubstTemplateTypeParmPack:break;
case clang::Type::PackExpansion: break;
case clang::Type::UnresolvedUsing: break;
- case clang::Type::Paren: break;
case clang::Type::Attributed: break;
case clang::Type::Auto: break;
case clang::Type::InjectedClassName: break;
@@ -5003,9 +5361,9 @@ ClangASTContext::GetUniqueNamespaceDecla
IdentifierInfo &identifier_info = ast->Idents.get(name);
DeclarationName decl_name (&identifier_info);
clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
- for (clang::DeclContext::lookup_iterator pos = result.first, end = result.second; pos != end; ++pos)
+ for (NamedDecl *decl : result)
{
- namespace_decl = dyn_cast<clang::NamespaceDecl>(*pos);
+ namespace_decl = dyn_cast<clang::NamespaceDecl>(decl);
if (namespace_decl)
return namespace_decl;
}
@@ -5158,9 +5516,8 @@ ClangASTContext::CreateFunctionType (AST
proto_info.Exceptions = NULL;
return ast->getFunctionType (QualType::getFromOpaquePtr(result_type),
- qual_type_args.empty() ? NULL : &qual_type_args.front(),
- qual_type_args.size(),
- proto_info).getAsOpaquePtr(); // NoReturn);
+ qual_type_args,
+ proto_info).getAsOpaquePtr();
}
ParmVarDecl *
@@ -5176,7 +5533,6 @@ ClangASTContext::CreateParameterDeclarat
QualType::getFromOpaquePtr(param_type),
NULL,
(VarDecl::StorageClass)storage,
- (VarDecl::StorageClass)storage,
0);
}
@@ -5191,17 +5547,40 @@ ClangASTContext::SetFunctionParameters (
#pragma mark Array Types
clang_type_t
-ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
+ClangASTContext::CreateArrayType (clang_type_t element_type,
+ size_t element_count,
+ bool is_vector)
{
if (element_type)
{
ASTContext *ast = getASTContext();
assert (ast != NULL);
- llvm::APInt ap_element_count (64, element_count);
- return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
+
+ QualType element_qual_type(QualType::getFromOpaquePtr(element_type));
+
+ if (is_vector)
+ {
+ return ast->getExtVectorType(element_qual_type, element_count).getAsOpaquePtr();
+ }
+ else
+ {
+
+ llvm::APInt ap_element_count (64, element_count);
+ if (element_count == 0)
+ {
+ return ast->getIncompleteArrayType(element_qual_type,
+ ArrayType::Normal,
+ 0).getAsOpaquePtr();
+
+ }
+ else
+ {
+ return ast->getConstantArrayType(element_qual_type,
ap_element_count,
ArrayType::Normal,
0).getAsOpaquePtr(); // ElemQuals
+ }
+ }
}
return NULL;
}
@@ -5380,6 +5759,8 @@ ClangASTContext::AddEnumerationValueToEn
assert (identifier_table != NULL);
QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
+ bool is_signed = false;
+ IsIntegerType (enumerator_clang_type, is_signed);
const clang::Type *clang_type = enum_qual_type.getTypePtr();
if (clang_type)
{
@@ -5387,7 +5768,7 @@ ClangASTContext::AddEnumerationValueToEn
if (enum_type)
{
- llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
+ llvm::APSInt enum_llvm_apsint(enum_value_bit_size, is_signed);
enum_llvm_apsint = enum_value;
EnumConstantDecl *enumerator_decl =
EnumConstantDecl::Create (*ast,
@@ -5470,7 +5851,7 @@ ClangASTContext::CreateMemberPointerType
return NULL;
}
-uint32_t
+uint64_t
ClangASTContext::GetPointerBitSize ()
{
ASTContext *ast = getASTContext();
@@ -5487,7 +5868,7 @@ ClangASTContext::IsPossibleDynamicType (
QualType pointee_qual_type;
if (clang_type)
{
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+ QualType qual_type (QualType::getFromOpaquePtr(clang_type).getCanonicalType());
const clang::Type::TypeClass type_class = qual_type->getTypeClass();
bool success = false;
switch (type_class)
@@ -5522,11 +5903,25 @@ ClangASTContext::IsPossibleDynamicType (
break;
case clang::Type::Typedef:
- return ClangASTContext::IsPossibleDynamicType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), dynamic_pointee_type);
+ return ClangASTContext::IsPossibleDynamicType (ast,
+ cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
+ dynamic_pointee_type,
+ check_cplusplus,
+ check_objc);
case clang::Type::Elaborated:
- return ClangASTContext::IsPossibleDynamicType (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), dynamic_pointee_type);
-
+ return ClangASTContext::IsPossibleDynamicType (ast,
+ cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
+ dynamic_pointee_type,
+ check_cplusplus,
+ check_objc);
+
+ case clang::Type::Paren:
+ return ClangASTContext::IsPossibleDynamicType (ast,
+ cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ dynamic_pointee_type,
+ check_cplusplus,
+ check_objc);
default:
break;
}
@@ -5536,7 +5931,7 @@ ClangASTContext::IsPossibleDynamicType (
// Check to make sure what we are pointing too is a possible dynamic C++ type
// We currently accept any "void *" (in case we have a class that has been
// watered down to an opaque pointer) and virtual C++ classes.
- const clang::Type::TypeClass pointee_type_class = pointee_qual_type->getTypeClass();
+ const clang::Type::TypeClass pointee_type_class = pointee_qual_type.getCanonicalType()->getTypeClass();
switch (pointee_type_class)
{
case clang::Type::Builtin:
@@ -5580,6 +5975,15 @@ ClangASTContext::IsPossibleDynamicType (
case clang::BuiltinType::Half:
case clang::BuiltinType::ARCUnbridgedCast:
case clang::BuiltinType::PseudoObject:
+ case clang::BuiltinType::BuiltinFn:
+ case clang::BuiltinType::OCLEvent:
+ case clang::BuiltinType::OCLImage1d:
+ case clang::BuiltinType::OCLImage1dArray:
+ case clang::BuiltinType::OCLImage1dBuffer:
+ case clang::BuiltinType::OCLImage2d:
+ case clang::BuiltinType::OCLImage2dArray:
+ case clang::BuiltinType::OCLImage3d:
+ case clang::BuiltinType::OCLSampler:
break;
}
break;
@@ -5590,23 +5994,25 @@ ClangASTContext::IsPossibleDynamicType (
CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
if (cxx_record_decl)
{
- // Do NOT complete the type here like we used to do
- // otherwise EVERY "class *" variable we have will try
- // to fully complete itself and this will take a lot of
- // time, memory and slow down debugging. If we have a complete
- // type, then answer the question definitively, else we
- // just say that a C++ class can possibly be dynamic...
- if (cxx_record_decl->isCompleteDefinition())
- {
+ bool is_complete = cxx_record_decl->isCompleteDefinition();
+
+ if (is_complete)
success = cxx_record_decl->isDynamicClass();
- }
else
{
- // We failed to get the complete type, so we have to
- // treat this as a void * which we might possibly be
- // able to complete
- success = true;
+ ClangASTMetadata *metadata = GetMetadata (ast, cxx_record_decl);
+ if (metadata)
+ success = metadata->GetIsDynamicCXXType();
+ else
+ {
+ is_complete = ClangASTContext::GetCompleteType (ast, pointee_qual_type.getAsOpaquePtr());
+ if (is_complete)
+ success = cxx_record_decl->isDynamicClass();
+ else
+ success = false;
+ }
}
+
if (success)
{
if (dynamic_pointee_type)
@@ -5671,6 +6077,9 @@ ClangASTContext::IsReferenceType (clang_
return ClangASTContext::IsReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
case clang::Type::Elaborated:
return ClangASTContext::IsReferenceType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+ case clang::Type::Paren:
+ return ClangASTContext::IsReferenceType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
+
default:
break;
}
@@ -5726,6 +6135,8 @@ ClangASTContext::IsPointerOrReferenceTyp
return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
case clang::Type::Elaborated:
return ClangASTContext::IsPointerOrReferenceType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+ case clang::Type::Paren:
+ return ClangASTContext::IsPointerOrReferenceType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
default:
break;
}
@@ -5795,6 +6206,8 @@ ClangASTContext::IsPointerType (clang_ty
return ClangASTContext::IsPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type);
case clang::Type::Elaborated:
return ClangASTContext::IsPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), target_type);
+ case clang::Type::Paren:
+ return ClangASTContext::IsPointerType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), target_type);
default:
break;
}
@@ -5867,7 +6280,7 @@ ClangASTContext::IsPointerToScalarType (
bool
ClangASTContext::IsArrayOfScalarType (lldb::clang_type_t clang_type)
{
- clang_type = GetAsArrayType(clang_type);
+ clang_type = GetAsArrayType(clang_type, NULL, NULL, NULL);
if (clang_type == 0)
return false;
@@ -6042,6 +6455,8 @@ ClangASTContext::IsFunctionPointerType (
return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
case clang::Type::Elaborated:
return ClangASTContext::IsFunctionPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+ case clang::Type::Paren:
+ return ClangASTContext::IsFunctionPointerType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
case clang::Type::LValueReference:
case clang::Type::RValueReference:
@@ -6078,6 +6493,9 @@ ClangASTContext::GetArraySize (clang_typ
case clang::Type::Elaborated:
return ClangASTContext::GetArraySize(cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+
+ case clang::Type::Paren:
+ return ClangASTContext::GetArraySize(cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
default:
break;
@@ -6087,8 +6505,10 @@ ClangASTContext::GetArraySize (clang_typ
}
clang_type_t
-ClangASTContext::GetAsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
+ClangASTContext::GetAsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size, bool *is_incomplete)
{
+ if (is_incomplete)
+ *is_incomplete = false;
if (!clang_type)
return 0;
@@ -6112,6 +6532,8 @@ ClangASTContext::GetAsArrayType (clang_t
*member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
if (size)
*size = 0;
+ if (is_incomplete)
+ *is_incomplete = true;
return clang_type;
case clang::Type::VariableArray:
@@ -6131,12 +6553,19 @@ ClangASTContext::GetAsArrayType (clang_t
case clang::Type::Typedef:
return ClangASTContext::GetAsArrayType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
member_type,
- size);
+ size,
+ is_incomplete);
case clang::Type::Elaborated:
return ClangASTContext::GetAsArrayType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
member_type,
- size);
+ size,
+ is_incomplete);
+ case clang::Type::Paren:
+ return ClangASTContext::GetAsArrayType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ member_type,
+ size,
+ is_incomplete);
}
return 0;
}
@@ -6161,7 +6590,7 @@ ClangASTContext::CreateTypedefType (cons
SourceLocation(),
SourceLocation(),
name ? &identifier_table->get(name) : NULL, // Identifier
- ast->CreateTypeSourceInfo(qual_type));
+ ast->getTrivialTypeSourceInfo(qual_type));
//decl_ctx->addDecl (decl);
@@ -6338,9 +6767,18 @@ ClangASTContext::GetCompleteDecl (clang:
}
void
+ClangASTContext::SetMetadataAsUserID (const void *object,
+ user_id_t user_id)
+{
+ ClangASTMetadata meta_data;
+ meta_data.SetUserID (user_id);
+ SetMetadata (object, meta_data);
+}
+
+void
ClangASTContext::SetMetadata (clang::ASTContext *ast,
- uintptr_t object,
- uint64_t metadata)
+ const void *object,
+ ClangASTMetadata &metadata)
{
ClangExternalASTSourceCommon *external_source =
static_cast<ClangExternalASTSourceCommon*>(ast->getExternalSource());
@@ -6349,9 +6787,9 @@ ClangASTContext::SetMetadata (clang::AST
external_source->SetMetadata(object, metadata);
}
-uint64_t
+ClangASTMetadata *
ClangASTContext::GetMetadata (clang::ASTContext *ast,
- uintptr_t object)
+ const void *object)
{
ClangExternalASTSourceCommon *external_source =
static_cast<ClangExternalASTSourceCommon*>(ast->getExternalSource());
@@ -6359,7 +6797,7 @@ ClangASTContext::GetMetadata (clang::AST
if (external_source && external_source->HasMetadata(object))
return external_source->GetMetadata(object);
else
- return 0;
+ return NULL;
}
clang::DeclContext *
@@ -6416,6 +6854,17 @@ ClangASTContext::GetClassMethodInfoForDe
language = eLanguageTypeObjC;
return true;
}
+ else if (clang::FunctionDecl *function_decl = llvm::dyn_cast<clang::FunctionDecl>(decl_ctx))
+ {
+ ClangASTMetadata *metadata = GetMetadata (&decl_ctx->getParentASTContext(), function_decl);
+ if (metadata && metadata->HasObjectPtr())
+ {
+ language_object_name.SetCString (metadata->GetObjectPtrName());
+ language = eLanguageTypeObjC;
+ is_instance_method = true;
+ }
+ return true;
+ }
}
return false;
}
Modified: lldb/branches/lldb-platform-work/source/Symbol/ClangASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/ClangASTImporter.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/ClangASTImporter.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/ClangASTImporter.cpp Thu Jun 6 19:06:43 2013
@@ -10,6 +10,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
+#include "llvm/Support/raw_ostream.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -20,7 +21,32 @@
using namespace lldb_private;
using namespace clang;
-clang::QualType
+ClangASTMetrics::Counters ClangASTMetrics::global_counters = { 0, 0, 0, 0, 0, 0 };
+ClangASTMetrics::Counters ClangASTMetrics::local_counters = { 0, 0, 0, 0, 0, 0 };
+
+void ClangASTMetrics::DumpCounters (Log *log, ClangASTMetrics::Counters &counters)
+{
+ log->Printf(" Number of visible Decl queries by name : %" PRIu64, counters.m_visible_query_count);
+ log->Printf(" Number of lexical Decl queries : %" PRIu64, counters.m_lexical_query_count);
+ log->Printf(" Number of imports initiated by LLDB : %" PRIu64, counters.m_lldb_import_count);
+ log->Printf(" Number of imports conducted by Clang : %" PRIu64, counters.m_clang_import_count);
+ log->Printf(" Number of Decls completed : %" PRIu64, counters.m_decls_completed_count);
+ log->Printf(" Number of records laid out : %" PRIu64, counters.m_record_layout_count);
+}
+
+void ClangASTMetrics::DumpCounters (Log *log)
+{
+ if (!log)
+ return;
+
+ log->Printf("== ClangASTMetrics output ==");
+ log->Printf("-- Global metrics --");
+ DumpCounters (log, global_counters);
+ log->Printf("-- Local metrics --");
+ DumpCounters (log, local_counters);
+}
+
+clang::QualType
ClangASTImporter::CopyType (clang::ASTContext *dst_ast,
clang::ASTContext *src_ast,
clang::QualType type)
@@ -56,19 +82,24 @@ ClangASTImporter::CopyDecl (clang::ASTCo
if (!result)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
{
+ lldb::user_id_t user_id;
+ ClangASTMetadata *metadata = GetDeclMetadata(decl);
+ if (metadata)
+ user_id = metadata->GetUserID();
+
if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl))
- log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s '%s', metadata 0x%llx",
+ log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s '%s', metadata 0x%" PRIx64,
decl->getDeclKindName(),
named_decl->getNameAsString().c_str(),
- GetDeclMetadata(decl));
+ user_id);
else
- log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s, metadata 0x%llx",
+ log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s, metadata 0x%" PRIx64,
decl->getDeclKindName(),
- GetDeclMetadata(decl));
+ user_id);
}
}
@@ -82,37 +113,27 @@ lldb::clang_type_t
ClangASTImporter::DeportType (clang::ASTContext *dst_ctx,
clang::ASTContext *src_ctx,
lldb::clang_type_t type)
-{
- lldb::clang_type_t result = CopyType(dst_ctx, src_ctx, type);
+{
+ MinionSP minion_sp (GetMinion (dst_ctx, src_ctx));
- if (!result)
+ if (!minion_sp)
return NULL;
- QualType qual_type = QualType::getFromOpaquePtr(type);
+ std::set<NamedDecl *> decls_to_deport;
+ std::set<NamedDecl *> decls_already_deported;
- if (const TagType *tag_type = qual_type->getAs<TagType>())
- {
- TagDecl *tag_decl = tag_type->getDecl();
- const TagType *result_tag_type = QualType::getFromOpaquePtr(result)->getAs<TagType>();
- TagDecl *result_tag_decl = result_tag_type->getDecl();
-
- if (tag_decl)
- {
- MinionSP minion_sp (GetMinion (dst_ctx, src_ctx));
-
- minion_sp->ImportDefinitionTo(result_tag_decl, tag_decl);
-
- ASTContextMetadataSP to_context_md = GetContextMetadata(dst_ctx);
-
- OriginMap::iterator oi = to_context_md->m_origins.find(result_tag_decl);
-
- if (oi != to_context_md->m_origins.end() &&
- oi->second.ctx == src_ctx)
- to_context_md->m_origins.erase(oi);
- }
- }
+ minion_sp->InitDeportWorkQueues(&decls_to_deport,
+ &decls_already_deported);
+
+ lldb::clang_type_t result = CopyType(dst_ctx, src_ctx, type);
+
+ minion_sp->ExecuteDeportWorkQueues();
+
+ if (!result)
+ return NULL;
return result;
+
}
clang::Decl *
@@ -120,25 +141,39 @@ ClangASTImporter::DeportDecl (clang::AST
clang::ASTContext *src_ctx,
clang::Decl *decl)
{
- clang::Decl *result = CopyDecl(dst_ctx, src_ctx, decl);
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
- if (!result)
- return NULL;
+ if (log)
+ log->Printf(" [ClangASTImporter] DeportDecl called on (%sDecl*)%p from (ASTContext*)%p to (ASTContex*)%p",
+ decl->getDeclKindName(),
+ decl,
+ src_ctx,
+ dst_ctx);
- ClangASTContext::GetCompleteDecl (src_ctx, decl);
-
MinionSP minion_sp (GetMinion (dst_ctx, src_ctx));
- if (minion_sp && isa<TagDecl>(decl))
- minion_sp->ImportDefinitionTo(result, decl);
+ if (!minion_sp)
+ return NULL;
+
+ std::set<NamedDecl *> decls_to_deport;
+ std::set<NamedDecl *> decls_already_deported;
- ASTContextMetadataSP to_context_md = GetContextMetadata(dst_ctx);
+ minion_sp->InitDeportWorkQueues(&decls_to_deport,
+ &decls_already_deported);
+
+ clang::Decl *result = CopyDecl(dst_ctx, src_ctx, decl);
- OriginMap::iterator oi = to_context_md->m_origins.find(decl);
+ minion_sp->ExecuteDeportWorkQueues();
- if (oi != to_context_md->m_origins.end() &&
- oi->second.ctx == src_ctx)
- to_context_md->m_origins.erase(oi);
+ if (!result)
+ return NULL;
+
+ if (log)
+ log->Printf(" [ClangASTImporter] DeportDecl deported (%sDecl*)%p to (%sDecl*)%p",
+ decl->getDeclKindName(),
+ decl,
+ result->getDeclKindName(),
+ result);
return result;
}
@@ -146,7 +181,7 @@ ClangASTImporter::DeportDecl (clang::AST
void
ClangASTImporter::CompleteDecl (clang::Decl *decl)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
log->Printf(" [ClangASTImporter] CompleteDecl called on (%sDecl*)%p",
@@ -183,7 +218,9 @@ ClangASTImporter::CompleteDecl (clang::D
bool
ClangASTImporter::CompleteTagDecl (clang::TagDecl *decl)
-{
+{
+ ClangASTMetrics::RegisterDeclCompletion();
+
DeclOrigin decl_origin = GetDeclOrigin(decl);
if (!decl_origin.Valid())
@@ -203,6 +240,8 @@ ClangASTImporter::CompleteTagDecl (clang
bool
ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl, clang::TagDecl *origin_decl)
{
+ ClangASTMetrics::RegisterDeclCompletion();
+
clang::ASTContext *origin_ast_ctx = &origin_decl->getASTContext();
if (!ClangASTContext::GetCompleteDecl(origin_ast_ctx, origin_decl))
@@ -225,7 +264,7 @@ ClangASTImporter::CompleteTagDeclWithOri
bool
ClangASTImporter::CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ ClangASTMetrics::RegisterDeclCompletion();
DeclOrigin decl_origin = GetDeclOrigin(interface_decl);
@@ -243,15 +282,44 @@ ClangASTImporter::CompleteObjCInterfaceD
return true;
}
-uint64_t
+bool
+ClangASTImporter::RequireCompleteType (clang::QualType type)
+{
+ if (type.isNull())
+ return false;
+
+ if (const TagType *tag_type = type->getAs<TagType>())
+ {
+ return CompleteTagDecl(tag_type->getDecl());
+ }
+ if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>())
+ {
+ if (ObjCInterfaceDecl *objc_interface_decl = objc_object_type->getInterface())
+ return CompleteObjCInterfaceDecl(objc_interface_decl);
+ else
+ return false;
+ }
+ if (const ArrayType *array_type = type->getAsArrayTypeUnsafe())
+ {
+ return RequireCompleteType(array_type->getElementType());
+ }
+ if (const AtomicType *atomic_type = type->getAs<AtomicType>())
+ {
+ return RequireCompleteType(atomic_type->getPointeeType());
+ }
+
+ return true;
+}
+
+ClangASTMetadata *
ClangASTImporter::GetDeclMetadata (const clang::Decl *decl)
{
DeclOrigin decl_origin = GetDeclOrigin(decl);
if (decl_origin.Valid())
- return ClangASTContext::GetMetadata(decl_origin.ctx, (uintptr_t)decl_origin.decl);
+ return ClangASTContext::GetMetadata(decl_origin.ctx, decl_origin.decl);
else
- return ClangASTContext::GetMetadata(&decl->getASTContext(), (uintptr_t)decl);
+ return ClangASTContext::GetMetadata(&decl->getASTContext(), decl);
}
ClangASTImporter::DeclOrigin
@@ -269,7 +337,27 @@ ClangASTImporter::GetDeclOrigin(const cl
return DeclOrigin();
}
-void
+void
+ClangASTImporter::SetDeclOrigin (const clang::Decl *decl, clang::Decl *original_decl)
+{
+ ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
+
+ OriginMap &origins = context_md->m_origins;
+
+ OriginMap::iterator iter = origins.find(decl);
+
+ if (iter != origins.end())
+ {
+ iter->second.decl = original_decl;
+ iter->second.ctx = &original_decl->getASTContext();
+ }
+ else
+ {
+ origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl);
+ }
+}
+
+void
ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl,
NamespaceMapSP &namespace_map)
{
@@ -296,6 +384,7 @@ ClangASTImporter::GetNamespaceMap(const
void
ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl)
{
+ assert (decl);
ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
const DeclContext *parent_context = decl->getDeclContext();
@@ -322,7 +411,7 @@ ClangASTImporter::BuildNamespaceMap(cons
void
ClangASTImporter::ForgetDestination (clang::ASTContext *dst_ast)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
log->Printf(" [ClangASTImporter] Forgetting destination (ASTContext*)%p", dst_ast);
@@ -335,7 +424,7 @@ ClangASTImporter::ForgetSource (clang::A
{
ASTContextMetadataSP md = MaybeGetContextMetadata (dst_ast);
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
log->Printf(" [ClangASTImporter] Forgetting source->dest (ASTContext*)%p->(ASTContext*)%p", src_ast, dst_ast);
@@ -362,6 +451,63 @@ ClangASTImporter::MapCompleter::~MapComp
}
void
+ClangASTImporter::Minion::InitDeportWorkQueues (std::set<clang::NamedDecl *> *decls_to_deport,
+ std::set<clang::NamedDecl *> *decls_already_deported)
+{
+ assert(!m_decls_to_deport); // TODO make debug only
+ assert(!m_decls_already_deported);
+
+ m_decls_to_deport = decls_to_deport;
+ m_decls_already_deported = decls_already_deported;
+}
+
+void
+ClangASTImporter::Minion::ExecuteDeportWorkQueues ()
+{
+ assert(m_decls_to_deport); // TODO make debug only
+ assert(m_decls_already_deported);
+
+ ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&getToContext());
+
+ while (!m_decls_to_deport->empty())
+ {
+ NamedDecl *decl = *m_decls_to_deport->begin();
+
+ m_decls_already_deported->insert(decl);
+ m_decls_to_deport->erase(decl);
+
+ DeclOrigin &origin = to_context_md->m_origins[decl];
+
+ assert (origin.ctx == m_source_ctx); // otherwise we should never have added this
+ // because it doesn't need to be deported
+
+ Decl *original_decl = to_context_md->m_origins[decl].decl;
+
+ ClangASTContext::GetCompleteDecl (m_source_ctx, original_decl);
+
+ if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl))
+ {
+ if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl))
+ if (original_tag_decl->isCompleteDefinition())
+ ImportDefinitionTo(tag_decl, original_tag_decl);
+
+ tag_decl->setHasExternalLexicalStorage(false);
+ tag_decl->setHasExternalVisibleStorage(false);
+ }
+ else if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl))
+ {
+ interface_decl->setHasExternalLexicalStorage(false);
+ interface_decl->setHasExternalVisibleStorage(false);
+ }
+
+ to_context_md->m_origins.erase(decl);
+ }
+
+ m_decls_to_deport = NULL;
+ m_decls_already_deported = NULL;
+}
+
+void
ClangASTImporter::Minion::ImportDefinitionTo (clang::Decl *to, clang::Decl *from)
{
ASTImporter::Imported(from, to);
@@ -425,10 +571,17 @@ ClangASTImporter::Minion::ImportDefiniti
clang::Decl
*ClangASTImporter::Minion::Imported (clang::Decl *from, clang::Decl *to)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ ClangASTMetrics::RegisterClangImport();
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
{
+ lldb::user_id_t user_id;
+ ClangASTMetadata *metadata = m_master.GetDeclMetadata(from);
+ if (metadata)
+ user_id = metadata->GetUserID();
+
if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from))
{
std::string name_string;
@@ -436,20 +589,20 @@ clang::Decl
from_named_decl->printName(name_stream);
name_stream.flush();
- log->Printf(" [ClangASTImporter] Imported (%sDecl*)%p, named %s (from (Decl*)%p), metadata 0x%llx",
+ log->Printf(" [ClangASTImporter] Imported (%sDecl*)%p, named %s (from (Decl*)%p), metadata 0x%" PRIx64,
from->getDeclKindName(),
to,
name_string.c_str(),
from,
- m_master.GetDeclMetadata(from));
+ user_id);
}
else
{
- log->Printf(" [ClangASTImporter] Imported (%sDecl*)%p (from (Decl*)%p), metadata 0x%llx",
+ log->Printf(" [ClangASTImporter] Imported (%sDecl*)%p (from (Decl*)%p), metadata 0x%" PRIx64,
from->getDeclKindName(),
to,
from,
- m_master.GetDeclMetadata(from));
+ user_id);
}
}
@@ -480,6 +633,17 @@ clang::Decl
}
else
{
+ if (m_decls_to_deport && m_decls_already_deported)
+ {
+ if (isa<TagDecl>(to) || isa<ObjCInterfaceDecl>(to))
+ {
+ NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to);
+
+ if (!m_decls_already_deported->count(to_named_decl))
+ m_decls_to_deport->insert(to_named_decl);
+ }
+
+ }
to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);
if (log)
@@ -515,15 +679,14 @@ clang::Decl
TagDecl *to_tag_decl = dyn_cast<TagDecl>(to);
to_tag_decl->setHasExternalLexicalStorage();
-
+ to_tag_decl->setMustBuildLookupTable();
+
if (log)
log->Printf(" [ClangASTImporter] To is a TagDecl - attributes %s%s [%s->%s]",
(to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
(to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""),
(from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"),
(to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"));
-
- to_tag_decl = NULL;
}
if (isa<NamespaceDecl>(from))
@@ -541,7 +704,7 @@ clang::Decl
to_interface_decl->setHasExternalLexicalStorage();
to_interface_decl->setHasExternalVisibleStorage();
-
+
/*to_interface_decl->setExternallyCompleted();*/
if (log)
Modified: lldb/branches/lldb-platform-work/source/Symbol/ClangASTType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/ClangASTType.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/ClangASTType.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/ClangASTType.cpp Thu Jun 6 19:06:43 2013
@@ -1,4 +1,4 @@
-//===-- ClangASTType.cpp ---------------------------------------------*- C++ -*-===//
+//===-- ClangASTType.cpp ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Symbol/ClangASTType.h"
#include "clang/AST/ASTConsumer.h"
@@ -34,10 +36,14 @@
#include "lldb/Core/Scalar.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
+#include <mutex>
+
using namespace lldb;
using namespace lldb_private;
@@ -53,6 +59,7 @@ ClangASTType::GetTypeNameForQualType (cl
clang::PrintingPolicy printing_policy (ast->getPrintingPolicy());
printing_policy.SuppressTagKeyword = true;
+ printing_policy.LangOpts.WChar = true;
const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
if (typedef_type)
{
@@ -72,6 +79,14 @@ ClangASTType::GetTypeNameForOpaqueQualTy
return GetTypeNameForQualType (ast, clang::QualType::getFromOpaquePtr(opaque_qual_type));
}
+ClangASTType
+ClangASTType::GetCanonicalType (clang::ASTContext *ast, lldb::clang_type_t opaque_qual_type)
+{
+ if (ast && opaque_qual_type)
+ return ClangASTType (ast,
+ clang::QualType::getFromOpaquePtr(opaque_qual_type).getCanonicalType().getAsOpaquePtr());
+ return ClangASTType();
+}
ConstString
ClangASTType::GetConstTypeName ()
@@ -117,7 +132,7 @@ ClangASTType::GetConstTypeName (clang::A
}
clang_type_t
-ClangASTType::GetPointeeType ()
+ClangASTType::GetPointeeType () const
{
return GetPointeeType (m_type);
}
@@ -135,7 +150,7 @@ ClangASTType::GetPointeeType (clang_type
}
lldb::clang_type_t
-ClangASTType::GetArrayElementType (uint32_t& stride)
+ClangASTType::GetArrayElementType (uint64_t& stride)
{
return GetArrayElementType(m_ast, m_type, stride);
}
@@ -143,7 +158,7 @@ ClangASTType::GetArrayElementType (uint3
lldb::clang_type_t
ClangASTType::GetArrayElementType (clang::ASTContext* ast,
lldb::clang_type_t opaque_clang_qual_type,
- uint32_t& stride)
+ uint64_t& stride)
{
if (opaque_clang_qual_type)
{
@@ -181,7 +196,7 @@ ClangASTType::GetPointerType (clang::AST
}
lldb::Encoding
-ClangASTType::GetEncoding (uint32_t &count)
+ClangASTType::GetEncoding (uint64_t &count)
{
return GetEncoding(m_type, count);
}
@@ -244,8 +259,11 @@ ClangASTType::GetTypeClass (clang::ASTCo
case clang::Type::Enum: return lldb::eTypeClassEnumeration;
case clang::Type::Typedef: return lldb::eTypeClassTypedef;
case clang::Type::UnresolvedUsing: break;
- case clang::Type::Paren: break;
- case clang::Type::Elaborated: break;
+ case clang::Type::Paren:
+ return ClangASTType::GetTypeClass (ast_context, llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
+ case clang::Type::Elaborated:
+ return ClangASTType::GetTypeClass (ast_context, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+
case clang::Type::Attributed: break;
case clang::Type::TemplateTypeParm: break;
case clang::Type::SubstTemplateTypeParm: break;
@@ -283,7 +301,7 @@ ClangASTType::GetMinimumLanguage (clang:
return lldb::eLanguageTypeObjC;
clang::QualType pointee_type (qual_type->getPointeeType());
- if (pointee_type->getCXXRecordDeclForPointerType() != NULL)
+ if (pointee_type->getPointeeCXXRecordDecl() != NULL)
return lldb::eLanguageTypeC_plus_plus;
if (pointee_type->isObjCObjectOrInterfaceType())
return lldb::eLanguageTypeObjC;
@@ -355,7 +373,7 @@ ClangASTType::GetMinimumLanguage (clang:
}
lldb::Encoding
-ClangASTType::GetEncoding (clang_type_t clang_type, uint32_t &count)
+ClangASTType::GetEncoding (clang_type_t clang_type, uint64_t &count)
{
count = 1;
clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
@@ -450,14 +468,17 @@ ClangASTType::GetEncoding (clang_type_t
case clang::Type::Record: break;
case clang::Type::Enum: return lldb::eEncodingSint;
case clang::Type::Typedef:
- return GetEncoding(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), count);
- break;
+ return GetEncoding(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), count);
+
+ case clang::Type::Elaborated:
+ return ClangASTType::GetEncoding (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), count);
+ case clang::Type::Paren:
+ return ClangASTType::GetEncoding (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), count);
+
case clang::Type::DependentSizedArray:
case clang::Type::DependentSizedExtVector:
case clang::Type::UnresolvedUsing:
- case clang::Type::Paren:
- case clang::Type::Elaborated:
case clang::Type::Attributed:
case clang::Type::TemplateTypeParm:
case clang::Type::SubstTemplateTypeParm:
@@ -509,7 +530,7 @@ ClangASTType::GetFormat (clang_type_t cl
break;
case clang::Type::ConstantArray:
- break;
+ return lldb::eFormatVoid; // no value
case clang::Type::ExtVector:
case clang::Type::Vector:
@@ -555,6 +576,15 @@ ClangASTType::GetFormat (clang_type_t cl
case clang::BuiltinType::Half:
case clang::BuiltinType::ARCUnbridgedCast:
case clang::BuiltinType::PseudoObject:
+ case clang::BuiltinType::BuiltinFn:
+ case clang::BuiltinType::OCLEvent:
+ case clang::BuiltinType::OCLImage1d:
+ case clang::BuiltinType::OCLImage1dArray:
+ case clang::BuiltinType::OCLImage1dBuffer:
+ case clang::BuiltinType::OCLImage2d:
+ case clang::BuiltinType::OCLImage2dArray:
+ case clang::BuiltinType::OCLImage3d:
+ case clang::BuiltinType::OCLSampler:
return lldb::eFormatHex;
}
break;
@@ -575,15 +605,16 @@ ClangASTType::GetFormat (clang_type_t cl
case clang::Type::Record: break;
case clang::Type::Enum: return lldb::eFormatEnum;
case clang::Type::Typedef:
- return ClangASTType::GetFormat(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
-
+ return ClangASTType::GetFormat(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
case clang::Type::Auto:
- return ClangASTType::GetFormat(llvm::cast<clang::AutoType>(qual_type)->desugar().getAsOpaquePtr());
+ return ClangASTType::GetFormat(llvm::cast<clang::AutoType>(qual_type)->desugar().getAsOpaquePtr());
+ case clang::Type::Paren:
+ return ClangASTType::GetFormat(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
+ case clang::Type::Elaborated:
+ return ClangASTType::GetFormat(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
case clang::Type::DependentSizedArray:
case clang::Type::DependentSizedExtVector:
case clang::Type::UnresolvedUsing:
- case clang::Type::Paren:
- case clang::Type::Elaborated:
case clang::Type::Attributed:
case clang::Type::TemplateTypeParm:
case clang::Type::SubstTemplateTypeParm:
@@ -613,7 +644,7 @@ ClangASTType::DumpValue
Stream *s,
lldb::Format format,
const lldb_private::DataExtractor &data,
- uint32_t data_byte_offset,
+ lldb::offset_t data_byte_offset,
size_t data_byte_size,
uint32_t bitfield_bit_size,
uint32_t bitfield_bit_offset,
@@ -649,7 +680,7 @@ ClangASTType::DumpValue
Stream *s,
lldb::Format format,
const lldb_private::DataExtractor &data,
- uint32_t data_byte_offset,
+ lldb::offset_t data_byte_offset,
size_t data_byte_size,
uint32_t bitfield_bit_size,
uint32_t bitfield_bit_offset,
@@ -798,7 +829,7 @@ ClangASTType::DumpValue
const clang::EnumDecl *enum_decl = enum_type->getDecl();
assert(enum_decl);
clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
- uint32_t offset = data_byte_offset;
+ lldb::offset_t offset = data_byte_offset;
const int64_t enum_value = data.GetMaxU64Bitfield(&offset, data_byte_size, bitfield_bit_size, bitfield_bit_offset);
for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
{
@@ -810,7 +841,7 @@ ClangASTType::DumpValue
}
// If we have gotten here we didn't get find the enumerator in the
// enum decl, so just print the integer.
- s->Printf("%lli", enum_value);
+ s->Printf("%" PRIi64, enum_value);
}
return;
@@ -908,6 +939,54 @@ ClangASTType::DumpValue
}
break;
+ case clang::Type::Elaborated:
+ {
+ clang::QualType elaborated_qual_type = llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType();
+ lldb::Format elaborated_format = ClangASTType::GetFormat(elaborated_qual_type.getAsOpaquePtr());
+ std::pair<uint64_t, unsigned> elaborated_type_info = ast_context->getTypeInfo(elaborated_qual_type);
+ uint64_t elaborated_byte_size = elaborated_type_info.first / 8;
+
+ return DumpValue (ast_context, // The clang AST context for this type
+ elaborated_qual_type.getAsOpaquePtr(), // The clang type we want to dump
+ exe_ctx,
+ s, // Stream to dump to
+ elaborated_format, // The format with which to display the element
+ data, // Data buffer containing all bytes for this type
+ data_byte_offset, // Offset into "data" where to grab value from
+ elaborated_byte_size, // Size of this type in bytes
+ bitfield_bit_size, // Bitfield bit size
+ bitfield_bit_offset,// Bitfield bit offset
+ show_types, // Boolean indicating if we should show the variable types
+ show_summary, // Boolean indicating if we should show a summary for the current type
+ verbose, // Verbose output?
+ depth); // Scope depth for any types that have children
+ }
+ break;
+
+ case clang::Type::Paren:
+ {
+ clang::QualType desugar_qual_type = llvm::cast<clang::ParenType>(qual_type)->desugar();
+ lldb::Format desugar_format = ClangASTType::GetFormat(desugar_qual_type.getAsOpaquePtr());
+ std::pair<uint64_t, unsigned> desugar_type_info = ast_context->getTypeInfo(desugar_qual_type);
+ uint64_t desugar_byte_size = desugar_type_info.first / 8;
+
+ return DumpValue (ast_context, // The clang AST context for this type
+ desugar_qual_type.getAsOpaquePtr(), // The clang type we want to dump
+ exe_ctx,
+ s, // Stream to dump to
+ desugar_format, // The format with which to display the element
+ data, // Data buffer containing all bytes for this type
+ data_byte_offset, // Offset into "data" where to grab value from
+ desugar_byte_size, // Size of this type in bytes
+ bitfield_bit_size, // Bitfield bit size
+ bitfield_bit_offset,// Bitfield bit offset
+ show_types, // Boolean indicating if we should show the variable types
+ show_summary, // Boolean indicating if we should show a summary for the current type
+ verbose, // Verbose output?
+ depth); // Scope depth for any types that have children
+ }
+ break;
+
default:
// We are down the a scalar type that we just need to display.
data.Dump(s, data_byte_offset, format, data_byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size, bitfield_bit_offset);
@@ -924,7 +1003,7 @@ bool
ClangASTType::DumpTypeValue (Stream *s,
lldb::Format format,
const lldb_private::DataExtractor &data,
- uint32_t byte_offset,
+ lldb::offset_t byte_offset,
size_t byte_size,
uint32_t bitfield_bit_size,
uint32_t bitfield_bit_offset,
@@ -949,7 +1028,7 @@ ClangASTType::DumpTypeValue (clang::ASTC
Stream *s,
lldb::Format format,
const lldb_private::DataExtractor &data,
- uint32_t byte_offset,
+ lldb::offset_t byte_offset,
size_t byte_size,
uint32_t bitfield_bit_size,
uint32_t bitfield_bit_offset,
@@ -996,20 +1075,38 @@ ClangASTType::DumpTypeValue (clang::ASTC
const clang::EnumDecl *enum_decl = enum_type->getDecl();
assert(enum_decl);
clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
- uint32_t offset = byte_offset;
- const int64_t enum_value = data.GetMaxU64Bitfield (&offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
- for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
+ const bool is_signed = qual_type->isSignedIntegerOrEnumerationType();
+ lldb::offset_t offset = byte_offset;
+ if (is_signed)
{
- if (enum_pos->getInitVal() == enum_value)
+ const int64_t enum_svalue = data.GetMaxS64Bitfield (&offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
+ for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
{
- s->PutCString (enum_pos->getNameAsString().c_str());
- return true;
+ if (enum_pos->getInitVal().getSExtValue() == enum_svalue)
+ {
+ s->PutCString (enum_pos->getNameAsString().c_str());
+ return true;
+ }
}
+ // If we have gotten here we didn't get find the enumerator in the
+ // enum decl, so just print the integer.
+ s->Printf("%" PRIi64, enum_svalue);
+ }
+ else
+ {
+ const uint64_t enum_uvalue = data.GetMaxU64Bitfield (&offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
+ for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
+ {
+ if (enum_pos->getInitVal().getZExtValue() == enum_uvalue)
+ {
+ s->PutCString (enum_pos->getNameAsString().c_str());
+ return true;
+ }
+ }
+ // If we have gotten here we didn't get find the enumerator in the
+ // enum decl, so just print the integer.
+ s->Printf("%" PRIu64, enum_uvalue);
}
- // If we have gotten here we didn't get find the enumerator in the
- // enum decl, so just print the integer.
-
- s->Printf("%lli", enum_value);
return true;
}
// format was not enum, just fall through and dump the value as requested....
@@ -1094,7 +1191,7 @@ ClangASTType::DumpSummary
ExecutionContext *exe_ctx,
Stream *s,
const lldb_private::DataExtractor &data,
- uint32_t data_byte_offset,
+ lldb::offset_t data_byte_offset,
size_t data_byte_size
)
{
@@ -1115,7 +1212,7 @@ ClangASTType::DumpSummary
ExecutionContext *exe_ctx,
Stream *s,
const lldb_private::DataExtractor &data,
- uint32_t data_byte_offset,
+ lldb::offset_t data_byte_offset,
size_t data_byte_size
)
{
@@ -1127,7 +1224,7 @@ ClangASTType::DumpSummary
Process *process = exe_ctx->GetProcessPtr();
if (process)
{
- uint32_t offset = data_byte_offset;
+ lldb::offset_t offset = data_byte_offset;
lldb::addr_t pointer_addresss = data.GetMaxU64(&offset, data_byte_size);
std::vector<uint8_t> buf;
if (length > 0)
@@ -1160,19 +1257,37 @@ ClangASTType::DumpSummary
}
}
-uint32_t
+uint64_t
+ClangASTType::GetClangTypeByteSize ()
+{
+ return (GetClangTypeBitWidth (m_ast, m_type) + 7) / 8;
+}
+
+uint64_t
+ClangASTType::GetClangTypeByteSize (clang::ASTContext *ast_context, clang_type_t clang_type)
+{
+ return (GetClangTypeBitWidth (ast_context, clang_type) + 7) / 8;
+}
+
+uint64_t
ClangASTType::GetClangTypeBitWidth ()
{
return GetClangTypeBitWidth (m_ast, m_type);
}
-uint32_t
+uint64_t
ClangASTType::GetClangTypeBitWidth (clang::ASTContext *ast_context, clang_type_t clang_type)
{
if (ClangASTContext::GetCompleteType (ast_context, clang_type))
{
clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
- return ast_context->getTypeSize (qual_type);
+ const uint32_t bit_size = ast_context->getTypeSize (qual_type);
+ if (bit_size == 0)
+ {
+ if (qual_type->isIncompleteArrayType())
+ return ast_context->getTypeSize (qual_type->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified());
+ }
+ return bit_size;
}
return 0;
}
@@ -1239,6 +1354,18 @@ ClangASTType::IsConst (lldb::clang_type_
}
void
+ClangASTType::DumpTypeDescription ()
+{
+ StreamFile s (stdout, false);
+ DumpTypeDescription (&s);
+ ClangASTMetadata *metadata = ClangASTContext::GetMetadata (m_ast, m_type);
+ if (metadata)
+ {
+ metadata->Dump (&s);
+ }
+}
+
+void
ClangASTType::DumpTypeDescription (Stream *s)
{
return DumpTypeDescription (m_ast, m_type, s);
@@ -1261,8 +1388,9 @@ ClangASTType::DumpTypeDescription (clang
{
case clang::Type::ObjCObject:
case clang::Type::ObjCInterface:
- if (ClangASTContext::GetCompleteType (ast_context, clang_type))
{
+ ClangASTContext::GetCompleteType (ast_context, clang_type);
+
const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
assert (objc_class_type);
if (objc_class_type)
@@ -1271,7 +1399,6 @@ ClangASTType::DumpTypeDescription (clang
if (class_interface_decl)
{
clang::PrintingPolicy policy = ast_context->getPrintingPolicy();
- policy.Dump = 1;
class_interface_decl->print(llvm_ostrm, policy, s->GetIndentLevel());
}
}
@@ -1294,9 +1421,22 @@ ClangASTType::DumpTypeDescription (clang
}
break;
+ case clang::Type::Elaborated:
+ DumpTypeDescription (ast_context,
+ llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
+ s);
+ return;
+
+ case clang::Type::Paren:
+ DumpTypeDescription (ast_context,
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ s);
+ return;
+
case clang::Type::Record:
- if (ClangASTContext::GetCompleteType (ast_context, clang_type))
{
+ ClangASTContext::GetCompleteType (ast_context, clang_type);
+
const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
const clang::RecordDecl *record_decl = record_type->getDecl();
const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
@@ -1334,25 +1474,11 @@ ClangASTType::DumpTypeDescription (clang
}
}
-void
-ClangASTType::DumpTypeCode (Stream *s)
-{
- DumpTypeCode(m_type, s);
-}
-
-void
-ClangASTType::DumpTypeCode (void *type,
- Stream *s)
-{
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(type));
- s->PutCString(qual_type.getAsString().c_str());
-}
-
bool
ClangASTType::GetValueAsScalar
(
const lldb_private::DataExtractor &data,
- uint32_t data_byte_offset,
+ lldb::offset_t data_byte_offset,
size_t data_byte_size,
Scalar &value
)
@@ -1371,7 +1497,7 @@ ClangASTType::GetValueAsScalar
clang::ASTContext *ast_context,
clang_type_t clang_type,
const lldb_private::DataExtractor &data,
- uint32_t data_byte_offset,
+ lldb::offset_t data_byte_offset,
size_t data_byte_size,
Scalar &value
)
@@ -1384,15 +1510,15 @@ ClangASTType::GetValueAsScalar
}
else
{
- uint32_t count = 0;
+ uint64_t count = 0;
lldb::Encoding encoding = GetEncoding (clang_type, count);
if (encoding == lldb::eEncodingInvalid || count != 1)
return false;
uint64_t bit_width = ast_context->getTypeSize(qual_type);
- uint32_t byte_size = (bit_width + 7 ) / 8;
- uint32_t offset = data_byte_offset;
+ uint64_t byte_size = (bit_width + 7 ) / 8;
+ lldb::offset_t offset = data_byte_offset;
switch (encoding)
{
case lldb::eEncodingInvalid:
@@ -1527,18 +1653,18 @@ ClangASTType::SetValueFromScalar
if (!ClangASTContext::IsAggregateType (clang_type))
{
strm.GetFlags().Set(Stream::eBinary);
- uint32_t count = 0;
+ uint64_t count = 0;
lldb::Encoding encoding = GetEncoding (clang_type, count);
if (encoding == lldb::eEncodingInvalid || count != 1)
return false;
- uint64_t bit_width = ast_context->getTypeSize(qual_type);
+ const uint64_t bit_width = ast_context->getTypeSize(qual_type);
// This function doesn't currently handle non-byte aligned assignments
if ((bit_width % 8) != 0)
return false;
- uint32_t byte_size = (bit_width + 7 ) / 8;
+ const uint64_t byte_size = (bit_width + 7 ) / 8;
switch (encoding)
{
case lldb::eEncodingInvalid:
@@ -1597,13 +1723,10 @@ ClangASTType::SetValueFromScalar
}
bool
-ClangASTType::ReadFromMemory
-(
- lldb_private::ExecutionContext *exe_ctx,
- lldb::addr_t addr,
- AddressType address_type,
- lldb_private::DataExtractor &data
-)
+ClangASTType::ReadFromMemory (lldb_private::ExecutionContext *exe_ctx,
+ lldb::addr_t addr,
+ AddressType address_type,
+ lldb_private::DataExtractor &data)
{
return ReadFromMemory (m_ast,
m_type,
@@ -1613,38 +1736,38 @@ ClangASTType::ReadFromMemory
data);
}
-uint32_t
+uint64_t
ClangASTType::GetTypeByteSize() const
{
- return GetTypeByteSize(m_ast,
- m_type);
+ return GetTypeByteSize (m_ast, m_type);
}
-uint32_t
-ClangASTType::GetTypeByteSize(
- clang::ASTContext *ast_context,
- lldb::clang_type_t opaque_clang_qual_type)
+uint64_t
+ClangASTType::GetTypeByteSize(clang::ASTContext *ast_context, lldb::clang_type_t opaque_clang_qual_type)
{
if (ClangASTContext::GetCompleteType (ast_context, opaque_clang_qual_type))
{
clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
- return (ast_context->getTypeSize (qual_type) + 7) / 8;
+
+ uint64_t byte_size = (ast_context->getTypeSize (qual_type) + (uint64_t)7) / (uint64_t)8;
+
+ if (ClangASTContext::IsObjCClassType(opaque_clang_qual_type))
+ byte_size += ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / 8; // isa
+
+ return byte_size;
}
return 0;
}
bool
-ClangASTType::ReadFromMemory
-(
- clang::ASTContext *ast_context,
- clang_type_t clang_type,
- lldb_private::ExecutionContext *exe_ctx,
- lldb::addr_t addr,
- AddressType address_type,
- lldb_private::DataExtractor &data
-)
+ClangASTType::ReadFromMemory (clang::ASTContext *ast_context,
+ clang_type_t clang_type,
+ lldb_private::ExecutionContext *exe_ctx,
+ lldb::addr_t addr,
+ AddressType address_type,
+ lldb_private::DataExtractor &data)
{
if (address_type == eAddressTypeFile)
{
@@ -1658,7 +1781,7 @@ ClangASTType::ReadFromMemory
clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
- const uint32_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8;
+ const uint64_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8;
if (data.GetByteSize() < byte_size)
{
lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0'));
@@ -1670,6 +1793,8 @@ ClangASTType::ReadFromMemory
{
if (address_type == eAddressTypeHost)
{
+ if (addr == 0)
+ return false;
// The address is an address in this process, so just copy it
memcpy (dst, (uint8_t*)NULL + addr, byte_size);
return true;
@@ -1724,7 +1849,7 @@ ClangASTType::WriteToMemory
return false;
}
clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
- const uint32_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8;
+ const uint64_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8;
if (byte_size > 0)
{
@@ -1758,6 +1883,13 @@ ClangASTType::RemoveFastQualifiers (lldb
return qual_type.getAsOpaquePtr();
}
+clang::CXXRecordDecl *
+ClangASTType::GetAsCXXRecordDecl (lldb::clang_type_t opaque_clang_qual_type)
+{
+ if (opaque_clang_qual_type)
+ return clang::QualType::getFromOpaquePtr(opaque_clang_qual_type)->getAsCXXRecordDecl();
+ return NULL;
+}
bool
lldb_private::operator == (const lldb_private::ClangASTType &lhs, const lldb_private::ClangASTType &rhs)
@@ -1771,3 +1903,191 @@ lldb_private::operator != (const lldb_pr
{
return lhs.GetASTContext() != rhs.GetASTContext() || lhs.GetOpaqueQualType() != rhs.GetOpaqueQualType();
}
+
+lldb::BasicType
+ClangASTType::GetBasicTypeEnumeration (const ConstString &name)
+{
+ if (name)
+ {
+ typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
+ static TypeNameToBasicTypeMap g_type_map;
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, [](){
+ // "void"
+ g_type_map.Append(ConstString("void").GetCString(), eBasicTypeVoid);
+
+ // "char"
+ g_type_map.Append(ConstString("char").GetCString(), eBasicTypeChar);
+ g_type_map.Append(ConstString("signed char").GetCString(), eBasicTypeSignedChar);
+ g_type_map.Append(ConstString("unsigned char").GetCString(), eBasicTypeUnsignedChar);
+ g_type_map.Append(ConstString("wchar_t").GetCString(), eBasicTypeWChar);
+ g_type_map.Append(ConstString("signed wchar_t").GetCString(), eBasicTypeSignedWChar);
+ g_type_map.Append(ConstString("unsigned wchar_t").GetCString(), eBasicTypeUnsignedWChar);
+ // "short"
+ g_type_map.Append(ConstString("short").GetCString(), eBasicTypeShort);
+ g_type_map.Append(ConstString("short int").GetCString(), eBasicTypeShort);
+ g_type_map.Append(ConstString("unsigned short").GetCString(), eBasicTypeUnsignedShort);
+ g_type_map.Append(ConstString("unsigned short int").GetCString(), eBasicTypeUnsignedShort);
+
+ // "int"
+ g_type_map.Append(ConstString("int").GetCString(), eBasicTypeInt);
+ g_type_map.Append(ConstString("signed int").GetCString(), eBasicTypeInt);
+ g_type_map.Append(ConstString("unsigned int").GetCString(), eBasicTypeUnsignedInt);
+ g_type_map.Append(ConstString("unsigned").GetCString(), eBasicTypeUnsignedInt);
+
+ // "long"
+ g_type_map.Append(ConstString("long").GetCString(), eBasicTypeLong);
+ g_type_map.Append(ConstString("long int").GetCString(), eBasicTypeLong);
+ g_type_map.Append(ConstString("unsigned long").GetCString(), eBasicTypeUnsignedLong);
+ g_type_map.Append(ConstString("unsigned long int").GetCString(), eBasicTypeUnsignedLong);
+
+ // "long long"
+ g_type_map.Append(ConstString("long long").GetCString(), eBasicTypeLongLong);
+ g_type_map.Append(ConstString("long long int").GetCString(), eBasicTypeLongLong);
+ g_type_map.Append(ConstString("unsigned long long").GetCString(), eBasicTypeUnsignedLongLong);
+ g_type_map.Append(ConstString("unsigned long long int").GetCString(), eBasicTypeUnsignedLongLong);
+
+ // "int128"
+ g_type_map.Append(ConstString("__int128_t").GetCString(), eBasicTypeInt128);
+ g_type_map.Append(ConstString("__uint128_t").GetCString(), eBasicTypeUnsignedInt128);
+
+ // Miscelaneous
+ g_type_map.Append(ConstString("bool").GetCString(), eBasicTypeBool);
+ g_type_map.Append(ConstString("float").GetCString(), eBasicTypeFloat);
+ g_type_map.Append(ConstString("double").GetCString(), eBasicTypeDouble);
+ g_type_map.Append(ConstString("long double").GetCString(), eBasicTypeLongDouble);
+ g_type_map.Append(ConstString("id").GetCString(), eBasicTypeObjCID);
+ g_type_map.Append(ConstString("SEL").GetCString(), eBasicTypeObjCSel);
+ g_type_map.Append(ConstString("nullptr").GetCString(), eBasicTypeNullPtr);
+ g_type_map.Sort();
+ });
+
+ return g_type_map.Find(name.GetCString(), eBasicTypeInvalid);
+ }
+ return eBasicTypeInvalid;
+}
+
+ClangASTType
+ClangASTType::GetBasicType (clang::ASTContext *ast, const ConstString &name)
+{
+ if (ast)
+ {
+ lldb::BasicType basic_type = ClangASTType::GetBasicTypeEnumeration (name);
+ return ClangASTType::GetBasicType (ast, basic_type);
+ }
+ return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::GetBasicType (clang::ASTContext *ast, lldb::BasicType type)
+{
+ if (ast)
+ {
+ clang_type_t clang_type = NULL;
+
+ switch (type)
+ {
+ case eBasicTypeInvalid:
+ case eBasicTypeOther:
+ break;
+ case eBasicTypeVoid:
+ clang_type = ast->VoidTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeChar:
+ clang_type = ast->CharTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeSignedChar:
+ clang_type = ast->SignedCharTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeUnsignedChar:
+ clang_type = ast->UnsignedCharTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeWChar:
+ clang_type = ast->getWCharType().getAsOpaquePtr();
+ break;
+ case eBasicTypeSignedWChar:
+ clang_type = ast->getSignedWCharType().getAsOpaquePtr();
+ break;
+ case eBasicTypeUnsignedWChar:
+ clang_type = ast->getUnsignedWCharType().getAsOpaquePtr();
+ break;
+ case eBasicTypeChar16:
+ clang_type = ast->Char16Ty.getAsOpaquePtr();
+ break;
+ case eBasicTypeChar32:
+ clang_type = ast->Char32Ty.getAsOpaquePtr();
+ break;
+ case eBasicTypeShort:
+ clang_type = ast->ShortTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeUnsignedShort:
+ clang_type = ast->UnsignedShortTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeInt:
+ clang_type = ast->IntTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeUnsignedInt:
+ clang_type = ast->UnsignedIntTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeLong:
+ clang_type = ast->LongTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeUnsignedLong:
+ clang_type = ast->UnsignedLongTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeLongLong:
+ clang_type = ast->LongLongTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeUnsignedLongLong:
+ clang_type = ast->UnsignedLongLongTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeInt128:
+ clang_type = ast->Int128Ty.getAsOpaquePtr();
+ break;
+ case eBasicTypeUnsignedInt128:
+ clang_type = ast->UnsignedInt128Ty.getAsOpaquePtr();
+ break;
+ case eBasicTypeBool:
+ clang_type = ast->BoolTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeHalf:
+ clang_type = ast->HalfTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeFloat:
+ clang_type = ast->FloatTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeDouble:
+ clang_type = ast->DoubleTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeLongDouble:
+ clang_type = ast->LongDoubleTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeFloatComplex:
+ clang_type = ast->FloatComplexTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeDoubleComplex:
+ clang_type = ast->DoubleComplexTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeLongDoubleComplex:
+ clang_type = ast->LongDoubleComplexTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeObjCID:
+ clang_type = ast->ObjCBuiltinIdTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeObjCClass:
+ clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeObjCSel:
+ clang_type = ast->ObjCBuiltinSelTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeNullPtr:
+ clang_type = ast->NullPtrTy.getAsOpaquePtr();
+ break;
+ }
+
+ if (clang_type)
+ return ClangASTType (ast, clang_type);
+ }
+ return ClangASTType();
+}
+
Modified: lldb/branches/lldb-platform-work/source/Symbol/ClangExternalASTSourceCallbacks.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/ClangExternalASTSourceCallbacks.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/ClangExternalASTSourceCallbacks.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/ClangExternalASTSourceCallbacks.cpp Thu Jun 6 19:06:43 2013
@@ -45,7 +45,7 @@
using namespace clang;
using namespace lldb_private;
-clang::DeclContextLookupResult
+bool
ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName
(
const clang::DeclContext *decl_ctx,
@@ -58,9 +58,9 @@ ClangExternalASTSourceCallbacks::FindExt
m_callback_find_by_name (m_callback_baton, decl_ctx, clang_decl_name, &results);
- DeclContextLookupResult lookup_result (SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, results));
+ SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, results);
- return lookup_result;
+ return (results.size() != 0);
}
std::string decl_name (clang_decl_name.getAsString());
@@ -70,55 +70,61 @@ ClangExternalASTSourceCallbacks::FindExt
case clang::DeclarationName::Identifier:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"Identifier\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
if (clang_decl_name.getAsIdentifierInfo()->getBuiltinID() != 0)
- return SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ {
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
+ }
break;
case clang::DeclarationName::ObjCZeroArgSelector:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"ObjCZeroArgSelector\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
- return DeclContext::lookup_result();
- break;
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
case clang::DeclarationName::ObjCOneArgSelector:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"ObjCOneArgSelector\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
- return DeclContext::lookup_result();
- break;
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
case clang::DeclarationName::ObjCMultiArgSelector:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"ObjCMultiArgSelector\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
- return DeclContext::lookup_result();
- break;
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
case clang::DeclarationName::CXXConstructorName:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXConstructorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
- return DeclContext::lookup_result();
- break;
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
+
case clang::DeclarationName::CXXDestructorName:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXDestructorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
- return DeclContext::lookup_result();
- break;
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
case clang::DeclarationName::CXXConversionFunctionName:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXConversionFunctionName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
- return DeclContext::lookup_result();
- break;
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
case clang::DeclarationName::CXXOperatorName:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXOperatorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
- return DeclContext::lookup_result();
- break;
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
case clang::DeclarationName::CXXLiteralOperatorName:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXLiteralOperatorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
- return DeclContext::lookup_result();
- break;
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
case clang::DeclarationName::CXXUsingDirective:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXUsingDirective\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
- return SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
}
- return DeclContext::lookup_result();
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
}
void
Modified: lldb/branches/lldb-platform-work/source/Symbol/ClangExternalASTSourceCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/ClangExternalASTSourceCommon.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/ClangExternalASTSourceCommon.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/ClangExternalASTSourceCommon.cpp Thu Jun 6 19:06:43 2013
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Core/Stream.h"
using namespace lldb_private;
@@ -27,14 +28,19 @@ ClangExternalASTSourceCommon::~ClangExte
g_TotalSizeOfMetadata -= m_metadata.size();
}
-uint64_t ClangExternalASTSourceCommon::GetMetadata (uintptr_t object)
+ClangASTMetadata *
+ClangExternalASTSourceCommon::GetMetadata (const void *object)
{
assert (m_magic == ClangExternalASTSourceCommon_MAGIC);
- return m_metadata[object];
+ if (HasMetadata (object))
+ return &m_metadata[object];
+ else
+ return NULL;
}
-void ClangExternalASTSourceCommon::SetMetadata (uintptr_t object, uint64_t metadata)
+void
+ClangExternalASTSourceCommon::SetMetadata (const void *object, ClangASTMetadata &metadata)
{
assert (m_magic == ClangExternalASTSourceCommon_MAGIC);
@@ -44,9 +50,40 @@ void ClangExternalASTSourceCommon::SetMe
g_TotalSizeOfMetadata += (new_size - orig_size);
}
-bool ClangExternalASTSourceCommon::HasMetadata (uintptr_t object)
+bool
+ClangExternalASTSourceCommon::HasMetadata (const void *object)
{
assert (m_magic == ClangExternalASTSourceCommon_MAGIC);
return m_metadata.find(object) != m_metadata.end();
}
+
+void
+ClangASTMetadata::Dump (Stream *s)
+{
+ lldb::user_id_t uid = GetUserID ();
+
+ if (uid != LLDB_INVALID_UID)
+ {
+ s->Printf ("uid=0x%" PRIx64, uid);
+ }
+
+ uint64_t isa_ptr = GetISAPtr ();
+ if (isa_ptr != 0)
+ {
+ s->Printf ("isa_ptr=0x%" PRIx64, isa_ptr);
+ }
+
+ const char *obj_ptr_name = GetObjectPtrName();
+ if (obj_ptr_name)
+ {
+ s->Printf ("obj_ptr_name=\"%s\" ", obj_ptr_name);
+ }
+
+ if (m_is_dynamic_cxx)
+ {
+ s->Printf ("is_dynamic_cxx=%i ", m_is_dynamic_cxx);
+ }
+ s->EOL();
+}
+
Modified: lldb/branches/lldb-platform-work/source/Symbol/CompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/CompileUnit.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/CompileUnit.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/CompileUnit.cpp Thu Jun 6 19:06:43 2013
@@ -8,8 +8,9 @@
//===----------------------------------------------------------------------===//
#include "lldb/Symbol/CompileUnit.h"
-#include "lldb/Symbol/LineTable.h"
#include "lldb/Core/Module.h"
+#include "lldb/Core/Language.h"
+#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/VariableList.h"
@@ -20,14 +21,16 @@ CompileUnit::CompileUnit (const lldb::Mo
ModuleChild(module_sp),
FileSpec (pathname, false),
UserID(cu_sym_id),
- Language (language),
m_user_data (user_data),
+ m_language (language),
m_flags (0),
m_functions (),
m_support_files (),
m_line_table_ap (),
m_variables()
{
+ if (language != eLanguageTypeUnknown)
+ m_flags.Set(flagsParsedLanguage);
assert(module_sp);
}
@@ -35,14 +38,16 @@ CompileUnit::CompileUnit (const lldb::Mo
ModuleChild(module_sp),
FileSpec (fspec),
UserID(cu_sym_id),
- Language (language),
m_user_data (user_data),
+ m_language (language),
m_flags (0),
m_functions (),
m_support_files (),
m_line_table_ap (),
m_variables()
{
+ if (language != eLanguageTypeUnknown)
+ m_flags.Set(flagsParsedLanguage);
assert(module_sp);
}
@@ -73,14 +78,15 @@ void
CompileUnit::DumpSymbolContext(Stream *s)
{
GetModule()->DumpSymbolContext(s);
- s->Printf(", CompileUnit{0x%8.8llx}", GetID());
+ s->Printf(", CompileUnit{0x%8.8" PRIx64 "}", GetID());
}
void
CompileUnit::GetDescription(Stream *s, lldb::DescriptionLevel level) const
{
- *s << "id = " << (const UserID&)*this << ", file = \"" << (const FileSpec&)*this << "\", language = \"" << (const Language&)*this << '"';
+ Language language(m_language);
+ *s << "id = " << (const UserID&)*this << ", file = \"" << (const FileSpec&)*this << "\", language = \"" << language << '"';
}
@@ -208,6 +214,26 @@ CompileUnit::FindFunctionByUID (lldb::us
}
+lldb::LanguageType
+CompileUnit::GetLanguage()
+{
+ if (m_language == eLanguageTypeUnknown)
+ {
+ if (m_flags.IsClear(flagsParsedLanguage))
+ {
+ m_flags.Set(flagsParsedLanguage);
+ SymbolVendor* symbol_vendor = GetModule()->GetSymbolVendor();
+ if (symbol_vendor)
+ {
+ SymbolContext sc;
+ CalculateSymbolContext(&sc);
+ m_language = symbol_vendor->ParseCompileUnitLanguage(sc);
+ }
+ }
+ }
+ return m_language;
+}
+
LineTable*
CompileUnit::GetLineTable()
{
@@ -298,7 +324,8 @@ CompileUnit::ResolveSymbolContext
// "file_spec" has an empty directory, then only compare the basenames
// when finding file indexes
std::vector<uint32_t> file_indexes;
- bool file_spec_matches_cu_file_spec = FileSpec::Equal(file_spec, *this, !file_spec.GetDirectory().IsEmpty());
+ const bool full_match = file_spec.GetDirectory();
+ bool file_spec_matches_cu_file_spec = FileSpec::Equal(file_spec, *this, full_match);
// If we are not looking for inlined functions and our file spec doesn't
// match then we are done...
Modified: lldb/branches/lldb-platform-work/source/Symbol/DWARFCallFrameInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/DWARFCallFrameInfo.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/DWARFCallFrameInfo.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/DWARFCallFrameInfo.cpp Thu Jun 6 19:06:43 2013
@@ -17,6 +17,7 @@
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
+#include "lldb/Core/Timer.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -47,54 +48,79 @@ DWARFCallFrameInfo::~DWARFCallFrameInfo(
bool
-DWARFCallFrameInfo::GetAddressRange (Address addr, AddressRange &range)
+DWARFCallFrameInfo::GetUnwindPlan (Address addr, UnwindPlan& unwind_plan)
{
- FDEEntry fde_entry;
- if (GetFDEEntryByAddress (addr, fde_entry) == false)
+ FDEEntryMap::Entry fde_entry;
+
+ // Make sure that the Address we're searching for is the same object file
+ // as this DWARFCallFrameInfo, we only store File offsets in m_fde_index.
+ ModuleSP module_sp = addr.GetModule();
+ if (module_sp.get() == NULL || module_sp->GetObjectFile() == NULL || module_sp->GetObjectFile() != &m_objfile)
return false;
- range = fde_entry.bounds;
- return true;
+
+ if (GetFDEEntryByFileAddress (addr.GetFileAddress(), fde_entry) == false)
+ return false;
+ return FDEToUnwindPlan (fde_entry.data, addr, unwind_plan);
}
bool
-DWARFCallFrameInfo::GetUnwindPlan (Address addr, UnwindPlan& unwind_plan)
+DWARFCallFrameInfo::GetAddressRange (Address addr, AddressRange &range)
{
- FDEEntry fde_entry;
- if (GetFDEEntryByAddress (addr, fde_entry) == false)
+
+ // Make sure that the Address we're searching for is the same object file
+ // as this DWARFCallFrameInfo, we only store File offsets in m_fde_index.
+ ModuleSP module_sp = addr.GetModule();
+ if (module_sp.get() == NULL || module_sp->GetObjectFile() == NULL || module_sp->GetObjectFile() != &m_objfile)
return false;
- return FDEToUnwindPlan (fde_entry.offset, addr, unwind_plan);
+
+ if (m_section_sp.get() == NULL || m_section_sp->IsEncrypted())
+ return false;
+ GetFDEIndex();
+ FDEEntryMap::Entry *fde_entry = m_fde_index.FindEntryThatContains (addr.GetFileAddress());
+ if (!fde_entry)
+ return false;
+
+ range = AddressRange(fde_entry->base, fde_entry->size, m_objfile.GetSectionList());
+ return true;
}
bool
-DWARFCallFrameInfo::GetFDEEntryByAddress (Address addr, FDEEntry& fde_entry)
+DWARFCallFrameInfo::GetFDEEntryByFileAddress (addr_t file_addr, FDEEntryMap::Entry &fde_entry)
{
if (m_section_sp.get() == NULL || m_section_sp->IsEncrypted())
return false;
+
GetFDEIndex();
- struct FDEEntry searchfde;
- searchfde.bounds = AddressRange (addr, 1);
+ if (m_fde_index.IsEmpty())
+ return false;
+
+ FDEEntryMap::Entry *fde = m_fde_index.FindEntryThatContains (file_addr);
- std::vector<FDEEntry>::const_iterator idx;
- if (m_fde_index.size() == 0)
+ if (fde == NULL)
return false;
- idx = std::lower_bound (m_fde_index.begin(), m_fde_index.end(), searchfde);
- if (idx == m_fde_index.end())
- {
- --idx;
- }
- if (idx != m_fde_index.begin() && idx->bounds.GetBaseAddress().GetOffset() != addr.GetOffset())
- {
- --idx;
- }
- if (idx->bounds.ContainsFileAddress (addr))
+ fde_entry = *fde;
+ return true;
+}
+
+void
+DWARFCallFrameInfo::GetFunctionAddressAndSizeVector (FunctionAddressAndSizeVector &function_info)
+{
+ GetFDEIndex();
+ const size_t count = m_fde_index.GetSize();
+ function_info.Clear();
+ if (count > 0)
+ function_info.Reserve(count);
+ for (size_t i = 0; i < count; ++i)
{
- fde_entry = *idx;
- return true;
+ const FDEEntryMap::Entry *func_offset_data_entry = m_fde_index.GetEntryAtIndex (i);
+ if (func_offset_data_entry)
+ {
+ FunctionAddressAndSizeVector::Entry function_offset_entry (func_offset_data_entry->base, func_offset_data_entry->size);
+ function_info.Append (function_offset_entry);
+ }
}
-
- return false;
}
const DWARFCallFrameInfo::CIE*
@@ -117,13 +143,13 @@ DWARFCallFrameInfo::CIESP
DWARFCallFrameInfo::ParseCIE (const dw_offset_t cie_offset)
{
CIESP cie_sp(new CIE(cie_offset));
- dw_offset_t offset = cie_offset;
+ lldb::offset_t offset = cie_offset;
if (m_cfi_data_initialized == false)
GetCFIData();
const uint32_t length = m_cfi_data.GetU32(&offset);
const dw_offset_t cie_id = m_cfi_data.GetU32(&offset);
const dw_offset_t end_offset = cie_offset + length + 4;
- if (length > 0 && ((!m_is_eh_frame && cie_id == 0xfffffffful) || (m_is_eh_frame && cie_id == 0ul)))
+ if (length > 0 && ((!m_is_eh_frame && cie_id == UINT32_MAX) || (m_is_eh_frame && cie_id == 0ul)))
{
size_t i;
// cie.offset = cie_offset;
@@ -277,9 +303,9 @@ DWARFCallFrameInfo::GetCFIData()
{
if (m_cfi_data_initialized == false)
{
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
if (log)
- m_objfile.GetModule()->LogMessage(log.get(), "Reading EH frame info");
+ m_objfile.GetModule()->LogMessage(log, "Reading EH frame info");
m_objfile.ReadSectionData (m_section_sp.get(), m_cfi_data);
m_cfi_data_initialized = true;
}
@@ -302,7 +328,9 @@ DWARFCallFrameInfo::GetFDEIndex ()
if (m_fde_index_initialized) // if two threads hit the locker
return;
- dw_offset_t offset = 0;
+ Timer scoped_timer (__PRETTY_FUNCTION__, "%s - %s", __PRETTY_FUNCTION__, m_objfile.GetFileSpec().GetFilename().AsCString(""));
+
+ lldb::offset_t offset = 0;
if (m_cfi_data_initialized == false)
GetCFIData();
while (m_cfi_data.ValidOffsetForDataOfSize (offset, 8))
@@ -329,10 +357,8 @@ DWARFCallFrameInfo::GetFDEIndex ()
lldb::addr_t addr = m_cfi_data.GetGNUEHPointer(&offset, cie->ptr_encoding, pc_rel_addr, text_addr, data_addr);
lldb::addr_t length = m_cfi_data.GetGNUEHPointer(&offset, cie->ptr_encoding & DW_EH_PE_MASK_ENCODING, pc_rel_addr, text_addr, data_addr);
- FDEEntry fde;
- fde.bounds = AddressRange (addr, length, m_objfile.GetSectionList());
- fde.offset = current_entry;
- m_fde_index.push_back(fde);
+ FDEEntryMap::Entry fde (addr, length, current_entry);
+ m_fde_index.Append(fde);
}
else
{
@@ -344,14 +370,15 @@ DWARFCallFrameInfo::GetFDEIndex ()
}
offset = next_entry;
}
- std::sort (m_fde_index.begin(), m_fde_index.end());
+ m_fde_index.Sort();
m_fde_index_initialized = true;
}
bool
-DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, UnwindPlan& unwind_plan)
+DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr, UnwindPlan& unwind_plan)
{
- dw_offset_t current_entry = offset;
+ lldb::offset_t offset = dwarf_offset;
+ lldb::offset_t current_entry = offset;
if (m_section_sp.get() == NULL || m_section_sp->IsEncrypted())
return false;
@@ -371,11 +398,18 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_
{
unwind_plan.SetSourceName ("eh_frame CFI");
cie_offset = current_entry + 4 - cie_offset;
+ unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
}
else
{
unwind_plan.SetSourceName ("DWARF CFI");
+ // In theory the debug_frame info should be valid at all call sites
+ // ("asynchronous unwind info" as it is sometimes called) but in practice
+ // gcc et al all emit call frame info for the prologue and call sites, but
+ // not for the epilogue or all the other locations during the function reliably.
+ unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
}
+ unwind_plan.SetSourcedFromCompiler (eLazyBoolYes);
const CIE *cie = GetCIE (cie_offset);
assert (cie != NULL);
@@ -407,6 +441,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_
UnwindPlan::RowSP row(cie_initial_row);
unwind_plan.SetRegisterKind (m_reg_kind);
+ unwind_plan.SetReturnAddressRegister (cie->return_addr_reg_num);
UnwindPlan::Row::RegisterLocation reg_location;
while (m_cfi_data.ValidOffset(offset) && offset < end_offset)
Modified: lldb/branches/lldb-platform-work/source/Symbol/FuncUnwinders.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/FuncUnwinders.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/FuncUnwinders.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/FuncUnwinders.cpp Thu Jun 6 19:06:43 2013
@@ -102,8 +102,8 @@ FuncUnwinders::GetUnwindPlanAtNonCallSit
// information. We want to make sure if someone requests an unwind
// plan, that they get one and don't run into a race condition where one
// thread has started to create the unwind plan and has put it into
- // the auto_ptr member variable, and have another thread enter this function
- // and return the partially filled pointer contained in the auto_ptr.
+ // the unique pointer member variable, and have another thread enter this function
+ // and return the partially filled pointer contained in the unique pointer.
// We also want to make sure that we lock out other unwind plans from
// being accessed until this one is done creating itself in case someone
// had some code like:
@@ -128,8 +128,8 @@ FuncUnwinders::GetUnwindPlanFastUnwind (
// information. We want to make sure if someone requests an unwind
// plan, that they get one and don't run into a race condition where one
// thread has started to create the unwind plan and has put it into
- // the auto_ptr member variable, and have another thread enter this function
- // and return the partially filled pointer contained in the auto_ptr.
+ // the unique pointer member variable, and have another thread enter this function
+ // and return the partially filled pointer contained in the unique pointer.
// We also want to make sure that we lock out other unwind plans from
// being accessed until this one is done creating itself in case someone
// had some code like:
@@ -154,8 +154,8 @@ FuncUnwinders::GetUnwindPlanArchitecture
// information. We want to make sure if someone requests an unwind
// plan, that they get one and don't run into a race condition where one
// thread has started to create the unwind plan and has put it into
- // the auto_ptr member variable, and have another thread enter this function
- // and return the partially filled pointer contained in the auto_ptr.
+ // the unique pointer member variable, and have another thread enter this function
+ // and return the partially filled pointer contained in the unique pointer.
// We also want to make sure that we lock out other unwind plans from
// being accessed until this one is done creating itself in case someone
// had some code like:
@@ -190,8 +190,8 @@ FuncUnwinders::GetUnwindPlanArchitecture
// information. We want to make sure if someone requests an unwind
// plan, that they get one and don't run into a race condition where one
// thread has started to create the unwind plan and has put it into
- // the auto_ptr member variable, and have another thread enter this function
- // and return the partially filled pointer contained in the auto_ptr.
+ // the unique pointer member variable, and have another thread enter this function
+ // and return the partially filled pointer contained in the unique pointer.
// We also want to make sure that we lock out other unwind plans from
// being accessed until this one is done creating itself in case someone
// had some code like:
@@ -236,3 +236,12 @@ FuncUnwinders::GetFunctionStartAddress (
return m_range.GetBaseAddress();
}
+void
+FuncUnwinders::InvalidateNonCallSiteUnwindPlan (lldb_private::Thread& thread)
+{
+ UnwindPlanSP arch_default = GetUnwindPlanArchitectureDefault (thread);
+ if (arch_default && m_tried_unwind_at_call_site)
+ {
+ m_unwind_plan_call_site_sp = arch_default;
+ }
+}
Modified: lldb/branches/lldb-platform-work/source/Symbol/Function.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/Function.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/Function.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/Function.cpp Thu Jun 6 19:06:43 2013
@@ -315,11 +315,9 @@ Function::GetBlock (bool can_create)
else
{
Host::SystemLog (Host::eSystemLogError,
- "error: unable to find module shared pointer for function '%s' in %s%s%s\n",
+ "error: unable to find module shared pointer for function '%s' in %s\n",
GetName().GetCString(),
- m_comp_unit->GetDirectory().GetCString(),
- m_comp_unit->GetDirectory() ? "/" : "",
- m_comp_unit->GetFilename().GetCString());
+ m_comp_unit->GetPath().c_str());
}
m_block.SetBlockInfoHasBeenParsed (true, true);
}
@@ -343,7 +341,9 @@ void
Function::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target)
{
Type* func_type = GetType();
- *s << "id = " << (const UserID&)*this << ", name = \"" << func_type->GetName() << "\", range = ";
+ const char *name = func_type ? func_type->GetName().AsCString() : "<unknown>";
+
+ *s << "id = " << (const UserID&)*this << ", name = \"" << name << "\", range = ";
Address::DumpStyle fallback_style;
if (level == eDescriptionLevelVerbose)
@@ -368,7 +368,7 @@ Function::Dump(Stream *s, bool show_cont
}
else if (m_type_uid != LLDB_INVALID_UID)
{
- s->Printf(", type_uid = 0x%8.8llx", m_type_uid);
+ s->Printf(", type_uid = 0x%8.8" PRIx64, m_type_uid);
}
s->EOL();
@@ -390,13 +390,7 @@ Function::CalculateSymbolContextModule (
{
SectionSP section_sp (m_range.GetBaseAddress().GetSection());
if (section_sp)
- {
- SectionSP linked_section_sp (section_sp->GetLinkedSection());
- if (linked_section_sp)
- return linked_section_sp->GetModule();
- else
- return section_sp->GetModule();
- }
+ return section_sp->GetModule();
return this->GetCompileUnit()->GetModule();
}
@@ -424,7 +418,7 @@ void
Function::DumpSymbolContext(Stream *s)
{
m_comp_unit->DumpSymbolContext(s);
- s->Printf(", Function{0x%8.8llx}", GetID());
+ s->Printf(", Function{0x%8.8" PRIx64 "}", GetID());
}
size_t
@@ -493,10 +487,14 @@ Function::GetType() const
clang_type_t
Function::GetReturnClangType ()
{
- clang::QualType clang_type (clang::QualType::getFromOpaquePtr(GetType()->GetClangFullType()));
- const clang::FunctionType *function_type = llvm::dyn_cast<clang::FunctionType> (clang_type);
- if (function_type)
- return function_type->getResultType().getAsOpaquePtr();
+ Type *type = GetType();
+ if (type)
+ {
+ clang::QualType clang_type (clang::QualType::getFromOpaquePtr(type->GetClangFullType()));
+ const clang::FunctionType *function_type = llvm::dyn_cast<clang::FunctionType> (clang_type);
+ if (function_type)
+ return function_type->getResultType().getAsOpaquePtr();
+ }
return NULL;
}
Modified: lldb/branches/lldb-platform-work/source/Symbol/LineTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/LineTable.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/LineTable.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/LineTable.cpp Thu Jun 6 19:06:43 2013
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Core/Address.h"
+#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/Stream.h"
#include "lldb/Symbol/CompileUnit.h"
@@ -22,7 +23,6 @@ using namespace lldb_private;
//----------------------------------------------------------------------
LineTable::LineTable(CompileUnit* comp_unit) :
m_comp_unit(comp_unit),
- m_section_list(),
m_entries()
{
}
@@ -34,18 +34,10 @@ LineTable::~LineTable()
{
}
-//void
-//LineTable::AddLineEntry(const LineEntry& entry)
-//{
-// // Do a binary search for the correct entry and insert it
-// m_line_entries.insert(std::upper_bound(m_line_entries.begin(), m_line_entries.end(), entry), entry);
-//}
-
void
-LineTable::AppendLineEntry
+LineTable::InsertLineEntry
(
- const lldb::SectionSP& section_sp,
- lldb::addr_t section_offset,
+ lldb::addr_t file_addr,
uint32_t line,
uint16_t column,
uint16_t file_idx,
@@ -56,17 +48,41 @@ LineTable::AppendLineEntry
bool is_terminal_entry
)
{
- uint32_t sect_idx = m_section_list.AddUniqueSection (section_sp);
- Entry entry(sect_idx, section_offset, line, column, file_idx, is_start_of_statement, is_start_of_basic_block, is_prologue_end, is_epilogue_begin, is_terminal_entry);
- m_entries.push_back (entry);
+ Entry entry(file_addr, line, column, file_idx, is_start_of_statement, is_start_of_basic_block, is_prologue_end, is_epilogue_begin, is_terminal_entry);
+
+ entry_collection::iterator begin_pos = m_entries.begin();
+ entry_collection::iterator end_pos = m_entries.end();
+ LineTable::Entry::LessThanBinaryPredicate less_than_bp(this);
+ entry_collection::iterator pos = upper_bound(begin_pos, end_pos, entry, less_than_bp);
+
+// Stream s(stdout);
+// s << "\n\nBefore:\n";
+// Dump (&s, Address::DumpStyleFileAddress);
+ m_entries.insert(pos, entry);
+// s << "After:\n";
+// Dump (&s, Address::DumpStyleFileAddress);
}
+LineSequence::LineSequence()
+{
+}
void
-LineTable::InsertLineEntry
+LineTable::LineSequenceImpl::Clear()
+{
+ m_entries.clear();
+}
+
+LineSequence* LineTable::CreateLineSequenceContainer ()
+{
+ return new LineTable::LineSequenceImpl();
+}
+
+void
+LineTable::AppendLineEntryToSequence
(
- const SectionSP& section_sp,
- lldb::addr_t section_offset,
+ LineSequence* sequence,
+ lldb::addr_t file_addr,
uint32_t line,
uint16_t column,
uint16_t file_idx,
@@ -77,33 +93,46 @@ LineTable::InsertLineEntry
bool is_terminal_entry
)
{
- SectionSP line_section_sp;
- SectionSP linked_section_sp (section_sp->GetLinkedSection());
- if (linked_section_sp)
- {
- section_offset += section_sp->GetLinkedOffset();
- line_section_sp = linked_section_sp;
- }
- else
+ assert(sequence != NULL);
+ LineSequenceImpl* seq = reinterpret_cast<LineSequenceImpl*>(sequence);
+ Entry entry(file_addr, line, column, file_idx, is_start_of_statement, is_start_of_basic_block, is_prologue_end, is_epilogue_begin, is_terminal_entry);
+ seq->m_entries.push_back (entry);
+}
+
+void
+LineTable::InsertSequence (LineSequence* sequence)
+{
+ assert(sequence != NULL);
+ LineSequenceImpl* seq = reinterpret_cast<LineSequenceImpl*>(sequence);
+ if (seq->m_entries.empty())
+ return;
+ Entry& entry = seq->m_entries.front();
+
+ // If the first entry address in this sequence is greater than or equal to
+ // the address of the last item in our entry collection, just append.
+ if (m_entries.empty() || !Entry::EntryAddressLessThan(entry, m_entries.back()))
{
- line_section_sp = section_sp;
+ m_entries.insert(m_entries.end(),
+ seq->m_entries.begin(),
+ seq->m_entries.end());
+ return;
}
- assert(line_section_sp.get());
-
- uint32_t sect_idx = m_section_list.AddUniqueSection (line_section_sp);
- Entry entry(sect_idx, section_offset, line, column, file_idx, is_start_of_statement, is_start_of_basic_block, is_prologue_end, is_epilogue_begin, is_terminal_entry);
+ // Otherwise, find where this belongs in the collection
entry_collection::iterator begin_pos = m_entries.begin();
entry_collection::iterator end_pos = m_entries.end();
LineTable::Entry::LessThanBinaryPredicate less_than_bp(this);
entry_collection::iterator pos = upper_bound(begin_pos, end_pos, entry, less_than_bp);
-
-// Stream s(stdout);
-// s << "\n\nBefore:\n";
-// Dump (&s, Address::DumpStyleFileAddress);
- m_entries.insert(pos, entry);
-// s << "After:\n";
-// Dump (&s, Address::DumpStyleFileAddress);
+#ifdef LLDB_CONFIGURATION_DEBUG
+ // If we aren't inserting at the beginning, the previous entry should
+ // terminate a sequence.
+ if (pos != begin_pos)
+ {
+ entry_collection::iterator prev_pos = pos - 1;
+ assert(prev_pos->is_terminal_entry);
+ }
+#endif
+ m_entries.insert(pos, seq->m_entries.begin(), seq->m_entries.end());
}
//----------------------------------------------------------------------
@@ -115,37 +144,23 @@ LineTable::Entry::LessThanBinaryPredicat
bool
LineTable::Entry::LessThanBinaryPredicate::operator() (const LineTable::Entry& a, const LineTable::Entry& b) const
{
- if (a.sect_idx == b.sect_idx)
- {
- #define LT_COMPARE(a,b) if (a != b) return a < b
- LT_COMPARE (a.sect_offset, b.sect_offset);
- // b and a reversed on purpose below.
- LT_COMPARE (b.is_terminal_entry, a.is_terminal_entry);
- LT_COMPARE (a.line, b.line);
- LT_COMPARE (a.column, b.column);
- LT_COMPARE (a.is_start_of_statement, b.is_start_of_statement);
- LT_COMPARE (a.is_start_of_basic_block, b.is_start_of_basic_block);
- // b and a reversed on purpose below.
- LT_COMPARE (b.is_prologue_end, a.is_prologue_end);
- LT_COMPARE (a.is_epilogue_begin, b.is_epilogue_begin);
- LT_COMPARE (a.file_idx, b.file_idx);
- return false;
- #undef LT_COMPARE
- }
-
- const Section *a_section = m_line_table->GetSectionForEntryIndex (a.sect_idx);
- const Section *b_section = m_line_table->GetSectionForEntryIndex (b.sect_idx);
- return Section::Compare(*a_section, *b_section) < 0;
+ #define LT_COMPARE(a,b) if (a != b) return a < b
+ LT_COMPARE (a.file_addr, b.file_addr);
+ // b and a reversed on purpose below.
+ LT_COMPARE (b.is_terminal_entry, a.is_terminal_entry);
+ LT_COMPARE (a.line, b.line);
+ LT_COMPARE (a.column, b.column);
+ LT_COMPARE (a.is_start_of_statement, b.is_start_of_statement);
+ LT_COMPARE (a.is_start_of_basic_block, b.is_start_of_basic_block);
+ // b and a reversed on purpose below.
+ LT_COMPARE (b.is_prologue_end, a.is_prologue_end);
+ LT_COMPARE (a.is_epilogue_begin, b.is_epilogue_begin);
+ LT_COMPARE (a.file_idx, b.file_idx);
+ return false;
+ #undef LT_COMPARE
}
-Section *
-LineTable::GetSectionForEntryIndex (uint32_t idx)
-{
- if (idx < m_section_list.GetSize())
- return m_section_list.GetSectionAtIndex(idx).get();
- return NULL;
-}
uint32_t
LineTable::GetSize() const
@@ -172,69 +187,69 @@ LineTable::FindLineEntryByAddress (const
*index_ptr = UINT32_MAX;
bool success = false;
- uint32_t sect_idx = m_section_list.FindSectionIndex (so_addr.GetSection().get());
- if (sect_idx != UINT32_MAX)
+
+ if (so_addr.GetModule().get() == m_comp_unit->GetModule().get())
{
Entry search_entry;
- search_entry.sect_idx = sect_idx;
- search_entry.sect_offset = so_addr.GetOffset();
-
- entry_collection::const_iterator begin_pos = m_entries.begin();
- entry_collection::const_iterator end_pos = m_entries.end();
- entry_collection::const_iterator pos = lower_bound(begin_pos, end_pos, search_entry, Entry::EntryAddressLessThan);
- if (pos != end_pos)
+ search_entry.file_addr = so_addr.GetFileAddress();
+ if (search_entry.file_addr != LLDB_INVALID_ADDRESS)
{
- if (pos != begin_pos)
+ entry_collection::const_iterator begin_pos = m_entries.begin();
+ entry_collection::const_iterator end_pos = m_entries.end();
+ entry_collection::const_iterator pos = lower_bound(begin_pos, end_pos, search_entry, Entry::EntryAddressLessThan);
+ if (pos != end_pos)
{
- if (pos->sect_offset != search_entry.sect_offset)
- --pos;
- else if (pos->sect_offset == search_entry.sect_offset)
+ if (pos != begin_pos)
{
- // If this is a termination entry, it should't match since
- // entries with the "is_terminal_entry" member set to true
- // are termination entries that define the range for the
- // previous entry.
- if (pos->is_terminal_entry)
+ if (pos->file_addr != search_entry.file_addr)
+ --pos;
+ else if (pos->file_addr == search_entry.file_addr)
{
- // The matching entry is a terminal entry, so we skip
- // ahead to the next entry to see if there is another
- // entry following this one whose section/offset matches.
- ++pos;
- if (pos != end_pos)
+ // If this is a termination entry, it should't match since
+ // entries with the "is_terminal_entry" member set to true
+ // are termination entries that define the range for the
+ // previous entry.
+ if (pos->is_terminal_entry)
{
- if (pos->sect_offset != search_entry.sect_offset)
- pos = end_pos;
+ // The matching entry is a terminal entry, so we skip
+ // ahead to the next entry to see if there is another
+ // entry following this one whose section/offset matches.
+ ++pos;
+ if (pos != end_pos)
+ {
+ if (pos->file_addr != search_entry.file_addr)
+ pos = end_pos;
+ }
}
- }
-
- if (pos != end_pos)
- {
- // While in the same section/offset backup to find the first
- // line entry that matches the address in case there are
- // multiple
- while (pos != begin_pos)
+
+ if (pos != end_pos)
{
- entry_collection::const_iterator prev_pos = pos - 1;
- if (prev_pos->sect_idx == search_entry.sect_idx &&
- prev_pos->sect_offset == search_entry.sect_offset &&
- prev_pos->is_terminal_entry == false)
- --pos;
- else
- break;
+ // While in the same section/offset backup to find the first
+ // line entry that matches the address in case there are
+ // multiple
+ while (pos != begin_pos)
+ {
+ entry_collection::const_iterator prev_pos = pos - 1;
+ if (prev_pos->file_addr == search_entry.file_addr &&
+ prev_pos->is_terminal_entry == false)
+ --pos;
+ else
+ break;
+ }
}
}
- }
- }
-
- // Make sure we have a valid match and that the match isn't a terminating
- // entry for a previous line...
- if (pos != end_pos && pos->is_terminal_entry == false)
- {
- uint32_t match_idx = std::distance (begin_pos, pos);
- success = ConvertEntryAtIndexToLineEntry(match_idx, line_entry);
- if (index_ptr != NULL && success)
- *index_ptr = match_idx;
+ }
+
+ // Make sure we have a valid match and that the match isn't a terminating
+ // entry for a previous line...
+ if (pos != end_pos && pos->is_terminal_entry == false)
+ {
+ uint32_t match_idx = std::distance (begin_pos, pos);
+ success = ConvertEntryAtIndexToLineEntry(match_idx, line_entry);
+ if (index_ptr != NULL && success)
+ *index_ptr = match_idx;
+ }
}
}
}
@@ -248,32 +263,24 @@ LineTable::ConvertEntryAtIndexToLineEntr
if (idx < m_entries.size())
{
const Entry& entry = m_entries[idx];
- line_entry.range.GetBaseAddress().SetSection(m_section_list.GetSectionAtIndex (entry.sect_idx));
- line_entry.range.GetBaseAddress().SetOffset(entry.sect_offset);
- if (!entry.is_terminal_entry && idx + 1 < m_entries.size())
+ ModuleSP module_sp (m_comp_unit->GetModule());
+ if (module_sp && module_sp->ResolveFileAddress(entry.file_addr, line_entry.range.GetBaseAddress()))
{
- const Entry& next_entry = m_entries[idx+1];
- if (next_entry.sect_idx == entry.sect_idx)
- {
- line_entry.range.SetByteSize(next_entry.sect_offset - entry.sect_offset);
- }
+ if (!entry.is_terminal_entry && idx + 1 < m_entries.size())
+ line_entry.range.SetByteSize(m_entries[idx+1].file_addr - entry.file_addr);
else
- {
- Address next_line_addr(m_section_list.GetSectionAtIndex (next_entry.sect_idx), next_entry.sect_offset);
- line_entry.range.SetByteSize(next_line_addr.GetFileAddress() - line_entry.range.GetBaseAddress().GetFileAddress());
- }
+ line_entry.range.SetByteSize(0);
+
+ line_entry.file = m_comp_unit->GetSupportFiles().GetFileSpecAtIndex (entry.file_idx);
+ line_entry.line = entry.line;
+ line_entry.column = entry.column;
+ line_entry.is_start_of_statement = entry.is_start_of_statement;
+ line_entry.is_start_of_basic_block = entry.is_start_of_basic_block;
+ line_entry.is_prologue_end = entry.is_prologue_end;
+ line_entry.is_epilogue_begin = entry.is_epilogue_begin;
+ line_entry.is_terminal_entry = entry.is_terminal_entry;
+ return true;
}
- else
- line_entry.range.SetByteSize(0);
- line_entry.file = m_comp_unit->GetSupportFiles().GetFileSpecAtIndex (entry.file_idx);
- line_entry.line = entry.line;
- line_entry.column = entry.column;
- line_entry.is_start_of_statement = entry.is_start_of_statement;
- line_entry.is_start_of_basic_block = entry.is_start_of_basic_block;
- line_entry.is_prologue_end = entry.is_prologue_end;
- line_entry.is_epilogue_begin = entry.is_epilogue_begin;
- line_entry.is_terminal_entry = entry.is_terminal_entry;
- return true;
}
return false;
}
@@ -448,5 +455,134 @@ LineTable::GetDescription (Stream *s, Ta
}
}
+size_t
+LineTable::GetContiguousFileAddressRanges (FileAddressRanges &file_ranges, bool append)
+{
+ if (!append)
+ file_ranges.Clear();
+ const size_t initial_count = file_ranges.GetSize();
+
+ const size_t count = m_entries.size();
+ LineEntry line_entry;
+ FileAddressRanges::Entry range (LLDB_INVALID_ADDRESS, 0);
+ for (size_t idx = 0; idx < count; ++idx)
+ {
+ const Entry& entry = m_entries[idx];
+
+ if (entry.is_terminal_entry)
+ {
+ if (range.GetRangeBase() != LLDB_INVALID_ADDRESS)
+ {
+ range.SetRangeEnd(entry.file_addr);
+ file_ranges.Append(range);
+ range.Clear(LLDB_INVALID_ADDRESS);
+ }
+ }
+ else if (range.GetRangeBase() == LLDB_INVALID_ADDRESS)
+ {
+ range.SetRangeBase(entry.file_addr);
+ }
+ }
+ return file_ranges.GetSize() - initial_count;
+}
+
+LineTable *
+LineTable::LinkLineTable (const FileRangeMap &file_range_map)
+{
+ std::unique_ptr<LineTable> line_table_ap (new LineTable (m_comp_unit));
+ LineSequenceImpl sequence;
+ const size_t count = m_entries.size();
+ LineEntry line_entry;
+ const FileRangeMap::Entry *file_range_entry = NULL;
+ const FileRangeMap::Entry *prev_file_range_entry = NULL;
+ lldb::addr_t prev_file_addr = LLDB_INVALID_ADDRESS;
+ bool prev_entry_was_linked = false;
+ bool range_changed = false;
+ for (size_t idx = 0; idx < count; ++idx)
+ {
+ const Entry& entry = m_entries[idx];
+
+ const bool end_sequence = entry.is_terminal_entry;
+ const lldb::addr_t lookup_file_addr = entry.file_addr - (end_sequence ? 1 : 0);
+ if (file_range_entry == NULL || !file_range_entry->Contains(lookup_file_addr))
+ {
+ prev_file_range_entry = file_range_entry;
+ file_range_entry = file_range_map.FindEntryThatContains(lookup_file_addr);
+ range_changed = true;
+ }
+
+ lldb::addr_t prev_end_entry_linked_file_addr = LLDB_INVALID_ADDRESS;
+ lldb::addr_t entry_linked_file_addr = LLDB_INVALID_ADDRESS;
+
+ bool terminate_previous_entry = false;
+ if (file_range_entry)
+ {
+ entry_linked_file_addr = entry.file_addr - file_range_entry->GetRangeBase() + file_range_entry->data;
+ // Determine if we need to terminate the previous entry when the previous
+ // entry was not contguous with this one after being linked.
+ if (range_changed && prev_file_range_entry)
+ {
+ prev_end_entry_linked_file_addr = std::min<lldb::addr_t>(entry.file_addr, prev_file_range_entry->GetRangeEnd()) - prev_file_range_entry->GetRangeBase() + prev_file_range_entry->data;
+ if (prev_end_entry_linked_file_addr != entry_linked_file_addr)
+ terminate_previous_entry = prev_entry_was_linked;
+ }
+ }
+ else if (prev_entry_was_linked)
+ {
+ // This entry doesn't have a remapping and it needs to be removed.
+ // Watch out in case we need to terminate a previous entry needs to
+ // be terminated now that one line entry in a sequence is not longer valid.
+ if (!entry.is_terminal_entry &&
+ !sequence.m_entries.empty() &&
+ !sequence.m_entries.back().is_terminal_entry)
+ {
+ terminate_previous_entry = true;
+ }
+ }
+
+ if (terminate_previous_entry && !sequence.m_entries.empty())
+ {
+ assert (prev_file_addr != LLDB_INVALID_ADDRESS);
+ sequence.m_entries.push_back(sequence.m_entries.back());
+ if (prev_end_entry_linked_file_addr == LLDB_INVALID_ADDRESS)
+ prev_end_entry_linked_file_addr = std::min<lldb::addr_t>(entry.file_addr,prev_file_range_entry->GetRangeEnd()) - prev_file_range_entry->GetRangeBase() + prev_file_range_entry->data;
+ sequence.m_entries.back().file_addr = prev_end_entry_linked_file_addr;
+ sequence.m_entries.back().is_terminal_entry = true;
+
+ // Append the sequence since we just terminated the previous one
+ line_table_ap->InsertSequence (&sequence);
+ sequence.Clear();
+ prev_entry_was_linked = false;
+ }
+
+ // Now link the current entry
+ if (file_range_entry)
+ {
+ // This entry has an address remapping and it needs to have its address relinked
+ sequence.m_entries.push_back(entry);
+ sequence.m_entries.back().file_addr = entry_linked_file_addr;
+ }
+
+ // If we have items in the sequence and the last entry is a terminal entry,
+ // insert this sequence into our new line table.
+ if (!sequence.m_entries.empty() && sequence.m_entries.back().is_terminal_entry)
+ {
+ line_table_ap->InsertSequence (&sequence);
+ sequence.Clear();
+ prev_entry_was_linked = false;
+ }
+ else
+ {
+ prev_entry_was_linked = file_range_entry != NULL;
+ }
+ prev_file_addr = entry.file_addr;
+ range_changed = false;
+ }
+ if (line_table_ap->m_entries.empty())
+ return NULL;
+ return line_table_ap.release();
+}
+
+
Modified: lldb/branches/lldb-platform-work/source/Symbol/ObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/ObjectFile.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/ObjectFile.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/ObjectFile.cpp Thu Jun 6 19:06:43 2013
@@ -13,74 +13,117 @@
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/Section.h"
#include "lldb/Core/Timer.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/ObjectContainer.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Target/Process.h"
+#include "Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h"
using namespace lldb;
using namespace lldb_private;
ObjectFileSP
-ObjectFile::FindPlugin (const lldb::ModuleSP &module_sp, const FileSpec* file, addr_t file_offset, addr_t file_size, DataBufferSP &file_data_sp)
+ObjectFile::FindPlugin (const lldb::ModuleSP &module_sp,
+ const FileSpec* file,
+ lldb::offset_t file_offset,
+ lldb::offset_t file_size,
+ DataBufferSP &data_sp,
+ lldb::offset_t &data_offset)
{
ObjectFileSP object_file_sp;
if (module_sp)
{
Timer scoped_timer (__PRETTY_FUNCTION__,
- "ObjectFile::FindPlugin (module = %s/%s, file = %p, file_offset = 0x%z8.8x, file_size = 0x%z8.8x)",
- module_sp->GetFileSpec().GetDirectory().AsCString(),
- module_sp->GetFileSpec().GetFilename().AsCString(),
- file, file_offset, file_size);
+ "ObjectFile::FindPlugin (module = %s, file = %p, file_offset = 0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")",
+ module_sp->GetFileSpec().GetPath().c_str(),
+ file, (uint64_t) file_offset, (uint64_t) file_size);
if (file)
{
- // Memory map the entire file contents
- if (!file_data_sp)
+ FileSpec archive_file;
+ ObjectContainerCreateInstance create_object_container_callback;
+
+ const bool file_exists = file->Exists();
+ if (!data_sp)
{
- assert (file_offset == 0);
- file_data_sp = file->MemoryMapFileContents(file_offset, file_size);
+ // We have an object name which most likely means we have
+ // a .o file in a static archive (.a file). Try and see if
+ // we have a cached archive first without reading any data
+ // first
+ if (file_exists && module_sp->GetObjectName())
+ {
+ for (uint32_t idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ {
+ std::unique_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size));
+
+ if (object_container_ap.get())
+ object_file_sp = object_container_ap->GetObjectFile(file);
+
+ if (object_file_sp.get())
+ return object_file_sp;
+ }
+ }
+ // Ok, we didn't find any containers that have a named object, now
+ // lets read the first 512 bytes from the file so the object file
+ // and object container plug-ins can use these bytes to see if they
+ // can parse this file.
+ if (file_size > 0)
+ {
+ data_sp = file->ReadFileContents(file_offset, std::min<size_t>(512, file_size));
+ data_offset = 0;
+ }
}
- if (!file_data_sp || file_data_sp->GetByteSize() == 0)
+ if (!data_sp || data_sp->GetByteSize() == 0)
{
// Check for archive file with format "/path/to/archive.a(object.o)"
char path_with_object[PATH_MAX*2];
module_sp->GetFileSpec().GetPath(path_with_object, sizeof(path_with_object));
- RegularExpression g_object_regex("(.*)\\(([^\\)]+)\\)$");
- if (g_object_regex.Execute (path_with_object, 2))
+ ConstString archive_object;
+ const bool must_exist = true;
+ if (ObjectFile::SplitArchivePathWithObject (path_with_object, archive_file, archive_object, must_exist))
{
- FileSpec archive_file;
- std::string path;
- std::string object;
- if (g_object_regex.GetMatchAtIndex (path_with_object, 1, path) &&
- g_object_regex.GetMatchAtIndex (path_with_object, 2, object))
+ file_size = archive_file.GetByteSize();
+ if (file_size > 0)
{
- archive_file.SetFile (path.c_str(), false);
- file_size = archive_file.GetByteSize();
- if (file_size > 0)
+ file = &archive_file;
+ module_sp->SetFileSpecAndObjectName (archive_file, archive_object);
+ // Check if this is a object container by iterating through all object
+ // container plugin instances and then trying to get an object file
+ // from the container plugins since we had a name. Also, don't read
+ // ANY data in case there is data cached in the container plug-ins
+ // (like BSD archives caching the contained objects within an file).
+ for (uint32_t idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx)
{
- module_sp->SetFileSpecAndObjectName (archive_file, ConstString(object.c_str()));
- file_data_sp = archive_file.MemoryMapFileContents(file_offset, file_size);
+ std::unique_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size));
+
+ if (object_container_ap.get())
+ object_file_sp = object_container_ap->GetObjectFile(file);
+
+ if (object_file_sp.get())
+ return object_file_sp;
}
+ // We failed to find any cached object files in the container
+ // plug-ins, so lets read the first 512 bytes and try again below...
+ data_sp = archive_file.ReadFileContents(file_offset, 512);
}
}
}
- if (file_data_sp && file_data_sp->GetByteSize() > 0)
+ if (data_sp && data_sp->GetByteSize() > 0)
{
- uint32_t idx;
-
// Check if this is a normal object file by iterating through
// all object file plugin instances.
ObjectFileCreateInstance create_object_file_callback;
- for (idx = 0; (create_object_file_callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ for (uint32_t idx = 0; (create_object_file_callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) != NULL; ++idx)
{
- object_file_sp.reset (create_object_file_callback(module_sp, file_data_sp, file, file_offset, file_size));
+ object_file_sp.reset (create_object_file_callback(module_sp, data_sp, data_offset, file, file_offset, file_size));
if (object_file_sp.get())
return object_file_sp;
}
@@ -88,10 +131,9 @@ ObjectFile::FindPlugin (const lldb::Modu
// Check if this is a object container by iterating through
// all object container plugin instances and then trying to get
// an object file from the container.
- ObjectContainerCreateInstance create_object_container_callback;
- for (idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ for (uint32_t idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx)
{
- std::auto_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module_sp, file_data_sp, file, file_offset, file_size));
+ std::unique_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size));
if (object_container_ap.get())
object_file_sp = object_container_ap->GetObjectFile(file);
@@ -112,16 +154,15 @@ ObjectFileSP
ObjectFile::FindPlugin (const lldb::ModuleSP &module_sp,
const ProcessSP &process_sp,
lldb::addr_t header_addr,
- DataBufferSP &file_data_sp)
+ DataBufferSP &data_sp)
{
ObjectFileSP object_file_sp;
if (module_sp)
{
Timer scoped_timer (__PRETTY_FUNCTION__,
- "ObjectFile::FindPlugin (module = %s/%s, process = %p, header_addr = 0x%llx)",
- module_sp->GetFileSpec().GetDirectory().AsCString(),
- module_sp->GetFileSpec().GetFilename().AsCString(),
+ "ObjectFile::FindPlugin (module = %s, process = %p, header_addr = 0x%" PRIx64 ")",
+ module_sp->GetFileSpec().GetPath().c_str(),
process_sp.get(), header_addr);
uint32_t idx;
@@ -130,7 +171,7 @@ ObjectFile::FindPlugin (const lldb::Modu
ObjectFileCreateMemoryInstance create_callback;
for (idx = 0; (create_callback = PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(idx)) != NULL; ++idx)
{
- object_file_sp.reset (create_callback(module_sp, file_data_sp, process_sp, header_addr));
+ object_file_sp.reset (create_callback(module_sp, data_sp, process_sp, header_addr));
if (object_file_sp.get())
return object_file_sp;
}
@@ -142,47 +183,93 @@ ObjectFile::FindPlugin (const lldb::Modu
return object_file_sp;
}
-ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
- const FileSpec *file_spec_ptr,
- addr_t file_offset,
- addr_t file_size,
- DataBufferSP& file_data_sp) :
+size_t
+ObjectFile::GetModuleSpecifications (const FileSpec &file,
+ lldb::offset_t file_offset,
+ ModuleSpecList &specs)
+{
+ DataBufferSP data_sp (file.ReadFileContents(file_offset, 512));
+ if (data_sp)
+ return ObjectFile::GetModuleSpecifications (file, // file spec
+ data_sp, // data bytes
+ 0, // data offset
+ file_offset, // file offset
+ data_sp->GetByteSize(), // data length
+ specs);
+ return 0;
+}
+
+size_t
+ObjectFile::GetModuleSpecifications (const lldb_private::FileSpec& file,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
+ lldb::offset_t file_offset,
+ lldb::offset_t length,
+ lldb_private::ModuleSpecList &specs)
+{
+ const size_t initial_count = specs.GetSize();
+ ObjectFileGetModuleSpecifications callback;
+ uint32_t i;
+ // Try the ObjectFile plug-ins
+ for (i = 0; (callback = PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(i)) != NULL; ++i)
+ {
+ if (callback (file, data_sp, data_offset, file_offset, length, specs) > 0)
+ return specs.GetSize() - initial_count;
+ }
+
+ // Try the ObjectContainer plug-ins
+ for (i = 0; (callback = PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(i)) != NULL; ++i)
+ {
+ if (callback (file, data_sp, data_offset, file_offset, length, specs) > 0)
+ return specs.GetSize() - initial_count;
+ }
+ return 0;
+}
+
+ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
+ const FileSpec *file_spec_ptr,
+ lldb::offset_t file_offset,
+ lldb::offset_t length,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset
+) :
ModuleChild (module_sp),
m_file (), // This file could be different from the original module's file
m_type (eTypeInvalid),
m_strata (eStrataInvalid),
- m_offset (file_offset),
- m_length (file_size),
+ m_file_offset (file_offset),
+ m_length (length),
m_data (),
m_unwind_table (*this),
m_process_wp(),
- m_memory_addr (LLDB_INVALID_ADDRESS)
-{
+ m_memory_addr (LLDB_INVALID_ADDRESS),
+ m_sections_ap (),
+ m_symtab_ap ()
+{
if (file_spec_ptr)
m_file = *file_spec_ptr;
- if (file_data_sp)
- m_data.SetData (file_data_sp, file_offset, file_size);
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+ if (data_sp)
+ m_data.SetData (data_sp, data_offset, length);
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
{
if (m_file)
{
- log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = %s/%s, offset = 0x%8.8llx, size = %llu\n",
+ log->Printf ("%p ObjectFile::ObjectFile() module = %p (%s), file = %s, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64,
this,
- module_sp->GetFileSpec().GetDirectory().AsCString(),
- module_sp->GetFileSpec().GetFilename().AsCString(),
- m_file.GetDirectory().AsCString(),
- m_file.GetFilename().AsCString(),
- m_offset,
+ module_sp.get(),
+ module_sp->GetSpecificationDescription().c_str(),
+ m_file.GetPath().c_str(),
+ m_file_offset,
m_length);
}
else
{
- log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = <NULL>, offset = 0x%8.8llx, size = %llu\n",
+ log->Printf ("%p ObjectFile::ObjectFile() module = %p (%s), file = <NULL>, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64,
this,
- module_sp->GetFileSpec().GetDirectory().AsCString(),
- module_sp->GetFileSpec().GetFilename().AsCString(),
- m_offset,
+ module_sp.get(),
+ module_sp->GetSpecificationDescription().c_str(),
+ m_file_offset,
m_length);
}
}
@@ -197,55 +284,35 @@ ObjectFile::ObjectFile (const lldb::Modu
m_file (),
m_type (eTypeInvalid),
m_strata (eStrataInvalid),
- m_offset (header_addr),
+ m_file_offset (0),
m_length (0),
m_data (),
m_unwind_table (*this),
m_process_wp (process_sp),
- m_memory_addr (header_addr)
-{
+ m_memory_addr (header_addr),
+ m_sections_ap (),
+ m_symtab_ap ()
+{
if (header_data_sp)
m_data.SetData (header_data_sp, 0, header_data_sp->GetByteSize());
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
{
- log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, process = %p, header_addr = 0x%llx\n",
+ log->Printf ("%p ObjectFile::ObjectFile() module = %p (%s), process = %p, header_addr = 0x%" PRIx64,
this,
- module_sp->GetFileSpec().GetDirectory().AsCString(),
- module_sp->GetFileSpec().GetFilename().AsCString(),
+ module_sp.get(),
+ module_sp->GetSpecificationDescription().c_str(),
process_sp.get(),
- m_offset);
+ m_memory_addr);
}
}
ObjectFile::~ObjectFile()
{
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
- {
- ModuleSP module_sp (GetModule());
- if (m_file)
- {
- log->Printf ("%p ObjectFile::~ObjectFile () module = %s/%s, file = %s/%s, offset = 0x%8.8llx, size = %llu\n",
- this,
- module_sp->GetFileSpec().GetDirectory().AsCString(),
- module_sp->GetFileSpec().GetFilename().AsCString(),
- m_file.GetDirectory().AsCString(),
- m_file.GetFilename().AsCString(),
- m_offset,
- m_length);
- }
- else
- {
- log->Printf ("%p ObjectFile::~ObjectFile () module = %s/%s, file = <NULL>, offset = 0x%8.8llx, size = %llu\n",
- this,
- module_sp->GetFileSpec().GetDirectory().AsCString(),
- module_sp->GetFileSpec().GetFilename().AsCString(),
- m_offset,
- m_length);
- }
- }
+ log->Printf ("%p ObjectFile::~ObjectFile ()\n", this);
}
bool
@@ -319,6 +386,7 @@ ObjectFile::GetAddressClass (addr_t file
case eSymbolTypeAbsolute: return eAddressClassUnknown;
case eSymbolTypeCode: return eAddressClassCode;
case eSymbolTypeTrampoline: return eAddressClassCode;
+ case eSymbolTypeResolver: return eAddressClassCode;
case eSymbolTypeData: return eAddressClassData;
case eSymbolTypeRuntime: return eAddressClassRuntime;
case eSymbolTypeException: return eAddressClassRuntime;
@@ -354,7 +422,7 @@ ObjectFile::ReadMemory (const ProcessSP
DataBufferSP data_sp;
if (process_sp)
{
- std::auto_ptr<DataBufferHeap> data_ap (new DataBufferHeap (byte_size, 0));
+ std::unique_ptr<DataBufferHeap> data_ap (new DataBufferHeap (byte_size, 0));
Error error;
const size_t bytes_read = process_sp->ReadMemory (addr,
data_ap->GetBytes(),
@@ -391,7 +459,9 @@ ObjectFile::ReadSectionData (const Secti
if (process_sp)
{
Error error;
- return process_sp->ReadMemory (section->GetLoadBaseAddress (&process_sp->GetTarget()) + section_offset, dst, dst_len, error);
+ const addr_t base_load_addr = section->GetLoadBaseAddress (&process_sp->GetTarget());
+ if (base_load_addr != LLDB_INVALID_ADDRESS)
+ return process_sp->ReadMemory (base_load_addr + section_offset, dst, dst_len, error);
}
}
else
@@ -405,6 +475,19 @@ ObjectFile::ReadSectionData (const Secti
section_dst_len = section_bytes_left;
return CopyData (section->GetFileOffset() + section_offset, section_dst_len, dst);
}
+ else
+ {
+ if (section->GetType() == eSectionTypeZeroFill)
+ {
+ const uint64_t section_size = section->GetByteSize();
+ const uint64_t section_bytes_left = section_size - section_offset;
+ uint64_t section_dst_len = dst_len;
+ if (section_dst_len > section_bytes_left)
+ section_dst_len = section_bytes_left;
+ bzero(dst, section_dst_len);
+ return section_dst_len;
+ }
+ }
}
return 0;
}
@@ -420,13 +503,17 @@ ObjectFile::ReadSectionData (const Secti
ProcessSP process_sp (m_process_wp.lock());
if (process_sp)
{
- DataBufferSP data_sp (ReadMemory (process_sp, section->GetLoadBaseAddress (&process_sp->GetTarget()), section->GetByteSize()));
- if (data_sp)
+ const addr_t base_load_addr = section->GetLoadBaseAddress (&process_sp->GetTarget());
+ if (base_load_addr != LLDB_INVALID_ADDRESS)
{
- section_data.SetData (data_sp, 0, data_sp->GetByteSize());
- section_data.SetByteOrder (process_sp->GetByteOrder());
- section_data.SetAddressByteSize (process_sp->GetAddressByteSize());
- return section_data.GetByteSize();
+ DataBufferSP data_sp (ReadMemory (process_sp, base_load_addr, section->GetByteSize()));
+ if (data_sp)
+ {
+ section_data.SetData (data_sp, 0, data_sp->GetByteSize());
+ section_data.SetByteOrder (process_sp->GetByteOrder());
+ section_data.SetAddressByteSize (process_sp->GetAddressByteSize());
+ return section_data.GetByteSize();
+ }
}
}
}
@@ -455,3 +542,43 @@ ObjectFile::MemoryMapSectionData (const
return 0;
}
+
+bool
+ObjectFile::SplitArchivePathWithObject (const char *path_with_object, FileSpec &archive_file, ConstString &archive_object, bool must_exist)
+{
+ RegularExpression g_object_regex("(.*)\\(([^\\)]+)\\)$");
+ RegularExpression::Match regex_match(2);
+ if (g_object_regex.Execute (path_with_object, ®ex_match))
+ {
+ std::string path;
+ std::string obj;
+ if (regex_match.GetMatchAtIndex (path_with_object, 1, path) &&
+ regex_match.GetMatchAtIndex (path_with_object, 2, obj))
+ {
+ archive_file.SetFile (path.c_str(), false);
+ archive_object.SetCString(obj.c_str());
+ if (must_exist && !archive_file.Exists())
+ return false;
+ return true;
+ }
+ }
+ return false;
+}
+
+void
+ObjectFile::ClearSymtab ()
+{
+ ModuleSP module_sp(GetModule());
+ if (module_sp)
+ {
+ lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+ if (log)
+ {
+ log->Printf ("%p ObjectFile::ClearSymtab () symtab = %p",
+ this,
+ m_symtab_ap.get());
+ }
+ m_symtab_ap.reset();
+ }
+}
Modified: lldb/branches/lldb-platform-work/source/Symbol/Symbol.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/Symbol.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/Symbol.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/Symbol.cpp Thu Jun 6 19:06:43 2013
@@ -12,6 +12,8 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/Stream.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/Symtab.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
@@ -31,6 +33,7 @@ Symbol::Symbol() :
m_size_is_sibling (false),
m_size_is_synthesized (false),
m_calculated_size (false),
+ m_demangled_is_synthesized (false),
m_type (eSymbolTypeInvalid),
m_flags (),
m_addr_range ()
@@ -49,7 +52,8 @@ Symbol::Symbol
bool is_artificial,
const lldb::SectionSP §ion_sp,
addr_t offset,
- uint32_t size,
+ addr_t size,
+ bool size_is_valid,
uint32_t flags
) :
SymbolContextScope (),
@@ -62,7 +66,8 @@ Symbol::Symbol
m_is_external (external),
m_size_is_sibling (false),
m_size_is_synthesized (false),
- m_calculated_size (size > 0),
+ m_calculated_size (size_is_valid || size > 0),
+ m_demangled_is_synthesized (false),
m_type (type),
m_flags (flags),
m_addr_range (section_sp, offset, size)
@@ -80,6 +85,7 @@ Symbol::Symbol
bool is_trampoline,
bool is_artificial,
const AddressRange &range,
+ bool size_is_valid,
uint32_t flags
) :
SymbolContextScope (),
@@ -92,7 +98,8 @@ Symbol::Symbol
m_is_external (external),
m_size_is_sibling (false),
m_size_is_synthesized (false),
- m_calculated_size (range.GetByteSize() > 0),
+ m_calculated_size (size_is_valid || range.GetByteSize() > 0),
+ m_demangled_is_synthesized (false),
m_type (type),
m_flags (flags),
m_addr_range (range)
@@ -111,6 +118,7 @@ Symbol::Symbol(const Symbol& rhs):
m_size_is_sibling (rhs.m_size_is_sibling),
m_size_is_synthesized (false),
m_calculated_size (rhs.m_calculated_size),
+ m_demangled_is_synthesized (rhs.m_demangled_is_synthesized),
m_type (rhs.m_type),
m_flags (rhs.m_flags),
m_addr_range (rhs.m_addr_range)
@@ -133,6 +141,7 @@ Symbol::operator= (const Symbol& rhs)
m_size_is_sibling = rhs.m_size_is_sibling;
m_size_is_synthesized = rhs.m_size_is_sibling;
m_calculated_size = rhs.m_calculated_size;
+ m_demangled_is_synthesized = rhs.m_demangled_is_synthesized;
m_type = rhs.m_type;
m_flags = rhs.m_flags;
m_addr_range = rhs.m_addr_range;
@@ -153,6 +162,7 @@ Symbol::Clear()
m_size_is_sibling = false;
m_size_is_synthesized = false;
m_calculated_size = false;
+ m_demangled_is_synthesized = false;
m_type = eSymbolTypeInvalid;
m_flags = 0;
m_addr_range.Clear();
@@ -176,6 +186,12 @@ Symbol::IsTrampoline () const
return m_type == eSymbolTypeTrampoline;
}
+bool
+Symbol::IsIndirect () const
+{
+ return m_type == eSymbolTypeResolver;
+}
+
void
Symbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const
{
@@ -198,14 +214,14 @@ Symbol::GetDescription (Stream *s, lldb:
}
}
else
- s->Printf (", value = 0x%16.16llx", m_addr_range.GetBaseAddress().GetOffset());
+ s->Printf (", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset());
}
else
{
if (m_size_is_sibling)
- s->Printf (", sibling = %5llu", m_addr_range.GetBaseAddress().GetOffset());
+ s->Printf (", sibling = %5" PRIu64, m_addr_range.GetBaseAddress().GetOffset());
else
- s->Printf (", value = 0x%16.16llx", m_addr_range.GetBaseAddress().GetOffset());
+ s->Printf (", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset());
}
if (m_mangled.GetDemangledName())
s->Printf(", name=\"%s\"", m_mangled.GetDemangledName().AsCString());
@@ -243,7 +259,7 @@ Symbol::Dump(Stream *s, Target *target,
const char *format = m_size_is_sibling ?
" Sibling -> [%5llu] 0x%8.8x %s\n":
- " 0x%16.16llx 0x%8.8x %s\n";
+ " 0x%16.16" PRIx64 " 0x%8.8x %s\n";
s->Printf( format,
GetByteSize(),
m_flags,
@@ -252,8 +268,8 @@ Symbol::Dump(Stream *s, Target *target,
else
{
const char *format = m_size_is_sibling ?
- "0x%16.16llx Sibling -> [%5llu] 0x%8.8x %s\n":
- "0x%16.16llx 0x%16.16llx 0x%8.8x %s\n";
+ "0x%16.16" PRIx64 " Sibling -> [%5llu] 0x%8.8x %s\n":
+ "0x%16.16" PRIx64 " 0x%16.16" PRIx64 " 0x%8.8x %s\n";
s->Printf( format,
m_addr_range.GetBaseAddress().GetOffset(),
GetByteSize(),
@@ -265,7 +281,7 @@ Symbol::Dump(Stream *s, Target *target,
uint32_t
Symbol::GetPrologueByteSize ()
{
- if (m_type == eSymbolTypeCode)
+ if (m_type == eSymbolTypeCode || m_type == eSymbolTypeResolver)
{
if (!m_type_data_resolved)
{
Modified: lldb/branches/lldb-platform-work/source/Symbol/SymbolContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/SymbolContext.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/SymbolContext.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/SymbolContext.cpp Thu Jun 6 19:06:43 2013
@@ -11,6 +11,7 @@
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Symbol/Block.h"
@@ -107,9 +108,10 @@ SymbolContext::operator= (const SymbolCo
}
void
-SymbolContext::Clear()
+SymbolContext::Clear(bool clear_target)
{
- target_sp.reset();
+ if (clear_target)
+ target_sp.reset();
module_sp.reset();
comp_unit = NULL;
function = NULL;
@@ -156,7 +158,7 @@ SymbolContext::DumpStopContext
if (function_offset)
{
dumped_something = true;
- s->Printf(" + %llu", function_offset);
+ s->Printf(" + %" PRIu64, function_offset);
}
}
@@ -173,7 +175,7 @@ SymbolContext::DumpStopContext
const addr_t inlined_function_offset = addr.GetOffset() - block_range.GetBaseAddress().GetOffset();
if (inlined_function_offset)
{
- s->Printf(" + %llu", inlined_function_offset);
+ s->Printf(" + %" PRIu64, inlined_function_offset);
}
}
const Declaration &call_site = inlined_block_info->GetCallSite();
@@ -216,7 +218,7 @@ SymbolContext::DumpStopContext
if (symbol_offset)
{
dumped_something = true;
- s->Printf(" + %llu", symbol_offset);
+ s->Printf(" + %" PRIu64, symbol_offset);
}
}
}
@@ -317,7 +319,6 @@ SymbolContext::GetResolvedMask () const
return resolved_mask;
}
-
void
SymbolContext::Dump(Stream *s, Target *target) const
{
@@ -452,7 +453,7 @@ SymbolContext::GetParentOfInlinedScope (
SymbolContext &next_frame_sc,
Address &next_frame_pc) const
{
- next_frame_sc.Clear();
+ next_frame_sc.Clear(false);
next_frame_pc.Clear();
if (block)
@@ -491,11 +492,11 @@ SymbolContext::GetParentOfInlinedScope (
}
else
{
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
if (log)
{
- log->Printf ("warning: inlined block 0x%8.8llx doesn't have a range that contains file address 0x%llx",
+ log->Printf ("warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64,
curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress());
}
#ifdef LLDB_CONFIGURATION_DEBUG
@@ -515,16 +516,15 @@ SymbolContext::GetParentOfInlinedScope (
if (objfile)
{
Host::SystemLog (Host::eSystemLogWarning,
- "warning: inlined block 0x%8.8llx doesn't have a range that contains file address 0x%llx in %s/%s\n",
+ "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 " in %s\n",
curr_inlined_block->GetID(),
curr_frame_pc.GetFileAddress(),
- objfile->GetFileSpec().GetDirectory().GetCString(),
- objfile->GetFileSpec().GetFilename().GetCString());
+ objfile->GetFileSpec().GetPath().c_str());
}
else
{
Host::SystemLog (Host::eSystemLogWarning,
- "warning: inlined block 0x%8.8llx doesn't have a range that contains file address 0x%llx\n",
+ "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 "\n",
curr_inlined_block->GetID(),
curr_frame_pc.GetFileAddress());
}
@@ -592,7 +592,7 @@ SymbolContext::GetFunctionMethodInfo (ll
}
ConstString
-SymbolContext::GetFunctionName (Mangled::NamePreference preference)
+SymbolContext::GetFunctionName (Mangled::NamePreference preference) const
{
if (function)
{
@@ -620,6 +620,33 @@ SymbolContext::GetFunctionName (Mangled:
}
}
+LineEntry
+SymbolContext::GetFunctionStartLineEntry () const
+{
+ LineEntry line_entry;
+ Address start_addr;
+ if (block)
+ {
+ Block *inlined_block = block->GetContainingInlinedBlock();
+ if (inlined_block)
+ {
+ if (inlined_block->GetStartAddress (start_addr))
+ {
+ if (start_addr.CalculateSymbolContextLineEntry (line_entry))
+ return line_entry;
+ }
+ return LineEntry();
+ }
+ }
+
+ if (function)
+ {
+ if (function->GetAddressRange().GetBaseAddress().CalculateSymbolContextLineEntry(line_entry))
+ return line_entry;
+ }
+ return LineEntry();
+}
+
//----------------------------------------------------------------------
//
// SymbolContextSpecifier
@@ -1043,7 +1070,7 @@ SymbolContextList::Dump(Stream *s, Targe
}
bool
-SymbolContextList::GetContextAtIndex(uint32_t idx, SymbolContext& sc) const
+SymbolContextList::GetContextAtIndex(size_t idx, SymbolContext& sc) const
{
if (idx < m_symbol_contexts.size())
{
@@ -1054,7 +1081,18 @@ SymbolContextList::GetContextAtIndex(uin
}
bool
-SymbolContextList::RemoveContextAtIndex (uint32_t idx)
+SymbolContextList::GetLastContext(SymbolContext& sc) const
+{
+ if (!m_symbol_contexts.empty())
+ {
+ sc = m_symbol_contexts.back();
+ return true;
+ }
+ return false;
+}
+
+bool
+SymbolContextList::RemoveContextAtIndex (size_t idx)
{
if (idx < m_symbol_contexts.size())
{
@@ -1074,8 +1112,8 @@ uint32_t
SymbolContextList::NumLineEntriesWithLine (uint32_t line) const
{
uint32_t match_count = 0;
- const uint32_t size = m_symbol_contexts.size();
- for (uint32_t idx = 0; idx<size; ++idx)
+ const size_t size = m_symbol_contexts.size();
+ for (size_t idx = 0; idx<size; ++idx)
{
if (m_symbol_contexts[idx].line_entry.line == line)
++match_count;
@@ -1088,8 +1126,8 @@ SymbolContextList::GetDescription(Stream
lldb::DescriptionLevel level,
Target *target) const
{
- const uint32_t size = m_symbol_contexts.size();
- for (uint32_t idx = 0; idx<size; ++idx)
+ const size_t size = m_symbol_contexts.size();
+ for (size_t idx = 0; idx<size; ++idx)
m_symbol_contexts[idx].GetDescription (s, level, target);
}
Modified: lldb/branches/lldb-platform-work/source/Symbol/SymbolFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/SymbolFile.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/SymbolFile.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/SymbolFile.cpp Thu Jun 6 19:06:43 2013
@@ -21,7 +21,7 @@ using namespace lldb_private;
SymbolFile*
SymbolFile::FindPlugin (ObjectFile* obj_file)
{
- std::auto_ptr<SymbolFile> best_symfile_ap;
+ std::unique_ptr<SymbolFile> best_symfile_ap;
if (obj_file != NULL)
{
// TODO: Load any plug-ins in the appropriate plug-in search paths and
@@ -32,7 +32,7 @@ SymbolFile::FindPlugin (ObjectFile* obj_
SymbolFileCreateInstance create_callback;
for (uint32_t idx = 0; (create_callback = PluginManager::GetSymbolFileCreateCallbackAtIndex(idx)) != NULL; ++idx)
{
- std::auto_ptr<SymbolFile> curr_symfile_ap(create_callback(obj_file));
+ std::unique_ptr<SymbolFile> curr_symfile_ap(create_callback(obj_file));
if (curr_symfile_ap.get())
{
@@ -40,7 +40,7 @@ SymbolFile::FindPlugin (ObjectFile* obj_
if (sym_file_abilities > best_symfile_abilities)
{
best_symfile_abilities = sym_file_abilities;
- best_symfile_ap = curr_symfile_ap;
+ best_symfile_ap.reset (curr_symfile_ap.release());
// If any symbol file parser has all of the abilities, then
// we should just stop looking.
if ((kAllAbilities & sym_file_abilities) == kAllAbilities)
Modified: lldb/branches/lldb-platform-work/source/Symbol/SymbolVendor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/SymbolVendor.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/SymbolVendor.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/SymbolVendor.cpp Thu Jun 6 19:06:43 2013
@@ -15,6 +15,8 @@
// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
@@ -30,16 +32,16 @@ using namespace lldb_private;
// also allow for finding separate debug information files.
//----------------------------------------------------------------------
SymbolVendor*
-SymbolVendor::FindPlugin (const lldb::ModuleSP &module_sp)
+SymbolVendor::FindPlugin (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm)
{
- std::auto_ptr<SymbolVendor> instance_ap;
+ std::unique_ptr<SymbolVendor> instance_ap;
//----------------------------------------------------------------------
// We currently only have one debug symbol parser...
//----------------------------------------------------------------------
SymbolVendorCreateInstance create_callback;
- for (uint32_t idx = 0; (create_callback = PluginManager::GetSymbolVendorCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ for (size_t idx = 0; (create_callback = PluginManager::GetSymbolVendorCreateCallbackAtIndex(idx)) != NULL; ++idx)
{
- instance_ap.reset(create_callback(module_sp));
+ instance_ap.reset(create_callback(module_sp, feedback_strm));
if (instance_ap.get())
{
@@ -100,13 +102,13 @@ SymbolVendor::AddSymbolFileRepresentatio
}
bool
-SymbolVendor::SetCompileUnitAtIndex (uint32_t idx, const CompUnitSP &cu_sp)
+SymbolVendor::SetCompileUnitAtIndex (size_t idx, const CompUnitSP &cu_sp)
{
ModuleSP module_sp(GetModule());
if (module_sp)
{
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
- const uint32_t num_compile_units = GetNumCompileUnits();
+ const size_t num_compile_units = GetNumCompileUnits();
if (idx < num_compile_units)
{
// Fire off an assertion if this compile unit already exists for now.
@@ -128,7 +130,7 @@ SymbolVendor::SetCompileUnitAtIndex (uin
return false;
}
-uint32_t
+size_t
SymbolVendor::GetNumCompileUnits()
{
ModuleSP module_sp(GetModule());
@@ -150,6 +152,20 @@ SymbolVendor::GetNumCompileUnits()
return m_compile_units.size();
}
+lldb::LanguageType
+SymbolVendor::ParseCompileUnitLanguage (const SymbolContext& sc)
+{
+ ModuleSP module_sp(GetModule());
+ if (module_sp)
+ {
+ lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ if (m_sym_file_ap.get())
+ return m_sym_file_ap->ParseCompileUnitLanguage(sc);
+ }
+ return eLanguageTypeUnknown;
+}
+
+
size_t
SymbolVendor::ParseCompileUnitFunctions (const SymbolContext &sc)
{
@@ -268,8 +284,8 @@ SymbolVendor::ResolveSymbolContext (cons
return 0;
}
-uint32_t
-SymbolVendor::FindGlobalVariables (const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
+size_t
+SymbolVendor::FindGlobalVariables (const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, size_t max_matches, VariableList& variables)
{
ModuleSP module_sp(GetModule());
if (module_sp)
@@ -281,8 +297,8 @@ SymbolVendor::FindGlobalVariables (const
return 0;
}
-uint32_t
-SymbolVendor::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
+size_t
+SymbolVendor::FindGlobalVariables (const RegularExpression& regex, bool append, size_t max_matches, VariableList& variables)
{
ModuleSP module_sp(GetModule());
if (module_sp)
@@ -294,7 +310,7 @@ SymbolVendor::FindGlobalVariables (const
return 0;
}
-uint32_t
+size_t
SymbolVendor::FindFunctions(const ConstString &name, const ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list)
{
ModuleSP module_sp(GetModule());
@@ -307,7 +323,7 @@ SymbolVendor::FindFunctions(const ConstS
return 0;
}
-uint32_t
+size_t
SymbolVendor::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
{
ModuleSP module_sp(GetModule());
@@ -321,8 +337,8 @@ SymbolVendor::FindFunctions(const Regula
}
-uint32_t
-SymbolVendor::FindTypes (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types)
+size_t
+SymbolVendor::FindTypes (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, size_t max_matches, TypeList& types)
{
ModuleSP module_sp(GetModule());
if (module_sp)
@@ -393,13 +409,13 @@ SymbolVendor::Dump(Stream *s)
}
CompUnitSP
-SymbolVendor::GetCompileUnitAtIndex(uint32_t idx)
+SymbolVendor::GetCompileUnitAtIndex(size_t idx)
{
CompUnitSP cu_sp;
ModuleSP module_sp(GetModule());
if (module_sp)
{
- const uint32_t num_compile_units = GetNumCompileUnits();
+ const size_t num_compile_units = GetNumCompileUnits();
if (idx < num_compile_units)
{
cu_sp = m_compile_units[idx];
@@ -417,16 +433,11 @@ SymbolVendor::GetCompileUnitAtIndex(uint
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-const char *
+lldb_private::ConstString
SymbolVendor::GetPluginName()
{
- return "SymbolVendor";
-}
-
-const char *
-SymbolVendor::GetShortPluginName()
-{
- return "vendor-default";
+ static ConstString g_name("vendor-default");
+ return g_name;
}
uint32_t
Modified: lldb/branches/lldb-platform-work/source/Symbol/Symtab.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/Symtab.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/Symtab.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/Symtab.cpp Thu Jun 6 19:06:43 2013
@@ -11,9 +11,12 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/Section.h"
#include "lldb/Core/Timer.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Symtab.h"
+#include "lldb/Target/CPPLanguageRuntime.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
using namespace lldb;
@@ -37,7 +40,7 @@ Symtab::~Symtab()
}
void
-Symtab::Reserve(uint32_t count)
+Symtab::Reserve(size_t count)
{
// Clients should grab the mutex from this symbol table and lock it manually
// when calling this function to avoid performance issues.
@@ -45,7 +48,7 @@ Symtab::Reserve(uint32_t count)
}
Symbol *
-Symtab::Resize(uint32_t count)
+Symtab::Resize(size_t count)
{
// Clients should grab the mutex from this symbol table and lock it manually
// when calling this function to avoid performance issues.
@@ -87,9 +90,8 @@ Symtab::Dump (Stream *s, Target *target,
object_name = m_objfile->GetModule()->GetObjectName().GetCString();
if (file_spec)
- s->Printf("Symtab, file = %s/%s%s%s%s, num_symbols = %lu",
- file_spec.GetDirectory().AsCString(),
- file_spec.GetFilename().AsCString(),
+ s->Printf("Symtab, file = %s%s%s%s, num_symbols = %lu",
+ file_spec.GetPath().c_str(),
object_name ? "(" : "",
object_name ? object_name : "",
object_name ? ")" : "",
@@ -149,7 +151,7 @@ Symtab::Dump (Stream *s, Target *target,
std::vector<uint32_t>::const_iterator end = m_addr_indexes.end();
for (pos = m_addr_indexes.begin(); pos != end; ++pos)
{
- uint32_t idx = *pos;
+ size_t idx = *pos;
if (idx < num_symbols)
{
s->Indent();
@@ -179,7 +181,7 @@ Symtab::Dump(Stream *s, Target *target,
DumpSymbolHeader (s);
for (pos = indexes.begin(); pos != end; ++pos)
{
- uint32_t idx = *pos;
+ size_t idx = *pos;
if (idx < num_symbols)
{
s->Indent();
@@ -229,7 +231,7 @@ Symtab::FindSymbolByID (lldb::user_id_t
Symbol *
-Symtab::SymbolAtIndex(uint32_t idx)
+Symtab::SymbolAtIndex(size_t idx)
{
// Clients should grab the mutex from this symbol table and lock it manually
// when calling this function to avoid performance issues.
@@ -240,7 +242,7 @@ Symtab::SymbolAtIndex(uint32_t idx)
const Symbol *
-Symtab::SymbolAtIndex(uint32_t idx) const
+Symtab::SymbolAtIndex(size_t idx) const
{
// Clients should grab the mutex from this symbol table and lock it manually
// when calling this function to avoid performance issues.
@@ -261,9 +263,9 @@ Symtab::InitNameIndexes()
m_name_indexes_computed = true;
Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
// Create the name index vector to be able to quickly search by name
- const size_t count = m_symbols.size();
+ const size_t num_symbols = m_symbols.size();
#if 1
- m_name_to_index.Reserve (count);
+ m_name_to_index.Reserve (num_symbols);
#else
// TODO: benchmark this to see if we save any memory. Otherwise we
// will always keep the memory reserved in the vector unless we pull
@@ -286,7 +288,12 @@ Symtab::InitNameIndexes()
NameToIndexMap::Entry entry;
- for (entry.value = 0; entry.value < count; ++entry.value)
+ // The "const char *" in "class_contexts" must come from a ConstString::GetCString()
+ std::set<const char *> class_contexts;
+ UniqueCStringMap<uint32_t> mangled_name_to_index;
+ std::vector<const char *> symbol_contexts(num_symbols, NULL);
+
+ for (entry.value = 0; entry.value<num_symbols; ++entry.value)
{
const Symbol *symbol = &m_symbols[entry.value];
@@ -301,33 +308,145 @@ Symtab::InitNameIndexes()
const Mangled &mangled = symbol->GetMangled();
entry.cstring = mangled.GetMangledName().GetCString();
if (entry.cstring && entry.cstring[0])
+ {
m_name_to_index.Append (entry);
-
+
+ const SymbolType symbol_type = symbol->GetType();
+ if (symbol_type == eSymbolTypeCode || symbol_type == eSymbolTypeResolver)
+ {
+ if (entry.cstring[0] == '_' && entry.cstring[1] == 'Z' &&
+ (entry.cstring[2] != 'T' && // avoid virtual table, VTT structure, typeinfo structure, and typeinfo name
+ entry.cstring[2] != 'G' && // avoid guard variables
+ entry.cstring[2] != 'Z')) // named local entities (if we eventually handle eSymbolTypeData, we will want this back)
+ {
+ CPPLanguageRuntime::MethodName cxx_method (mangled.GetDemangledName());
+ entry.cstring = ConstString(cxx_method.GetBasename()).GetCString();
+ if (entry.cstring && entry.cstring[0])
+ {
+ // ConstString objects permanently store the string in the pool so calling
+ // GetCString() on the value gets us a const char * that will never go away
+ const char *const_context = ConstString(cxx_method.GetContext()).GetCString();
+
+ if (entry.cstring[0] == '~' || !cxx_method.GetQualifiers().empty())
+ {
+ // The first character of the demangled basename is '~' which
+ // means we have a class destructor. We can use this information
+ // to help us know what is a class and what isn't.
+ if (class_contexts.find(const_context) == class_contexts.end())
+ class_contexts.insert(const_context);
+ m_method_to_index.Append (entry);
+ }
+ else
+ {
+ if (const_context && const_context[0])
+ {
+ if (class_contexts.find(const_context) != class_contexts.end())
+ {
+ // The current decl context is in our "class_contexts" which means
+ // this is a method on a class
+ m_method_to_index.Append (entry);
+ }
+ else
+ {
+ // We don't know if this is a function basename or a method,
+ // so put it into a temporary collection so once we are done
+ // we can look in class_contexts to see if each entry is a class
+ // or just a function and will put any remaining items into
+ // m_method_to_index or m_basename_to_index as needed
+ mangled_name_to_index.Append (entry);
+ symbol_contexts[entry.value] = const_context;
+ }
+ }
+ else
+ {
+ // No context for this function so this has to be a basename
+ m_basename_to_index.Append(entry);
+ }
+ }
+ }
+ }
+ }
+ }
+
entry.cstring = mangled.GetDemangledName().GetCString();
if (entry.cstring && entry.cstring[0])
m_name_to_index.Append (entry);
// If the demangled name turns out to be an ObjC name, and
// is a category name, add the version without categories to the index too.
- ConstString objc_base_name;
- if (ObjCLanguageRuntime::ParseMethodName (entry.cstring,
- NULL,
- NULL,
- &objc_base_name,
- NULL))
+ ObjCLanguageRuntime::MethodName objc_method (entry.cstring, true);
+ if (objc_method.IsValid(true))
{
- entry.cstring = objc_base_name.GetCString();
- m_name_to_index.Append (entry);
+ entry.cstring = objc_method.GetSelector().GetCString();
+ m_selector_to_index.Append (entry);
+
+ ConstString objc_method_no_category (objc_method.GetFullNameWithoutCategory(true));
+ if (objc_method_no_category)
+ {
+ entry.cstring = objc_method_no_category.GetCString();
+ m_name_to_index.Append (entry);
+ }
}
}
+
+ size_t count;
+ if (!mangled_name_to_index.IsEmpty())
+ {
+ count = mangled_name_to_index.GetSize();
+ for (size_t i=0; i<count; ++i)
+ {
+ if (mangled_name_to_index.GetValueAtIndex(i, entry.value))
+ {
+ entry.cstring = mangled_name_to_index.GetCStringAtIndex(i);
+ if (symbol_contexts[entry.value] && class_contexts.find(symbol_contexts[entry.value]) != class_contexts.end())
+ {
+ m_method_to_index.Append (entry);
+ }
+ else
+ {
+ // If we got here, we have something that had a context (was inside a namespace or class)
+ // yet we don't know if the entry
+ m_method_to_index.Append (entry);
+ m_basename_to_index.Append (entry);
+ }
+ }
+ }
+ }
m_name_to_index.Sort();
m_name_to_index.SizeToFit();
+ m_selector_to_index.Sort();
+ m_selector_to_index.SizeToFit();
+ m_basename_to_index.Sort();
+ m_basename_to_index.SizeToFit();
+ m_method_to_index.Sort();
+ m_method_to_index.SizeToFit();
+
+// static StreamFile a ("/tmp/a.txt");
+//
+// count = m_basename_to_index.GetSize();
+// if (count)
+// {
+// for (size_t i=0; i<count; ++i)
+// {
+// if (m_basename_to_index.GetValueAtIndex(i, entry.value))
+// a.Printf ("%s BASENAME\n", m_symbols[entry.value].GetMangled().GetName().GetCString());
+// }
+// }
+// count = m_method_to_index.GetSize();
+// if (count)
+// {
+// for (size_t i=0; i<count; ++i)
+// {
+// if (m_method_to_index.GetValueAtIndex(i, entry.value))
+// a.Printf ("%s METHOD\n", m_symbols[entry.value].GetMangled().GetName().GetCString());
+// }
+// }
}
}
void
-Symtab::AppendSymbolNamesToMap (const IndexCollection &indexes,
+Symtab::AppendSymbolNamesToMap (const IndexCollection &indexes,
bool add_demangled,
bool add_mangled,
NameToIndexMap &name_to_index_map) const
@@ -651,7 +770,7 @@ Symtab::FindSymbolWithType (SymbolType s
Mutex::Locker locker (m_mutex);
const size_t count = m_symbols.size();
- for (uint32_t idx = start_idx; idx < count; ++idx)
+ for (size_t idx = start_idx; idx < count; ++idx)
{
if (symbol_type == eSymbolTypeAny || m_symbols[idx].GetType() == symbol_type)
{
@@ -827,14 +946,7 @@ Symtab::InitAddressIndexes()
if (!m_addr_indexes_computed && !m_symbols.empty())
{
m_addr_indexes_computed = true;
-#if 0
- // The old was to add only code, trampoline or data symbols...
- AppendSymbolIndexesWithType (eSymbolTypeCode, m_addr_indexes);
- AppendSymbolIndexesWithType (eSymbolTypeTrampoline, m_addr_indexes);
- AppendSymbolIndexesWithType (eSymbolTypeData, m_addr_indexes);
-#else
- // The new way adds all symbols with valid addresses that are section
- // offset.
+
const_iterator begin = m_symbols.begin();
const_iterator end = m_symbols.end();
for (const_iterator pos = m_symbols.begin(); pos != end; ++pos)
@@ -842,7 +954,7 @@ Symtab::InitAddressIndexes()
if (pos->ValueIsAddress())
m_addr_indexes.push_back (std::distance(begin, pos));
}
-#endif
+
SortSymbolIndexesByValue (m_addr_indexes, false);
m_addr_indexes.push_back (UINT32_MAX); // Terminator for bsearch since we might need to look at the next symbol
}
@@ -876,13 +988,13 @@ Symtab::CalculateSymbolSize (Symbol *sym
if (!m_addr_indexes_computed)
InitAddressIndexes();
const size_t num_addr_indexes = m_addr_indexes.size();
+ const lldb::addr_t symbol_file_addr = symbol->GetAddress().GetFileAddress();
SymbolSearchInfo info = FindIndexPtrForSymbolContainingAddress (this,
- symbol->GetAddress().GetFileAddress(),
+ symbol_file_addr,
&m_addr_indexes.front(),
num_addr_indexes);
if (info.match_index_ptr != NULL)
{
- const lldb::addr_t curr_file_addr = symbol->GetAddress().GetFileAddress();
// We can figure out the address range of all symbols except the
// last one by taking the delta between the current symbol and
// the next symbol
@@ -893,15 +1005,32 @@ Symtab::CalculateSymbolSize (Symbol *sym
{
Symbol *next_symbol = SymbolAtIndex(m_addr_indexes[addr_index]);
if (next_symbol == NULL)
- break;
-
- const lldb::addr_t next_file_addr = next_symbol->GetAddress().GetFileAddress();
- if (next_file_addr > curr_file_addr)
{
- byte_size = next_file_addr - curr_file_addr;
- symbol->SetByteSize(byte_size);
- symbol->SetSizeIsSynthesized(true);
- break;
+ // No next symbol take the size to be the remaining bytes in the section
+ // in which the symbol resides
+ SectionSP section_sp (m_objfile->GetSectionList()->FindSectionContainingFileAddress (symbol_file_addr));
+ if (section_sp)
+ {
+ const lldb::addr_t end_section_file_addr = section_sp->GetFileAddress() + section_sp->GetByteSize();
+ if (end_section_file_addr > symbol_file_addr)
+ {
+ byte_size = end_section_file_addr - symbol_file_addr;
+ symbol->SetByteSize(byte_size);
+ symbol->SetSizeIsSynthesized(true);
+ break;
+ }
+ }
+ }
+ else
+ {
+ const lldb::addr_t next_file_addr = next_symbol->GetAddress().GetFileAddress();
+ if (next_file_addr > symbol_file_addr)
+ {
+ byte_size = next_file_addr - symbol_file_addr;
+ symbol->SetByteSize(byte_size);
+ symbol->SetSizeIsSynthesized(true);
+ break;
+ }
}
}
}
@@ -910,27 +1039,6 @@ Symtab::CalculateSymbolSize (Symbol *sym
}
Symbol *
-Symtab::FindSymbolWithFileAddress (addr_t file_addr)
-{
- Mutex::Locker locker (m_mutex);
-
- if (!m_addr_indexes_computed)
- InitAddressIndexes();
-
- SymbolSearchInfo info = { this, file_addr, NULL, NULL, 0 };
-
- uint32_t* match = (uint32_t*)::bsearch (&info,
- &m_addr_indexes[0],
- m_addr_indexes.size(),
- sizeof(uint32_t),
- (ComparisonFunction)SymbolWithFileAddress);
- if (match)
- return SymbolAtIndex (*match);
- return NULL;
-}
-
-
-Symbol *
Symtab::FindSymbolContainingFileAddress (addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes)
{
Mutex::Locker locker (m_mutex);
@@ -979,3 +1087,131 @@ Symtab::FindSymbolContainingFileAddress
return FindSymbolContainingFileAddress (file_addr, &m_addr_indexes[0], m_addr_indexes.size());
}
+void
+Symtab::SymbolIndicesToSymbolContextList (std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list)
+{
+ // No need to protect this call using m_mutex all other method calls are
+ // already thread safe.
+
+ const bool merge_symbol_into_function = true;
+ size_t num_indices = symbol_indexes.size();
+ if (num_indices > 0)
+ {
+ SymbolContext sc;
+ sc.module_sp = m_objfile->GetModule();
+ for (size_t i = 0; i < num_indices; i++)
+ {
+ sc.symbol = SymbolAtIndex (symbol_indexes[i]);
+ if (sc.symbol)
+ sc_list.AppendIfUnique(sc, merge_symbol_into_function);
+ }
+ }
+}
+
+
+size_t
+Symtab::FindFunctionSymbols (const ConstString &name,
+ uint32_t name_type_mask,
+ SymbolContextList& sc_list)
+{
+ size_t count = 0;
+ std::vector<uint32_t> symbol_indexes;
+
+ const char *name_cstr = name.GetCString();
+
+ // eFunctionNameTypeAuto should be pre-resolved by a call to Module::PrepareForFunctionNameLookup()
+ assert ((name_type_mask & eFunctionNameTypeAuto) == 0);
+
+ if (name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull))
+ {
+ std::vector<uint32_t> temp_symbol_indexes;
+ FindAllSymbolsWithNameAndType (name, eSymbolTypeAny, temp_symbol_indexes);
+
+ unsigned temp_symbol_indexes_size = temp_symbol_indexes.size();
+ if (temp_symbol_indexes_size > 0)
+ {
+ Mutex::Locker locker (m_mutex);
+ for (unsigned i = 0; i < temp_symbol_indexes_size; i++)
+ {
+ SymbolContext sym_ctx;
+ sym_ctx.symbol = SymbolAtIndex (temp_symbol_indexes[i]);
+ if (sym_ctx.symbol)
+ {
+ switch (sym_ctx.symbol->GetType())
+ {
+ case eSymbolTypeCode:
+ case eSymbolTypeResolver:
+ symbol_indexes.push_back(temp_symbol_indexes[i]);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (name_type_mask & eFunctionNameTypeBase)
+ {
+ // From mangled names we can't tell what is a basename and what
+ // is a method name, so we just treat them the same
+ if (!m_name_indexes_computed)
+ InitNameIndexes();
+
+ if (!m_basename_to_index.IsEmpty())
+ {
+ const UniqueCStringMap<uint32_t>::Entry *match;
+ for (match = m_basename_to_index.FindFirstValueForName(name_cstr);
+ match != NULL;
+ match = m_basename_to_index.FindNextValueForName(match))
+ {
+ symbol_indexes.push_back(match->value);
+ }
+ }
+ }
+
+ if (name_type_mask & eFunctionNameTypeMethod)
+ {
+ if (!m_name_indexes_computed)
+ InitNameIndexes();
+
+ if (!m_method_to_index.IsEmpty())
+ {
+ const UniqueCStringMap<uint32_t>::Entry *match;
+ for (match = m_method_to_index.FindFirstValueForName(name_cstr);
+ match != NULL;
+ match = m_method_to_index.FindNextValueForName(match))
+ {
+ symbol_indexes.push_back(match->value);
+ }
+ }
+ }
+
+ if (name_type_mask & eFunctionNameTypeSelector)
+ {
+ if (!m_name_indexes_computed)
+ InitNameIndexes();
+
+ if (!m_selector_to_index.IsEmpty())
+ {
+ const UniqueCStringMap<uint32_t>::Entry *match;
+ for (match = m_selector_to_index.FindFirstValueForName(name_cstr);
+ match != NULL;
+ match = m_selector_to_index.FindNextValueForName(match))
+ {
+ symbol_indexes.push_back(match->value);
+ }
+ }
+ }
+
+ if (!symbol_indexes.empty())
+ {
+ std::sort(symbol_indexes.begin(), symbol_indexes.end());
+ symbol_indexes.erase(std::unique(symbol_indexes.begin(), symbol_indexes.end()), symbol_indexes.end());
+ count = symbol_indexes.size();
+ SymbolIndicesToSymbolContextList (symbol_indexes, sc_list);
+ }
+
+ return count;
+}
+
Modified: lldb/branches/lldb-platform-work/source/Symbol/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/Type.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/Type.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/Type.cpp Thu Jun 6 19:06:43 2013
@@ -28,6 +28,8 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "llvm/ADT/StringRef.h"
+
using namespace lldb;
using namespace lldb_private;
@@ -49,7 +51,7 @@ Type::Type
lldb::user_id_t uid,
SymbolFile* symbol_file,
const ConstString &name,
- uint32_t byte_size,
+ uint64_t byte_size,
SymbolContextScope *context,
user_id_t encoding_uid,
EncodingDataType encoding_uid_type,
@@ -57,6 +59,7 @@ Type::Type
clang_type_t clang_type,
ResolveState clang_type_resolve_state
) :
+ std::enable_shared_from_this<Type> (),
UserID (uid),
m_name (name),
m_symbol_file (symbol_file),
@@ -73,12 +76,13 @@ Type::Type
}
Type::Type () :
+ std::enable_shared_from_this<Type> (),
UserID (0),
m_name ("<INVALID TYPE>"),
m_symbol_file (NULL),
m_context (NULL),
m_encoding_type (NULL),
- m_encoding_uid (0),
+ m_encoding_uid (LLDB_INVALID_UID),
m_encoding_uid_type (eEncodingInvalid),
m_byte_size (0),
m_decl (),
@@ -90,6 +94,7 @@ Type::Type () :
Type::Type (const Type &rhs) :
+ std::enable_shared_from_this<Type> (rhs),
UserID (rhs),
m_name (rhs.m_name),
m_symbol_file (rhs.m_symbol_file),
@@ -136,7 +141,7 @@ Type::GetDescription (Stream *s, lldb::D
// Call the get byte size accesor so we resolve our byte size
if (GetByteSize())
- s->Printf(", byte-size = %u", m_byte_size);
+ s->Printf(", byte-size = %" PRIu64, m_byte_size);
bool show_fullpaths = (level == lldb::eDescriptionLevelVerbose);
m_decl.Dump(s, show_fullpaths);
@@ -148,7 +153,7 @@ Type::GetDescription (Stream *s, lldb::D
}
else if (m_encoding_uid != LLDB_INVALID_UID)
{
- s->Printf(", type_uid = 0x%8.8x", m_encoding_uid);
+ s->Printf(", type_uid = 0x%8.8" PRIx64, m_encoding_uid);
switch (m_encoding_uid_type)
{
case eEncodingInvalid: break;
@@ -176,7 +181,7 @@ Type::Dump (Stream *s, bool show_context
*s << ", name = \"" << m_name << "\"";
if (m_byte_size != 0)
- s->Printf(", size = %u", m_byte_size);
+ s->Printf(", size = %" PRIu64, m_byte_size);
if (show_context && m_context != NULL)
{
@@ -255,7 +260,7 @@ Type::DumpValue
{
s->PutChar('(');
if (verbose)
- s->Printf("Type{0x%8.8llx} ", GetID());
+ s->Printf("Type{0x%8.8" PRIx64 "} ", GetID());
DumpTypeName (s);
s->PutCString(") ");
}
@@ -287,7 +292,7 @@ Type::GetEncodingType ()
-uint32_t
+uint64_t
Type::GetByteSize()
{
if (m_byte_size == 0)
@@ -373,7 +378,7 @@ Type::GetFormat ()
lldb::Encoding
-Type::GetEncoding (uint32_t &count)
+Type::GetEncoding (uint64_t &count)
{
// Make sure we resolve our type if it already hasn't been.
if (!ResolveClangType(eResolveStateForward))
@@ -424,7 +429,7 @@ Type::ReadFromMemory (ExecutionContext *
return false;
}
- const uint32_t byte_size = GetByteSize();
+ const uint64_t byte_size = GetByteSize();
if (data.GetByteSize() < byte_size)
{
lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0'));
@@ -437,6 +442,8 @@ Type::ReadFromMemory (ExecutionContext *
if (address_type == eAddressTypeHost)
{
// The address is an address in this process, so just copy it
+ if (addr == 0)
+ return false;
memcpy (dst, (uint8_t*)NULL + addr, byte_size);
return true;
}
@@ -728,14 +735,43 @@ Type::GetQualifiedName ()
bool
-Type::GetTypeScopeAndBasename (const char* name_cstr,
+Type::GetTypeScopeAndBasename (const char* &name_cstr,
std::string &scope,
- std::string &basename)
+ std::string &basename,
+ TypeClass &type_class)
{
// Protect against null c string.
+ type_class = eTypeClassAny;
+
if (name_cstr && name_cstr[0])
{
+ llvm::StringRef name_strref(name_cstr);
+ if (name_strref.startswith("struct "))
+ {
+ name_cstr += 7;
+ type_class = eTypeClassStruct;
+ }
+ else if (name_strref.startswith("class "))
+ {
+ name_cstr += 6;
+ type_class = eTypeClassClass;
+ }
+ else if (name_strref.startswith("union "))
+ {
+ name_cstr += 6;
+ type_class = eTypeClassUnion;
+ }
+ else if (name_strref.startswith("enum "))
+ {
+ name_cstr += 5;
+ type_class = eTypeClassEnumeration;
+ }
+ else if (name_strref.startswith("typedef "))
+ {
+ name_cstr += 8;
+ type_class = eTypeClassTypedef;
+ }
const char *basename_cstr = name_cstr;
const char* namespace_separator = ::strstr (basename_cstr, "::");
if (namespace_separator)
@@ -797,6 +833,26 @@ TypeAndOrName::operator= (const TypeAndO
return *this;
}
+bool
+TypeAndOrName::operator==(const TypeAndOrName &other) const
+{
+ if (m_type_sp != other.m_type_sp)
+ return false;
+ if (m_type_name != other.m_type_name)
+ return false;
+ return true;
+}
+
+bool
+TypeAndOrName::operator!=(const TypeAndOrName &other) const
+{
+ if (m_type_sp != other.m_type_sp)
+ return true;
+ if (m_type_name != other.m_type_name)
+ return true;
+ return false;
+}
+
ConstString
TypeAndOrName::GetName () const
{
@@ -807,15 +863,15 @@ TypeAndOrName::GetName () const
}
void
-TypeAndOrName::SetName (ConstString &type_name_const_str)
+TypeAndOrName::SetName (const ConstString &type_name)
{
- m_type_name = type_name_const_str;
+ m_type_name = type_name;
}
void
-TypeAndOrName::SetName (const char *type_name_str)
+TypeAndOrName::SetName (const char *type_name_cstr)
{
- m_type_name.SetCString (type_name_str);
+ m_type_name.SetCString (type_name_cstr);
}
void
@@ -835,6 +891,25 @@ TypeAndOrName::IsEmpty()
return true;
}
+void
+TypeAndOrName::Clear ()
+{
+ m_type_name.Clear();
+ m_type_sp.reset();
+}
+
+bool
+TypeAndOrName::HasName ()
+{
+ return (bool)m_type_name;
+}
+
+bool
+TypeAndOrName::HasTypeSP ()
+{
+ return m_type_sp.get() != NULL;
+}
+
TypeImpl::TypeImpl(const lldb_private::ClangASTType& clang_ast_type) :
m_clang_ast_type(clang_ast_type.GetASTContext(), clang_ast_type.GetOpaqueQualType()),
m_type_sp()
Modified: lldb/branches/lldb-platform-work/source/Symbol/TypeHierarchyNavigator.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/TypeHierarchyNavigator.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/TypeHierarchyNavigator.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/TypeHierarchyNavigator.cpp Thu Jun 6 19:06:43 2013
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/AST/ASTContext.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/ClangASTContext.h"
Modified: lldb/branches/lldb-platform-work/source/Symbol/TypeList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/TypeList.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/TypeList.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/TypeList.cpp Thu Jun 6 19:06:43 2013
@@ -207,17 +207,19 @@ TypeList::RemoveMismatchedTypes (const c
{
std::string type_scope;
std::string type_basename;
- if (!Type::GetTypeScopeAndBasename (qualified_typename, type_scope, type_basename))
+ TypeClass type_class = eTypeClassAny;
+ if (!Type::GetTypeScopeAndBasename (qualified_typename, type_scope, type_basename, type_class))
{
type_basename = qualified_typename;
type_scope.clear();
}
- return RemoveMismatchedTypes (type_scope, type_basename, exact_match);
+ return RemoveMismatchedTypes (type_scope, type_basename, type_class, exact_match);
}
void
TypeList::RemoveMismatchedTypes (const std::string &type_scope,
const std::string &type_basename,
+ TypeClass type_class,
bool exact_match)
{
// Our "collection" type currently is a std::map which doesn't
@@ -232,6 +234,15 @@ TypeList::RemoveMismatchedTypes (const s
{
Type* the_type = pos->second.get();
bool keep_match = false;
+ TypeClass match_type_class = eTypeClassAny;
+
+ if (type_class != eTypeClassAny)
+ {
+ match_type_class = ClangASTType::GetTypeClass (the_type->GetClangAST(),
+ the_type->GetClangForwardType());
+ if ((match_type_class & type_class) == 0)
+ continue;
+ }
ConstString match_type_name_const_str (the_type->GetQualifiedName());
if (match_type_name_const_str)
@@ -241,7 +252,8 @@ TypeList::RemoveMismatchedTypes (const s
std::string match_type_basename;
if (Type::GetTypeScopeAndBasename (match_type_name,
match_type_scope,
- match_type_basename))
+ match_type_basename,
+ match_type_class))
{
if (match_type_basename == type_basename)
{
@@ -298,6 +310,31 @@ TypeList::RemoveMismatchedTypes (const s
}
m_types.swap(matching_types);
}
+
+void
+TypeList::RemoveMismatchedTypes (TypeClass type_class)
+{
+ if (type_class == eTypeClassAny)
+ return;
+
+ // Our "collection" type currently is a std::map which doesn't
+ // have any good way to iterate and remove items from the map
+ // so we currently just make a new list and add all of the matching
+ // types to it, and then swap it into m_types at the end
+ collection matching_types;
+
+ iterator pos, end = m_types.end();
+
+ for (pos = m_types.begin(); pos != end; ++pos)
+ {
+ Type* the_type = pos->second.get();
+ TypeClass match_type_class = ClangASTType::GetTypeClass (the_type->GetClangAST(),
+ the_type->GetClangForwardType());
+ if (match_type_class & type_class)
+ matching_types.insert (*pos);
+ }
+ m_types.swap(matching_types);
+}
//void *
//TypeList::CreateClangPointerType (Type *type)
Modified: lldb/branches/lldb-platform-work/source/Symbol/UnwindPlan.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/UnwindPlan.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/UnwindPlan.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/UnwindPlan.cpp Thu Jun 6 19:06:43 2013
@@ -153,7 +153,7 @@ void
UnwindPlan::Row::Clear ()
{
m_offset = 0;
- m_cfa_reg_num = 0;
+ m_cfa_reg_num = LLDB_INVALID_REGNUM;
m_cfa_offset = 0;
m_register_locations.clear();
}
@@ -164,9 +164,9 @@ UnwindPlan::Row::Dump (Stream& s, const
const RegisterInfo *reg_info = unwind_plan->GetRegisterInfo (thread, GetCFARegister());
if (base_addr != LLDB_INVALID_ADDRESS)
- s.Printf ("0x%16.16llx: CFA=", base_addr + GetOffset());
+ s.Printf ("0x%16.16" PRIx64 ": CFA=", base_addr + GetOffset());
else
- s.Printf ("0x%8.8llx: CFA=", GetOffset());
+ s.Printf ("0x%8.8" PRIx64 ": CFA=", GetOffset());
if (reg_info)
s.Printf ("%s", reg_info->name);
@@ -189,7 +189,7 @@ UnwindPlan::Row::Dump (Stream& s, const
UnwindPlan::Row::Row() :
m_offset(0),
- m_cfa_reg_num(0),
+ m_cfa_reg_num(LLDB_INVALID_REGNUM),
m_cfa_offset(0),
m_register_locations()
{
Modified: lldb/branches/lldb-platform-work/source/Symbol/UnwindTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/UnwindTable.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/UnwindTable.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/UnwindTable.cpp Thu Jun 6 19:06:43 2013
@@ -135,12 +135,12 @@ UnwindTable::GetUncachedFuncUnwindersCon
void
UnwindTable::Dump (Stream &s)
{
- s.Printf("UnwindTable for %s/%s:\n", m_object_file.GetFileSpec().GetDirectory().GetCString(), m_object_file.GetFileSpec().GetFilename().GetCString());
+ s.Printf("UnwindTable for '%s':\n", m_object_file.GetFileSpec().GetPath().c_str());
const_iterator begin = m_unwinds.begin();
const_iterator end = m_unwinds.end();
for (const_iterator pos = begin; pos != end; ++pos)
{
- s.Printf ("[%u] 0x%16.16llx\n", (unsigned)std::distance (begin, pos), pos->first);
+ s.Printf ("[%u] 0x%16.16" PRIx64 "\n", (unsigned)std::distance (begin, pos), pos->first);
}
s.EOL();
}
Modified: lldb/branches/lldb-platform-work/source/Symbol/Variable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/Variable.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/Variable.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/Variable.cpp Thu Jun 6 19:06:43 2013
@@ -9,6 +9,7 @@
#include "lldb/Symbol/Variable.h"
+#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/ValueObject.h"
@@ -202,7 +203,7 @@ Variable::CalculateSymbolContext (Symbol
if (m_owner_scope)
m_owner_scope->CalculateSymbolContext(sc);
else
- sc->Clear();
+ sc->Clear(false);
}
bool
@@ -395,11 +396,12 @@ Variable::GetValuesForVariableExpression
default:
{
- RegularExpression regex ("^([A-Za-z_:][A-Za-z_0-9:]*)(.*)");
- if (regex.Execute(variable_expr_path, 1))
+ static RegularExpression g_regex ("^([A-Za-z_:][A-Za-z_0-9:]*)(.*)");
+ RegularExpression::Match regex_match(1);
+ if (g_regex.Execute(variable_expr_path, ®ex_match))
{
std::string variable_name;
- if (regex.GetMatchAtIndex(variable_expr_path, 1, variable_name))
+ if (regex_match.GetMatchAtIndex(variable_expr_path, 1, variable_name))
{
variable_list.Clear();
if (callback (baton, variable_name.c_str(), variable_list))
@@ -414,8 +416,8 @@ Variable::GetValuesForVariableExpression
ValueObjectSP variable_valobj_sp(ValueObjectVariable::Create (scope, var_sp));
if (variable_valobj_sp)
{
- variable_expr_path += variable_name.size();
- if (*variable_expr_path)
+ const char *variable_sub_expr_path = variable_expr_path + variable_name.size();
+ if (*variable_sub_expr_path)
{
const char* first_unparsed = NULL;
ValueObject::ExpressionPathScanEndReason reason_to_stop;
@@ -423,7 +425,7 @@ Variable::GetValuesForVariableExpression
ValueObject::GetValueForExpressionPathOptions options;
ValueObject::ExpressionPathAftermath final_task_on_target;
- valobj_sp = variable_valobj_sp->GetValueForExpressionPath (variable_expr_path,
+ valobj_sp = variable_valobj_sp->GetValueForExpressionPath (variable_sub_expr_path,
&first_unparsed,
&reason_to_stop,
&final_value_type,
@@ -432,7 +434,7 @@ Variable::GetValuesForVariableExpression
if (!valobj_sp)
{
error.SetErrorStringWithFormat ("invalid expression path '%s' for variable '%s'",
- variable_expr_path,
+ variable_sub_expr_path,
var_sp->GetName().GetCString());
}
}
@@ -463,7 +465,7 @@ Variable::GetValuesForVariableExpression
}
}
}
- error.SetErrorStringWithFormat ("unable to extracta variable name from '%s'", variable_expr_path);
+ error.SetErrorStringWithFormat ("unable to extract a variable name from '%s'", variable_expr_path);
}
break;
}
@@ -514,6 +516,397 @@ Variable::DumpLocationForAddress (Stream
}
}
return false;
+}
+
+
+static void
+PrivateAutoComplete (StackFrame *frame,
+ const std::string &partial_path,
+ const std::string &prefix_path, // Anything that has been resolved already will be in here
+ const ClangASTType& clang_type,
+ StringList &matches,
+ bool &word_complete);
+
+static void
+PrivateAutoCompleteMembers (StackFrame *frame,
+ const std::string &partial_member_name,
+ const std::string &partial_path,
+ const std::string &prefix_path, // Anything that has been resolved already will be in here
+ const ClangASTType& clang_type,
+ StringList &matches,
+ bool &word_complete);
+
+static void
+PrivateAutoCompleteMembers (StackFrame *frame,
+ const std::string &partial_member_name,
+ const std::string &partial_path,
+ const std::string &prefix_path, // Anything that has been resolved already will be in here
+ const ClangASTType& clang_type,
+ StringList &matches,
+ bool &word_complete)
+{
+
+ // We are in a type parsing child members
+ const uint32_t num_bases = ClangASTContext::GetNumDirectBaseClasses(clang_type.GetASTContext(),
+ clang_type.GetOpaqueQualType());
+
+ if (num_bases > 0)
+ {
+ for (uint32_t i = 0; i < num_bases; ++i)
+ {
+ ClangASTType base_class_type (clang_type.GetASTContext(),
+ ClangASTContext::GetDirectBaseClassAtIndex (clang_type.GetASTContext(),
+ clang_type.GetOpaqueQualType(),
+ i,
+ NULL));
+
+ PrivateAutoCompleteMembers (frame,
+ partial_member_name,
+ partial_path,
+ prefix_path,
+ base_class_type.GetCanonicalType(),
+ matches,
+ word_complete);
+ }
+ }
+
+ const uint32_t num_vbases = ClangASTContext::GetNumVirtualBaseClasses(clang_type.GetASTContext(),
+ clang_type.GetOpaqueQualType());
+
+ if (num_vbases > 0)
+ {
+ for (uint32_t i = 0; i < num_vbases; ++i)
+ {
+ ClangASTType vbase_class_type (clang_type.GetASTContext(),
+ ClangASTContext::GetVirtualBaseClassAtIndex(clang_type.GetASTContext(),
+ clang_type.GetOpaqueQualType(),
+ i,
+ NULL));
+
+ PrivateAutoCompleteMembers (frame,
+ partial_member_name,
+ partial_path,
+ prefix_path,
+ vbase_class_type.GetCanonicalType(),
+ matches,
+ word_complete);
+ }
+ }
+
+ // We are in a type parsing child members
+ const uint32_t num_fields = ClangASTContext::GetNumFields(clang_type.GetASTContext(),
+ clang_type.GetOpaqueQualType());
+
+ if (num_fields > 0)
+ {
+ for (uint32_t i = 0; i < num_fields; ++i)
+ {
+ std::string member_name;
+
+ lldb::clang_type_t member_type = ClangASTContext::GetFieldAtIndex (clang_type.GetASTContext(),
+ clang_type.GetOpaqueQualType(),
+ i,
+ member_name,
+ NULL,
+ NULL,
+ NULL);
+
+ if (partial_member_name.empty() ||
+ member_name.find(partial_member_name) == 0)
+ {
+ if (member_name == partial_member_name)
+ {
+ ClangASTType member_clang_type (clang_type.GetASTContext(), member_type);
+ PrivateAutoComplete (frame,
+ partial_path,
+ prefix_path + member_name, // Anything that has been resolved already will be in here
+ member_clang_type.GetCanonicalType(),
+ matches,
+ word_complete);
+ }
+ else
+ {
+ matches.AppendString (prefix_path + member_name);
+ }
+ }
+ }
+ }
+}
+
+static void
+PrivateAutoComplete (StackFrame *frame,
+ const std::string &partial_path,
+ const std::string &prefix_path, // Anything that has been resolved already will be in here
+ const ClangASTType& clang_type,
+ StringList &matches,
+ bool &word_complete)
+{
+// printf ("\nPrivateAutoComplete()\n\tprefix_path = '%s'\n\tpartial_path = '%s'\n", prefix_path.c_str(), partial_path.c_str());
+ std::string remaining_partial_path;
+
+ const lldb::TypeClass type_class = clang_type.GetTypeClass();
+ if (partial_path.empty())
+ {
+ if (clang_type.IsValid())
+ {
+ switch (type_class)
+ {
+ default:
+ case eTypeClassArray:
+ case eTypeClassBlockPointer:
+ case eTypeClassBuiltin:
+ case eTypeClassComplexFloat:
+ case eTypeClassComplexInteger:
+ case eTypeClassEnumeration:
+ case eTypeClassFunction:
+ case eTypeClassMemberPointer:
+ case eTypeClassReference:
+ case eTypeClassTypedef:
+ case eTypeClassVector:
+ {
+ matches.AppendString (prefix_path);
+ word_complete = matches.GetSize() == 1;
+ }
+ break;
+
+ case eTypeClassClass:
+ case eTypeClassStruct:
+ case eTypeClassUnion:
+ if (prefix_path.back() != '.')
+ matches.AppendString (prefix_path + '.');
+ break;
+
+ case eTypeClassObjCObject:
+ case eTypeClassObjCInterface:
+ break;
+ case eTypeClassObjCObjectPointer:
+ case eTypeClassPointer:
+ {
+ bool omit_empty_base_classes = true;
+ if (ClangASTContext::GetNumChildren (clang_type.GetASTContext(), clang_type.GetPointeeType(), omit_empty_base_classes) > 0)
+ matches.AppendString (prefix_path + "->");
+ else
+ {
+ matches.AppendString (prefix_path);
+ word_complete = true;
+ }
+ }
+ break;
+ }
+ }
+ else
+ {
+ if (frame)
+ {
+ const bool get_file_globals = true;
+
+ VariableList *variable_list = frame->GetVariableList(get_file_globals);
+
+ const size_t num_variables = variable_list->GetSize();
+ for (size_t i=0; i<num_variables; ++i)
+ {
+ Variable *variable = variable_list->GetVariableAtIndex(i).get();
+ matches.AppendString (variable->GetName().AsCString());
+ }
+ }
+ }
+ }
+ else
+ {
+ const char ch = partial_path[0];
+ switch (ch)
+ {
+ case '*':
+ if (prefix_path.empty())
+ {
+ PrivateAutoComplete (frame,
+ partial_path.substr(1),
+ std::string("*"),
+ clang_type,
+ matches,
+ word_complete);
+ }
+ break;
+
+ case '&':
+ if (prefix_path.empty())
+ {
+ PrivateAutoComplete (frame,
+ partial_path.substr(1),
+ std::string("&"),
+ clang_type,
+ matches,
+ word_complete);
+ }
+ break;
+
+ case '-':
+ if (partial_path[1] == '>' && !prefix_path.empty())
+ {
+ switch (type_class)
+ {
+ case lldb::eTypeClassPointer:
+ {
+ ClangASTType pointee_type(clang_type.GetASTContext(), clang_type.GetPointeeType());
+ if (partial_path[2])
+ {
+ // If there is more after the "->", then search deeper
+ PrivateAutoComplete (frame,
+ partial_path.substr(2),
+ prefix_path + "->",
+ pointee_type.GetCanonicalType(),
+ matches,
+ word_complete);
+ }
+ else
+ {
+ // Nothing after the "->", so list all members
+ PrivateAutoCompleteMembers (frame,
+ std::string(),
+ std::string(),
+ prefix_path + "->",
+ pointee_type.GetCanonicalType(),
+ matches,
+ word_complete);
+ }
+ }
+ default:
+ break;
+ }
+ }
+ break;
+
+ case '.':
+ if (clang_type.IsValid())
+ {
+ switch (type_class)
+ {
+ case lldb::eTypeClassUnion:
+ case lldb::eTypeClassStruct:
+ case lldb::eTypeClassClass:
+ if (partial_path[1])
+ {
+ // If there is more after the ".", then search deeper
+ PrivateAutoComplete (frame,
+ partial_path.substr(1),
+ prefix_path + ".",
+ clang_type,
+ matches,
+ word_complete);
+
+ }
+ else
+ {
+ // Nothing after the ".", so list all members
+ PrivateAutoCompleteMembers (frame,
+ std::string(),
+ partial_path,
+ prefix_path + ".",
+ clang_type,
+ matches,
+ word_complete);
+ }
+ default:
+ break;
+ }
+ }
+ break;
+ default:
+ if (isalpha(ch) || ch == '_' || ch == '$')
+ {
+ const size_t partial_path_len = partial_path.size();
+ size_t pos = 1;
+ while (pos < partial_path_len)
+ {
+ const char curr_ch = partial_path[pos];
+ if (isalnum(curr_ch) || curr_ch == '_' || curr_ch == '$')
+ {
+ ++pos;
+ continue;
+ }
+ break;
+ }
+
+ std::string token(partial_path, 0, pos);
+ remaining_partial_path = partial_path.substr(pos);
+
+ if (clang_type.IsValid())
+ {
+ PrivateAutoCompleteMembers (frame,
+ token,
+ remaining_partial_path,
+ prefix_path,
+ clang_type,
+ matches,
+ word_complete);
+ }
+ else if (frame)
+ {
+ // We haven't found our variable yet
+ const bool get_file_globals = true;
+
+ VariableList *variable_list = frame->GetVariableList(get_file_globals);
+
+ const size_t num_variables = variable_list->GetSize();
+ for (size_t i=0; i<num_variables; ++i)
+ {
+ Variable *variable = variable_list->GetVariableAtIndex(i).get();
+ const char *variable_name = variable->GetName().AsCString();
+ if (strstr(variable_name, token.c_str()) == variable_name)
+ {
+ if (strcmp (variable_name, token.c_str()) == 0)
+ {
+ Type *variable_type = variable->GetType();
+ if (variable_type)
+ {
+ ClangASTType variable_clang_type (variable_type->GetClangAST(), variable_type->GetClangForwardType());
+ PrivateAutoComplete (frame,
+ remaining_partial_path,
+ prefix_path + token, // Anything that has been resolved already will be in here
+ variable_clang_type.GetCanonicalType(),
+ matches,
+ word_complete);
+ }
+ else
+ {
+ matches.AppendString (prefix_path + variable_name);
+ }
+ }
+ else if (remaining_partial_path.empty())
+ {
+ matches.AppendString (prefix_path + variable_name);
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+}
+
+
+
+size_t
+Variable::AutoComplete (const ExecutionContext &exe_ctx,
+ const char *partial_path_cstr,
+ StringList &matches,
+ bool &word_complete)
+{
+ word_complete = false;
+ std::string partial_path;
+ std::string prefix_path;
+ ClangASTType clang_type;
+ if (partial_path_cstr && partial_path_cstr[0])
+ partial_path = partial_path_cstr;
+
+ PrivateAutoComplete (exe_ctx.GetFramePtr(),
+ partial_path,
+ prefix_path,
+ clang_type,
+ matches,
+ word_complete);
+ return matches.GetSize();
}
Modified: lldb/branches/lldb-platform-work/source/Symbol/VariableList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/VariableList.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/VariableList.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/VariableList.cpp Thu Jun 6 19:06:43 2013
@@ -52,9 +52,12 @@ VariableList::AddVariableIfUnique (const
void
VariableList::AddVariables(VariableList *variable_list)
{
- std::copy( variable_list->m_variables.begin(), // source begin
- variable_list->m_variables.end(), // source end
- back_inserter(m_variables)); // destination
+ if (variable_list)
+ {
+ std::copy(variable_list->m_variables.begin(), // source begin
+ variable_list->m_variables.end(), // source end
+ back_inserter(m_variables)); // destination
+ }
}
void
@@ -64,7 +67,7 @@ VariableList::Clear()
}
VariableSP
-VariableList::GetVariableAtIndex(uint32_t idx)
+VariableList::GetVariableAtIndex(size_t idx) const
{
VariableSP var_sp;
if (idx < m_variables.size())
@@ -73,7 +76,7 @@ VariableList::GetVariableAtIndex(uint32_
}
VariableSP
-VariableList::RemoveVariableAtIndex(uint32_t idx)
+VariableList::RemoveVariableAtIndex(size_t idx)
{
VariableSP var_sp;
if (idx < m_variables.size())
@@ -131,6 +134,27 @@ VariableList::AppendVariablesIfUnique (c
return var_list.GetSize() - initial_size;
}
+size_t
+VariableList::AppendVariablesWithScope (lldb::ValueType type,
+ VariableList &var_list,
+ bool if_unique)
+{
+ const size_t initial_size = var_list.GetSize();
+ iterator pos, end = m_variables.end();
+ for (pos = m_variables.begin(); pos != end; ++pos)
+ {
+ if ((*pos)->GetScope() == type)
+ {
+ if (if_unique)
+ var_list.AddVariableIfUnique (*pos);
+ else
+ var_list.AddVariable(*pos);
+ }
+ }
+ // Return the number of new unique variables added to "var_list"
+ return var_list.GetSize() - initial_size;
+}
+
uint32_t
VariableList::FindIndexForVariable (Variable* variable)
{
@@ -175,41 +199,3 @@ VariableList::Dump(Stream *s, bool show_
(*pos)->Dump(s, show_context);
}
}
-
-lldb::VariableSP
-VariableList::FindArtificialObjectVariable (lldb::LanguageType language) const
-{
- lldb::VariableSP object_variable_sp;
- ConstString object_variable_name;
- switch (language)
- {
- case eLanguageTypeC_plus_plus:
- object_variable_name.SetCString("this");
- break;
-
- case eLanguageTypeObjC:
- case eLanguageTypeObjC_plus_plus:
- object_variable_name.SetCString("self");
- break;
-
- default:
- break;
- }
- if (object_variable_name)
- {
- const_iterator pos, end = m_variables.end();
- for (pos = m_variables.begin(); pos != end; ++pos)
- {
- Variable *variable = pos->get();
- if (variable->IsArtificial() &&
- variable->GetScope() == eValueTypeVariableArgument &&
- variable->GetName() == object_variable_name)
- {
- object_variable_sp = *pos;
- break;
- }
- }
- }
- return object_variable_sp;
-}
-
Modified: lldb/branches/lldb-platform-work/source/Target/ABI.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ABI.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ABI.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ABI.cpp Thu Jun 6 19:06:43 2013
@@ -156,6 +156,7 @@ ABI::GetReturnValueObject (Thread &threa
// we don't do anything with these for now
break;
case Value::eValueTypeScalar:
+ case Value::eValueTypeVector:
clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsFreezeDried;
clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
Modified: lldb/branches/lldb-platform-work/source/Target/CPPLanguageRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/CPPLanguageRuntime.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/CPPLanguageRuntime.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/CPPLanguageRuntime.cpp Thu Jun 6 19:06:43 2013
@@ -9,6 +9,8 @@
#include "lldb/Target/CPPLanguageRuntime.h"
+#include <string.h>
+
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Target/ExecutionContext.h"
@@ -190,66 +192,28 @@ CPPLanguageRuntime::IsCPPMangledName (co
bool
CPPLanguageRuntime::StripNamespacesFromVariableName (const char *name, const char *&base_name_start, const char *&base_name_end)
{
- if (base_name_end == NULL)
- base_name_end = name + strlen (name);
+ if (base_name_end == NULL)
+ base_name_end = name + strlen (name);
- const char *last_colon = NULL;
- for (const char *ptr = base_name_end; ptr != name; ptr--)
- {
- if (*ptr == ':')
- {
- last_colon = ptr;
- break;
- }
- }
-
- if (last_colon == NULL)
- {
- base_name_start = name;
- return true;
- }
-
- // Can't have a C++ name that begins with a single ':', nor contains an internal single ':'
- if (last_colon == name)
- return false;
- else if (last_colon[-1] != ':')
- return false;
- else
+ const char *last_colon = strrchr (name, ':');
+
+ if (last_colon == NULL)
{
- // FIXME: should check if there is
- base_name_start = last_colon + 1;
- return true;
+ base_name_start = name;
+ return true;
}
-}
-bool
-CPPLanguageRuntime::IsPossibleCPPCall (const char *name, const char *&base_name_start, const char *&base_name_end)
-{
- if (!name)
- return false;
- // For now, I really can't handle taking template names apart, so if you
- // have < or > I'll say "could be CPP but leave the base_name empty which
- // means I couldn't figure out what to use for that.
- // FIXME: Do I need to do more sanity checking here?
-
- if (strchr(name, '>') != NULL || strchr (name, '>') != NULL)
- return true;
-
- size_t name_len = strlen (name);
-
- if (name[name_len - 1] == ')')
+
+ // Can't have a C++ name that begins with a single ':', nor contains an internal single ':'
+ if (last_colon == name)
+ return false;
+ else if (last_colon[-1] != ':')
+ return false;
+ else
{
- // We've got arguments.
- base_name_end = strchr (name, '(');
- if (base_name_end == NULL)
- return false;
-
- // FIXME: should check that this parenthesis isn't a template specialized
- // on a function type or something gross like that...
+ // FIXME: should check if there is
+ base_name_start = last_colon + 1;
+ return true;
}
- else
- base_name_end = name + strlen (name);
-
- return StripNamespacesFromVariableName (name, base_name_start, base_name_end);
}
uint32_t
@@ -267,3 +231,156 @@ CPPLanguageRuntime::FindEquivalentNames(
return count;
}
+
+void
+CPPLanguageRuntime::MethodName::Clear()
+{
+ m_full.Clear();
+ m_basename = llvm::StringRef();
+ m_context = llvm::StringRef();
+ m_arguments = llvm::StringRef();
+ m_qualifiers = llvm::StringRef();
+ m_type = eTypeInvalid;
+ m_parsed = false;
+ m_parse_error = false;
+}
+
+bool
+ReverseFindMatchingChars (const llvm::StringRef &s,
+ const llvm::StringRef &left_right_chars,
+ size_t &left_pos,
+ size_t &right_pos,
+ size_t pos = llvm::StringRef::npos)
+{
+ assert (left_right_chars.size() == 2);
+ left_pos = llvm::StringRef::npos;
+ const char left_char = left_right_chars[0];
+ const char right_char = left_right_chars[1];
+ pos = s.find_last_of(left_right_chars, pos);
+ if (pos == llvm::StringRef::npos || s[pos] == left_char)
+ return false;
+ right_pos = pos;
+ uint32_t depth = 1;
+ while (pos > 0 && depth > 0)
+ {
+ pos = s.find_last_of(left_right_chars, pos);
+ if (pos == llvm::StringRef::npos)
+ return false;
+ if (s[pos] == left_char)
+ {
+ if (--depth == 0)
+ {
+ left_pos = pos;
+ return left_pos < right_pos;
+ }
+ }
+ else if (s[pos] == right_char)
+ {
+ ++depth;
+ }
+ }
+ return false;
+}
+
+void
+CPPLanguageRuntime::MethodName::Parse()
+{
+ if (!m_parsed && m_full)
+ {
+// ConstString mangled;
+// m_full.GetMangledCounterpart(mangled);
+// printf ("\n parsing = '%s'\n", m_full.GetCString());
+// if (mangled)
+// printf (" mangled = '%s'\n", mangled.GetCString());
+ m_parse_error = false;
+ m_parsed = true;
+ llvm::StringRef full (m_full.GetCString());
+
+ size_t arg_start, arg_end;
+ llvm::StringRef parens("()", 2);
+ if (ReverseFindMatchingChars (full, parens, arg_start, arg_end))
+ {
+ m_arguments = full.substr(arg_start, arg_end - arg_start + 1);
+ if (arg_end + 1 < full.size())
+ m_qualifiers = full.substr(arg_end + 1);
+ if (arg_start > 0)
+ {
+ size_t basename_end = arg_start;
+ size_t context_end = llvm::StringRef::npos;
+ if (basename_end > 0 && full[basename_end-1] == '>')
+ {
+ // TODO: handle template junk...
+ // Templated function
+ size_t template_start, template_end;
+ llvm::StringRef lt_gt("<>", 2);
+ if (ReverseFindMatchingChars (full, lt_gt, template_start, template_end, basename_end))
+ context_end = full.rfind(':', template_start);
+ }
+ if (context_end == llvm::StringRef::npos)
+ context_end = full.rfind(':', basename_end);
+
+ if (context_end == llvm::StringRef::npos)
+ m_basename = full.substr(0, basename_end);
+ else
+ {
+ m_context = full.substr(0, context_end - 1);
+ const size_t basename_begin = context_end + 1;
+ m_basename = full.substr(basename_begin, basename_end - basename_begin);
+ }
+ m_type = eTypeUnknownMethod;
+ }
+ else
+ {
+ m_parse_error = true;
+ return;
+ }
+
+// if (!m_context.empty())
+// printf (" context = '%s'\n", m_context.str().c_str());
+// if (m_basename)
+// printf (" basename = '%s'\n", m_basename.GetCString());
+// if (!m_arguments.empty())
+// printf (" arguments = '%s'\n", m_arguments.str().c_str());
+// if (!m_qualifiers.empty())
+// printf ("qualifiers = '%s'\n", m_qualifiers.str().c_str());
+ }
+ else
+ {
+ m_parse_error = true;
+// printf ("error: didn't find matching parens for arguments\n");
+ }
+ }
+}
+
+llvm::StringRef
+CPPLanguageRuntime::MethodName::GetBasename ()
+{
+ if (!m_parsed)
+ Parse();
+ return m_basename;
+}
+
+llvm::StringRef
+CPPLanguageRuntime::MethodName::GetContext ()
+{
+ if (!m_parsed)
+ Parse();
+ return m_context;
+}
+
+llvm::StringRef
+CPPLanguageRuntime::MethodName::GetArguments ()
+{
+ if (!m_parsed)
+ Parse();
+ return m_arguments;
+}
+
+llvm::StringRef
+CPPLanguageRuntime::MethodName::GetQualifiers ()
+{
+ if (!m_parsed)
+ Parse();
+ return m_qualifiers;
+}
+
Modified: lldb/branches/lldb-platform-work/source/Target/ExecutionContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ExecutionContext.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ExecutionContext.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ExecutionContext.cpp Thu Jun 6 19:06:43 2013
@@ -169,6 +169,40 @@ ExecutionContext::ExecutionContext (cons
}
}
+ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr, Mutex::Locker &locker) :
+ m_target_sp (),
+ m_process_sp (),
+ m_thread_sp (),
+ m_frame_sp ()
+{
+ if (exe_ctx_ref_ptr)
+ {
+ m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
+ if (m_target_sp)
+ {
+ locker.Lock(m_target_sp->GetAPIMutex());
+ m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
+ m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
+ m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
+ }
+ }
+}
+
+ExecutionContext::ExecutionContext (const ExecutionContextRef &exe_ctx_ref, Mutex::Locker &locker) :
+ m_target_sp (exe_ctx_ref.GetTargetSP()),
+ m_process_sp (),
+ m_thread_sp (),
+ m_frame_sp ()
+{
+ if (m_target_sp)
+ {
+ locker.Lock(m_target_sp->GetAPIMutex());
+ m_process_sp = exe_ctx_ref.GetProcessSP();
+ m_thread_sp = exe_ctx_ref.GetThreadSP();
+ m_frame_sp = exe_ctx_ref.GetFrameSP();
+ }
+}
+
ExecutionContext::ExecutionContext (ExecutionContextScope *exe_scope_ptr) :
m_target_sp (),
m_process_sp (),
@@ -459,13 +493,38 @@ ExecutionContext::operator !=(const Exec
return !(*this == rhs);
}
+bool
+ExecutionContext::HasTargetScope () const
+{
+ return ((bool) m_target_sp
+ && m_target_sp->IsValid());
+}
+
+bool
+ExecutionContext::HasProcessScope () const
+{
+ return (HasTargetScope()
+ && ((bool) m_process_sp && m_process_sp->IsValid()));
+}
+
+bool
+ExecutionContext::HasThreadScope () const
+{
+ return (HasProcessScope()
+ && ((bool) m_thread_sp && m_thread_sp->IsValid()));
+}
+
+bool
+ExecutionContext::HasFrameScope () const
+{
+ return HasThreadScope() && m_frame_sp;
+}
ExecutionContextRef::ExecutionContextRef() :
m_target_wp (),
m_process_wp (),
m_thread_wp (),
- m_frame_wp (),
- m_tid(LLDB_INVALID_THREAD_ID),
+ m_tid(LLDB_INVALID_THREAD_ID),
m_stack_id ()
{
}
@@ -474,8 +533,7 @@ ExecutionContextRef::ExecutionContextRef
m_target_wp (),
m_process_wp (),
m_thread_wp (),
- m_frame_wp (),
- m_tid(LLDB_INVALID_THREAD_ID),
+ m_tid(LLDB_INVALID_THREAD_ID),
m_stack_id ()
{
if (exe_ctx)
@@ -486,8 +544,7 @@ ExecutionContextRef::ExecutionContextRef
m_target_wp (),
m_process_wp (),
m_thread_wp (),
- m_frame_wp (),
- m_tid(LLDB_INVALID_THREAD_ID),
+ m_tid(LLDB_INVALID_THREAD_ID),
m_stack_id ()
{
*this = exe_ctx;
@@ -498,8 +555,7 @@ ExecutionContextRef::ExecutionContextRef
m_target_wp(),
m_process_wp(),
m_thread_wp(),
- m_frame_wp(),
- m_tid(LLDB_INVALID_THREAD_ID),
+ m_tid(LLDB_INVALID_THREAD_ID),
m_stack_id ()
{
SetTargetPtr (target, adopt_selected);
@@ -512,7 +568,6 @@ ExecutionContextRef::ExecutionContextRef
m_target_wp (rhs.m_target_wp),
m_process_wp(rhs.m_process_wp),
m_thread_wp (rhs.m_thread_wp),
- m_frame_wp (rhs.m_frame_wp),
m_tid (rhs.m_tid),
m_stack_id (rhs.m_stack_id)
{
@@ -526,7 +581,6 @@ ExecutionContextRef::operator =(const Ex
m_target_wp = rhs.m_target_wp;
m_process_wp = rhs.m_process_wp;
m_thread_wp = rhs.m_thread_wp;
- m_frame_wp = rhs.m_frame_wp;
m_tid = rhs.m_tid;
m_stack_id = rhs.m_stack_id;
}
@@ -545,7 +599,6 @@ ExecutionContextRef::operator =(const Ex
else
m_tid = LLDB_INVALID_THREAD_ID;
lldb::StackFrameSP frame_sp (exe_ctx.GetFrameSP());
- m_frame_wp = frame_sp;
if (frame_sp)
m_stack_id = frame_sp->GetStackID();
else
@@ -609,7 +662,6 @@ ExecutionContextRef::SetFrameSP (const l
{
if (frame_sp)
{
- m_frame_wp = frame_sp;
m_stack_id = frame_sp->GetStackID();
SetThreadSP (frame_sp->GetThread());
}
@@ -703,11 +755,29 @@ ExecutionContextRef::SetFramePtr (StackF
Clear();
}
+lldb::TargetSP
+ExecutionContextRef::GetTargetSP () const
+{
+ lldb::TargetSP target_sp(m_target_wp.lock());
+ if (target_sp && !target_sp->IsValid())
+ target_sp.reset();
+ return target_sp;
+}
+
+lldb::ProcessSP
+ExecutionContextRef::GetProcessSP () const
+{
+ lldb::ProcessSP process_sp(m_process_wp.lock());
+ if (process_sp && !process_sp->IsValid())
+ process_sp.reset();
+ return process_sp;
+}
lldb::ThreadSP
ExecutionContextRef::GetThreadSP () const
{
lldb::ThreadSP thread_sp (m_thread_wp.lock());
+
if (m_tid != LLDB_INVALID_THREAD_ID)
{
// We check if the thread has been destroyed in cases where clients
@@ -716,30 +786,33 @@ ExecutionContextRef::GetThreadSP () cons
if (!thread_sp || !thread_sp->IsValid())
{
lldb::ProcessSP process_sp(GetProcessSP());
- if (process_sp)
+ if (process_sp && process_sp->IsValid())
{
thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid);
m_thread_wp = thread_sp;
}
}
}
+
+ // Check that we aren't about to return an invalid thread sp. We might return a NULL thread_sp,
+ // but don't return an invalid one.
+
+ if (thread_sp && !thread_sp->IsValid())
+ thread_sp.reset();
+
return thread_sp;
}
lldb::StackFrameSP
ExecutionContextRef::GetFrameSP () const
{
- lldb::StackFrameSP frame_sp (m_frame_wp.lock());
- if (!frame_sp && m_stack_id.IsValid())
+ if (m_stack_id.IsValid())
{
lldb::ThreadSP thread_sp (GetThreadSP());
if (thread_sp)
- {
- frame_sp = thread_sp->GetFrameWithStackID (m_stack_id);
- m_frame_wp = frame_sp;
- }
+ return thread_sp->GetFrameWithStackID (m_stack_id);
}
- return frame_sp;
+ return lldb::StackFrameSP();
}
ExecutionContext
Modified: lldb/branches/lldb-platform-work/source/Target/LanguageRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/LanguageRuntime.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/LanguageRuntime.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/LanguageRuntime.cpp Thu Jun 6 19:06:43 2013
@@ -14,10 +14,221 @@
using namespace lldb;
using namespace lldb_private;
+
+class ExceptionSearchFilter : public SearchFilter
+{
+public:
+ ExceptionSearchFilter (const lldb::TargetSP &target_sp,
+ lldb::LanguageType language) :
+ SearchFilter (target_sp),
+ m_language (language),
+ m_language_runtime (NULL),
+ m_filter_sp ()
+ {
+ UpdateModuleListIfNeeded ();
+ }
+
+ virtual bool
+ ModulePasses (const lldb::ModuleSP &module_sp)
+ {
+ UpdateModuleListIfNeeded ();
+ if (m_filter_sp)
+ return m_filter_sp->ModulePasses (module_sp);
+ return false;
+ }
+
+ virtual bool
+ ModulePasses (const FileSpec &spec)
+ {
+ UpdateModuleListIfNeeded ();
+ if (m_filter_sp)
+ return m_filter_sp->ModulePasses (spec);
+ return false;
+
+ }
+
+ virtual void
+ Search (Searcher &searcher)
+ {
+ UpdateModuleListIfNeeded ();
+ if (m_filter_sp)
+ m_filter_sp->Search (searcher);
+ }
+
+ virtual void
+ GetDescription (Stream *s)
+ {
+ UpdateModuleListIfNeeded ();
+ if (m_filter_sp)
+ m_filter_sp->GetDescription (s);
+ }
+
+protected:
+ LanguageType m_language;
+ LanguageRuntime *m_language_runtime;
+ SearchFilterSP m_filter_sp;
+
+ void
+ UpdateModuleListIfNeeded ()
+ {
+ ProcessSP process_sp (m_target_sp->GetProcessSP());
+ if (process_sp)
+ {
+ bool refreash_filter = !m_filter_sp;
+ if (m_language_runtime == NULL)
+ {
+ m_language_runtime = process_sp->GetLanguageRuntime(m_language);
+ refreash_filter = true;
+ }
+ else
+ {
+ LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
+ if (m_language_runtime != language_runtime)
+ {
+ m_language_runtime = language_runtime;
+ refreash_filter = true;
+ }
+ }
+
+ if (refreash_filter && m_language_runtime)
+ {
+ m_filter_sp = m_language_runtime->CreateExceptionSearchFilter ();
+ }
+ }
+ else
+ {
+ m_filter_sp.reset();
+ m_language_runtime = NULL;
+ }
+ }
+};
+
+// The Target is the one that knows how to create breakpoints, so this function
+// is meant to be used either by the target or internally in Set/ClearExceptionBreakpoints.
+class ExceptionBreakpointResolver : public BreakpointResolver
+{
+public:
+ ExceptionBreakpointResolver (lldb::LanguageType language,
+ bool catch_bp,
+ bool throw_bp) :
+ BreakpointResolver (NULL, BreakpointResolver::ExceptionResolver),
+ m_language (language),
+ m_language_runtime (NULL),
+ m_catch_bp (catch_bp),
+ m_throw_bp (throw_bp)
+ {
+ }
+
+ virtual
+ ~ExceptionBreakpointResolver()
+ {
+ }
+
+ virtual Searcher::CallbackReturn
+ SearchCallback (SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr,
+ bool containing)
+ {
+
+ if (SetActualResolver())
+ return m_actual_resolver_sp->SearchCallback (filter, context, addr, containing);
+ else
+ return eCallbackReturnStop;
+ }
+
+ virtual Searcher::Depth
+ GetDepth ()
+ {
+ if (SetActualResolver())
+ return m_actual_resolver_sp->GetDepth();
+ else
+ return eDepthTarget;
+ }
+
+ virtual void
+ GetDescription (Stream *s)
+ {
+ s->Printf ("Exception breakpoint (catch: %s throw: %s)",
+ m_catch_bp ? "on" : "off",
+ m_throw_bp ? "on" : "off");
+
+ SetActualResolver();
+ if (m_actual_resolver_sp)
+ {
+ s->Printf (" using: ");
+ m_actual_resolver_sp->GetDescription (s);
+ }
+ else
+ s->Printf (" the correct runtime exception handler will be determined when you run");
+ }
+
+ virtual void
+ Dump (Stream *s) const
+ {
+ }
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const BreakpointResolverName *) { return true; }
+ static inline bool classof(const BreakpointResolver *V) {
+ return V->getResolverID() == BreakpointResolver::ExceptionResolver;
+ }
+protected:
+ bool
+ SetActualResolver()
+ {
+ ProcessSP process_sp;
+ if (m_breakpoint)
+ {
+ process_sp = m_breakpoint->GetTarget().GetProcessSP();
+ if (process_sp)
+ {
+ bool refreash_resolver = !m_actual_resolver_sp;
+ if (m_language_runtime == NULL)
+ {
+ m_language_runtime = process_sp->GetLanguageRuntime(m_language);
+ refreash_resolver = true;
+ }
+ else
+ {
+ LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
+ if (m_language_runtime != language_runtime)
+ {
+ m_language_runtime = language_runtime;
+ refreash_resolver = true;
+ }
+ }
+
+ if (refreash_resolver && m_language_runtime)
+ {
+ m_actual_resolver_sp = m_language_runtime->CreateExceptionResolver (m_breakpoint, m_catch_bp, m_throw_bp);
+ }
+ }
+ else
+ {
+ m_actual_resolver_sp.reset();
+ m_language_runtime = NULL;
+ }
+ }
+ else
+ {
+ m_actual_resolver_sp.reset();
+ m_language_runtime = NULL;
+ }
+ return (bool)m_actual_resolver_sp;
+ }
+ lldb::BreakpointResolverSP m_actual_resolver_sp;
+ lldb::LanguageType m_language;
+ LanguageRuntime *m_language_runtime;
+ bool m_catch_bp;
+ bool m_throw_bp;
+};
+
+
LanguageRuntime*
LanguageRuntime::FindPlugin (Process *process, lldb::LanguageType language)
{
- std::auto_ptr<LanguageRuntime> language_runtime_ap;
+ std::unique_ptr<LanguageRuntime> language_runtime_ap;
LanguageRuntimeCreateInstance create_callback;
for (uint32_t idx = 0;
@@ -49,152 +260,66 @@ LanguageRuntime::~LanguageRuntime()
}
BreakpointSP
-LanguageRuntime::CreateExceptionBreakpoint(
- Target &target,
- lldb::LanguageType language,
- bool catch_bp,
- bool throw_bp,
- bool is_internal)
-{
- BreakpointSP exc_breakpt_sp;
- BreakpointResolverSP resolver_sp(new ExceptionBreakpointResolver(NULL, language, catch_bp, throw_bp));
- SearchFilterSP filter_sp(target.GetSearchFilterForModule(NULL));
-
- exc_breakpt_sp = target.CreateBreakpoint (filter_sp, resolver_sp, is_internal);
-
- return exc_breakpt_sp;
-}
-
-LanguageRuntime::ExceptionBreakpointResolver::ExceptionBreakpointResolver (Breakpoint *bkpt,
- LanguageType language,
- bool catch_bp,
- bool throw_bp) :
- BreakpointResolver (bkpt, BreakpointResolver::ExceptionResolver),
- m_language (language),
- m_catch_bp (catch_bp),
- m_throw_bp (throw_bp)
-
-{
-}
-
-void
-LanguageRuntime::ExceptionBreakpointResolver::GetDescription (Stream *s)
-{
- s->Printf ("Exception breakpoint (catch: %s throw: %s)",
- m_catch_bp ? "on" : "off",
- m_throw_bp ? "on" : "off");
-
- SetActualResolver();
- if (m_actual_resolver_sp)
- {
- s->Printf (" using: ");
- m_actual_resolver_sp->GetDescription (s);
- }
- else
- s->Printf (" the correct runtime exception handler will be determined when you run");
-}
-
-bool
-LanguageRuntime::ExceptionBreakpointResolver::SetActualResolver()
+LanguageRuntime::CreateExceptionBreakpoint (Target &target,
+ lldb::LanguageType language,
+ bool catch_bp,
+ bool throw_bp,
+ bool is_internal)
{
- ProcessSP process_sp = m_process_wp.lock();
-
- // See if our process weak pointer is still good:
- if (!process_sp)
- {
- // If not, our resolver is no good, so chuck that. Then see if we can get the
- // target's new process.
- m_actual_resolver_sp.reset();
- if (m_breakpoint)
- {
- Target &target = m_breakpoint->GetTarget();
- process_sp = target.GetProcessSP();
- if (process_sp)
- {
- m_process_wp = process_sp;
- process_sp = m_process_wp.lock();
- }
- }
- }
+ BreakpointResolverSP resolver_sp(new ExceptionBreakpointResolver(language, catch_bp, throw_bp));
+ SearchFilterSP filter_sp(new ExceptionSearchFilter(target.shared_from_this(), language));
- if (process_sp)
- {
- if (m_actual_resolver_sp)
- return true;
- else
- {
- // If we have a process but not a resolver, set one now.
- LanguageRuntime *runtime = process_sp->GetLanguageRuntime(m_language);
- if (runtime)
- {
- m_actual_resolver_sp = runtime->CreateExceptionResolver (m_breakpoint, m_catch_bp, m_throw_bp);
- return (bool) m_actual_resolver_sp;
- }
- else
- return false;
- }
- }
- else
- return false;
-}
-
-Searcher::CallbackReturn
-LanguageRuntime::ExceptionBreakpointResolver::SearchCallback (SearchFilter &filter,
- SymbolContext &context,
- Address *addr,
- bool containing)
-{
+ BreakpointSP exc_breakpt_sp (target.CreateBreakpoint (filter_sp, resolver_sp, is_internal));
+ if (is_internal)
+ exc_breakpt_sp->SetBreakpointKind("exception");
- if (!SetActualResolver())
- {
- return eCallbackReturnStop;
- }
- else
- return m_actual_resolver_sp->SearchCallback (filter, context, addr, containing);
+ return exc_breakpt_sp;
}
-Searcher::Depth
-LanguageRuntime::ExceptionBreakpointResolver::GetDepth ()
-{
- if (!SetActualResolver())
- return eDepthTarget;
- else
- return m_actual_resolver_sp->GetDepth();
-}
+struct language_name_pair {
+ const char *name;
+ LanguageType type;
+};
-static const char *language_names[] =
+struct language_name_pair language_names[] =
{
- "unknown",
- "c89",
- "c",
- "ada83",
- "c++",
- "cobol74",
- "cobol85",
- "fortran77",
- "fortran90",
- "pascal83",
- "modula2",
- "java",
- "c99",
- "ada95",
- "fortran95",
- "pli",
- "objective-c",
- "objective-c++",
- "upc",
- "d",
- "python"
+ // To allow GetNameForLanguageType to be a simple array lookup, the first
+ // part of this array must follow enum LanguageType exactly.
+ { "unknown", eLanguageTypeUnknown },
+ { "c89", eLanguageTypeC89 },
+ { "c", eLanguageTypeC },
+ { "ada83", eLanguageTypeAda83 },
+ { "c++", eLanguageTypeC_plus_plus },
+ { "cobol74", eLanguageTypeCobol74 },
+ { "cobol85", eLanguageTypeCobol85 },
+ { "fortran77", eLanguageTypeFortran77 },
+ { "fortran90", eLanguageTypeFortran90 },
+ { "pascal83", eLanguageTypePascal83 },
+ { "modula2", eLanguageTypeModula2 },
+ { "java", eLanguageTypeJava },
+ { "c99", eLanguageTypeC99 },
+ { "ada95", eLanguageTypeAda95 },
+ { "fortran95", eLanguageTypeFortran95 },
+ { "pli", eLanguageTypePLI },
+ { "objective-c", eLanguageTypeObjC },
+ { "objective-c++", eLanguageTypeObjC_plus_plus },
+ { "upc", eLanguageTypeUPC },
+ { "d", eLanguageTypeD },
+ { "python", eLanguageTypePython },
+ // Now synonyms, in arbitrary order
+ { "objc", eLanguageTypeObjC },
+ { "objc++", eLanguageTypeObjC_plus_plus }
};
-static uint32_t num_languages = sizeof(language_names) / sizeof (char *);
+
+static uint32_t num_languages = sizeof(language_names) / sizeof (struct language_name_pair);
LanguageType
LanguageRuntime::GetLanguageTypeFromString (const char *string)
{
for (uint32_t i = 0; i < num_languages; i++)
{
- if (strcmp (language_names[i], string) == 0)
- return (LanguageType) i;
+ if (strcasecmp (language_names[i].name, string) == 0)
+ return (LanguageType) language_names[i].type;
}
return eLanguageTypeUnknown;
}
@@ -203,8 +328,16 @@ const char *
LanguageRuntime::GetNameForLanguageType (LanguageType language)
{
if (language < num_languages)
- return language_names[language];
+ return language_names[language].name;
else
- return language_names[eLanguageTypeUnknown];
+ return language_names[eLanguageTypeUnknown].name;
}
-
+
+lldb::SearchFilterSP
+LanguageRuntime::CreateExceptionSearchFilter ()
+{
+ return m_process->GetTarget().GetSearchFilterForModule(NULL);
+}
+
+
+
Modified: lldb/branches/lldb-platform-work/source/Target/Memory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/Memory.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/Memory.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/Memory.cpp Thu Jun 6 19:06:43 2013
@@ -40,10 +40,12 @@ MemoryCache::~MemoryCache()
}
void
-MemoryCache::Clear()
+MemoryCache::Clear(bool clear_invalid_ranges)
{
Mutex::Locker locker (m_mutex);
m_cache.clear();
+ if (clear_invalid_ranges)
+ m_invalid_ranges.Clear();
}
void
@@ -68,14 +70,11 @@ MemoryCache::Flush (addr_t addr, size_t
else
num_cache_lines = (UINT64_MAX - first_cache_line_addr + 1)/cache_line_byte_size;
- //printf ("MemoryCache::Flush (0x%16.16llx, %zu (0x%zx))\n", addr, size, size);
-
uint32_t cache_idx = 0;
for (addr_t curr_addr = first_cache_line_addr;
cache_idx < num_cache_lines;
curr_addr += cache_line_byte_size, ++cache_idx)
{
- //printf ("flushing: 0x%16.16llx\n", curr_addr); /// REMOVE THIS PRIOR TO CHECKIN!!!!
BlockMap::iterator pos = m_cache.find (curr_addr);
if (pos != m_cache.end())
m_cache.erase(pos);
@@ -131,7 +130,10 @@ MemoryCache::Read (addr_t addr,
while (bytes_left > 0)
{
if (m_invalid_ranges.FindEntryThatContains(curr_addr))
+ {
+ error.SetErrorStringWithFormat("memory read failed for 0x%" PRIx64, curr_addr);
return dst_len - bytes_left;
+ }
BlockMap::const_iterator pos = m_cache.find (curr_addr);
BlockMap::const_iterator end = m_cache.end ();
@@ -181,7 +183,7 @@ MemoryCache::Read (addr_t addr,
if (bytes_left > 0)
{
assert ((curr_addr % cache_line_byte_size) == 0);
- std::auto_ptr<DataBufferHeap> data_buffer_heap_ap(new DataBufferHeap (cache_line_byte_size, 0));
+ std::unique_ptr<DataBufferHeap> data_buffer_heap_ap(new DataBufferHeap (cache_line_byte_size, 0));
size_t process_bytes_read = m_process.ReadMemoryFromInferior (curr_addr,
data_buffer_heap_ap->GetBytes(),
data_buffer_heap_ap->GetByteSize(),
@@ -228,7 +230,7 @@ AllocatedBlock::ReserveBlock (uint32_t s
if (size <= m_byte_size)
{
const uint32_t needed_chunks = CalculateChunksNeededForSize (size);
- LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+ Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
if (m_offset_to_chunk_size.empty())
{
@@ -327,9 +329,9 @@ AllocatedBlock::ReserveBlock (uint32_t s
// return m_addr + m_chunk_size * first_chunk_idx;
// }
}
- LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+ Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
if (log)
- log->Printf ("AllocatedBlock::ReserveBlock (size = %u (0x%x)) => 0x%16.16llx", size, size, (uint64_t)addr);
+ log->Printf ("AllocatedBlock::ReserveBlock (size = %u (0x%x)) => 0x%16.16" PRIx64, size, size, (uint64_t)addr);
return addr;
}
@@ -344,9 +346,9 @@ AllocatedBlock::FreeBlock (addr_t addr)
m_offset_to_chunk_size.erase (pos);
success = true;
}
- LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+ Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
if (log)
- log->Printf ("AllocatedBlock::FreeBlock (addr = 0x%16.16llx) => %i", (uint64_t)addr, success);
+ log->Printf ("AllocatedBlock::FreeBlock (addr = 0x%16.16" PRIx64 ") => %i", (uint64_t)addr, success);
return success;
}
@@ -390,10 +392,10 @@ AllocatedMemoryCache::AllocatePage (uint
addr_t addr = m_process.DoAllocateMemory(page_byte_size, permissions, error);
- LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
{
- log->Printf ("Process::DoAllocateMemory (byte_size = 0x%8.8zx, permissions = %s) => 0x%16.16llx",
+ log->Printf ("Process::DoAllocateMemory (byte_size = 0x%8.8zx, permissions = %s) => 0x%16.16" PRIx64,
page_byte_size,
GetPermissionsAsCString(permissions),
(uint64_t)addr);
@@ -429,9 +431,9 @@ AllocatedMemoryCache::AllocateMemory (si
if (block_sp)
addr = block_sp->ReserveBlock (byte_size);
}
- LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
- log->Printf ("AllocatedMemoryCache::AllocateMemory (byte_size = 0x%8.8zx, permissions = %s) => 0x%16.16llx", byte_size, GetPermissionsAsCString(permissions), (uint64_t)addr);
+ log->Printf ("AllocatedMemoryCache::AllocateMemory (byte_size = 0x%8.8zx, permissions = %s) => 0x%16.16" PRIx64, byte_size, GetPermissionsAsCString(permissions), (uint64_t)addr);
return addr;
}
@@ -450,9 +452,9 @@ AllocatedMemoryCache::DeallocateMemory (
break;
}
}
- LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
- log->Printf("AllocatedMemoryCache::DeallocateMemory (addr = 0x%16.16llx) => %i", (uint64_t)addr, success);
+ log->Printf("AllocatedMemoryCache::DeallocateMemory (addr = 0x%16.16" PRIx64 ") => %i", (uint64_t)addr, success);
return success;
}
More information about the llvm-branch-commits
mailing list