Vendor import of lldb release_38 branch r260756:
https://llvm.org/svn/llvm-project/lldb/branches/release_38@260756
This commit is contained in:
parent
e195173fdf
commit
2fc5d2d1df
8
Makefile
8
Makefile
@ -88,14 +88,6 @@ EXTRA_OPTIONS += -Wno-sign-compare
|
||||
|
||||
ifeq ($(IS_TOP_LEVEL),1)
|
||||
|
||||
ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT))
|
||||
$(RecursiveTargets)::
|
||||
$(Verb) if [ ! -f test/Makefile ]; then \
|
||||
$(MKDIR) test; \
|
||||
$(CP) $(PROJ_SRC_DIR)/test/Makefile test/Makefile; \
|
||||
fi
|
||||
endif
|
||||
|
||||
test::
|
||||
@ $(MAKE) -C test
|
||||
|
||||
|
@ -60,6 +60,9 @@ class LLDB_API SBInstruction
|
||||
bool
|
||||
DoesBranch ();
|
||||
|
||||
bool
|
||||
HasDelaySlot ();
|
||||
|
||||
void
|
||||
Print (FILE *out);
|
||||
|
||||
|
@ -1216,6 +1216,25 @@ namespace lldb_private {
|
||||
}
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
FindEntryIndexesThatContain(B addr, std::vector<uint32_t> &indexes) const
|
||||
{
|
||||
#ifdef ASSERT_RANGEMAP_ARE_SORTED
|
||||
assert (IsSorted());
|
||||
#endif
|
||||
|
||||
if (!m_entries.empty())
|
||||
{
|
||||
typename Collection::const_iterator pos;
|
||||
for (const auto &entry : m_entries)
|
||||
{
|
||||
if (entry.Contains(addr))
|
||||
indexes.push_back(entry.data);
|
||||
}
|
||||
}
|
||||
return indexes.size() ;
|
||||
}
|
||||
|
||||
Entry *
|
||||
FindEntryThatContains (B addr)
|
||||
|
@ -81,6 +81,7 @@ class Symtab
|
||||
Symbol * FindFirstSymbolWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility);
|
||||
Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes);
|
||||
Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr);
|
||||
void ForEachSymbolContainingFileAddress(lldb::addr_t file_addr, std::function<bool(Symbol *)> const &callback);
|
||||
size_t FindFunctionSymbols (const ConstString &name, uint32_t name_type_mask, SymbolContextList& sc_list);
|
||||
void CalculateSymbolSizes ();
|
||||
|
||||
|
@ -65,5 +65,6 @@ def test_signed_char(self):
|
||||
@expectedFailurei386("llvm.org/pr23069")
|
||||
@expectedFailurex86_64("llvm.org/pr23069")
|
||||
@expectedFailureWindows("llvm.org/pr21765")
|
||||
@expectedFailureAll(bugnumber="llvm.org/pr23069", triple = 'mips*')
|
||||
def test_unsigned_char(self):
|
||||
self.do_test(dictionary={'CFLAGS_EXTRAS': '-funsigned-char'})
|
||||
|
@ -0,0 +1,6 @@
|
||||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
@ -0,0 +1,84 @@
|
||||
"""
|
||||
Test specific to MIPS
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import os, time
|
||||
import re
|
||||
import unittest2
|
||||
import lldb
|
||||
import lldbsuite.test.lldbutil as lldbutil
|
||||
from lldbsuite.test.lldbtest import *
|
||||
|
||||
class AvoidBreakpointInDelaySlotAPITestCase(TestBase):
|
||||
|
||||
mydir = TestBase.compute_mydir(__file__)
|
||||
|
||||
@skipUnlessArch(archs=re.compile('mips*'))
|
||||
def test(self):
|
||||
self.build()
|
||||
exe = os.path.join(os.getcwd(), "a.out")
|
||||
self.expect("file " + exe,
|
||||
patterns = [ "Current executable set to .*a.out.*" ])
|
||||
|
||||
# Create a target by the debugger.
|
||||
target = self.dbg.CreateTarget(exe)
|
||||
self.assertTrue(target, VALID_TARGET)
|
||||
|
||||
breakpoint = target.BreakpointCreateByName('main', 'a.out')
|
||||
self.assertTrue(breakpoint and
|
||||
breakpoint.GetNumLocations() == 1,
|
||||
VALID_BREAKPOINT)
|
||||
|
||||
# Now launch the process, and do not stop at entry point.
|
||||
process = target.LaunchSimple (None, None, self.get_process_working_directory())
|
||||
self.assertTrue(process, PROCESS_IS_VALID)
|
||||
|
||||
list = target.FindFunctions('foo', lldb.eFunctionNameTypeAuto)
|
||||
self.assertTrue(list.GetSize() == 1)
|
||||
sc = list.GetContextAtIndex(0)
|
||||
self.assertTrue(sc.GetSymbol().GetName() == "foo")
|
||||
function = sc.GetFunction()
|
||||
self.assertTrue(function)
|
||||
self.function(function, target)
|
||||
|
||||
def function (self, function, target):
|
||||
"""Iterate over instructions in function and place a breakpoint on delay slot instruction"""
|
||||
# Get the list of all instructions in the function
|
||||
insts = function.GetInstructions(target)
|
||||
print(insts)
|
||||
i = 0
|
||||
for inst in insts:
|
||||
if (inst.HasDelaySlot()):
|
||||
# Remember the address of branch instruction.
|
||||
branchinstaddress = inst.GetAddress().GetLoadAddress(target)
|
||||
|
||||
# Get next instruction i.e delay slot instruction.
|
||||
delayinst = insts.GetInstructionAtIndex(i+1)
|
||||
delayinstaddr = delayinst.GetAddress().GetLoadAddress(target)
|
||||
|
||||
# Set breakpoint on delay slot instruction
|
||||
breakpoint = target.BreakpointCreateByAddress(delayinstaddr)
|
||||
|
||||
# Verify the breakpoint.
|
||||
self.assertTrue(breakpoint and
|
||||
breakpoint.GetNumLocations() == 1,
|
||||
VALID_BREAKPOINT)
|
||||
# Get the location from breakpoint
|
||||
location = breakpoint.GetLocationAtIndex(0)
|
||||
|
||||
# Get the address where breakpoint is actually set.
|
||||
bpaddr = location.GetLoadAddress()
|
||||
|
||||
# Breakpoint address should be adjusted to the address of branch instruction.
|
||||
self.assertTrue(branchinstaddress == bpaddr)
|
||||
i += 1
|
||||
else:
|
||||
i += 1
|
||||
|
||||
if __name__ == '__main__':
|
||||
import atexit
|
||||
lldb.SBDebugger.Initialize()
|
||||
atexit.register(lambda: lldb.SBDebugger.Terminate())
|
||||
unittest2.main()
|
@ -0,0 +1,21 @@
|
||||
#include <stdio.h>
|
||||
|
||||
foo (int a, int b)
|
||||
{
|
||||
int c;
|
||||
if (a<=b)
|
||||
c=b-a;
|
||||
else
|
||||
c=b+a;
|
||||
return c;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int a=7, b=8, c;
|
||||
|
||||
c = foo(a, b);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -633,6 +633,14 @@ def check_list_or_lambda(list_or_lambda, value):
|
||||
else:
|
||||
return list_or_lambda is None or value is None or list_or_lambda == value
|
||||
|
||||
def matchArchitectures(archs, actual_arch):
|
||||
retype = type(re.compile('hello, world'))
|
||||
list_passes = isinstance(archs, list) and actual_arch in archs
|
||||
basestring_passes = isinstance(archs, six.string_types) and actual_arch == archs
|
||||
regex_passes = isinstance(archs, retype) and re.match(archs, actual_arch)
|
||||
|
||||
return (list_passes or basestring_passes or regex_passes)
|
||||
|
||||
# provide a function to xfail on defined oslist, compiler version, and archs
|
||||
# if none is specified for any argument, that argument won't be checked and thus means for all
|
||||
# for example,
|
||||
@ -1026,7 +1034,7 @@ def skipUnlessHostPlatform(oslist):
|
||||
return unittest2.skipUnless(getHostPlatform() in oslist,
|
||||
"requires on of %s" % (", ".join(oslist)))
|
||||
|
||||
def skipUnlessArch(archlist):
|
||||
def skipUnlessArch(archs):
|
||||
"""Decorate the item to skip tests unless running on one of the listed architectures."""
|
||||
def myImpl(func):
|
||||
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
|
||||
@ -1035,9 +1043,8 @@ def myImpl(func):
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
self = args[0]
|
||||
if self.getArchitecture() not in archlist:
|
||||
self.skipTest("skipping for architecture %s (requires one of %s)" %
|
||||
(self.getArchitecture(), ", ".join(archlist)))
|
||||
if not matchArchitectures(archs, self.getArchitecture()):
|
||||
self.skipTest("skipping for architecture %s" % (self.getArchitecture()))
|
||||
else:
|
||||
func(*args, **kwargs)
|
||||
return wrapper
|
||||
|
@ -24,7 +24,6 @@ def setUp(self):
|
||||
self.line2 = line_number('main.c', '// Find the line number for breakpoint 2 here.')
|
||||
|
||||
@add_test_categories(['pyapi'])
|
||||
@expectedFailureWindows("llvm.org/pr24778")
|
||||
def test(self):
|
||||
"""Exercise some SBSymbol and SBAddress APIs."""
|
||||
self.build()
|
||||
|
@ -22,6 +22,10 @@ def setUp(self):
|
||||
self.line = line_number('main.cpp', '// Set break point at this line.')
|
||||
|
||||
@expectedFailureAll("llvm.org/pr23043", ["linux"], archs=["i386"]) # We are unable to produce a backtrace of the main thread when the thread is blocked in fgets
|
||||
|
||||
#The __thread_start function in libc doesn't contain any epilogue and prologue instructions
|
||||
#hence unwinding fail when we are stopped in __thread_start
|
||||
@expectedFailureAll(triple = 'mips*')
|
||||
@expectedFailureWindows("llvm.org/pr24778")
|
||||
@add_test_categories(['pyapi'])
|
||||
def test_stack_traces(self):
|
||||
|
@ -51,6 +51,9 @@ public:
|
||||
bool
|
||||
DoesBranch ();
|
||||
|
||||
bool
|
||||
HasDelaySlot ();
|
||||
|
||||
void
|
||||
Print (FILE *out);
|
||||
|
||||
|
@ -160,6 +160,14 @@ SBInstruction::DoesBranch ()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
SBInstruction::HasDelaySlot ()
|
||||
{
|
||||
if (m_opaque_sp)
|
||||
return m_opaque_sp->HasDelaySlot ();
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
SBInstruction::SetOpaque (const lldb::InstructionSP &inst_sp)
|
||||
{
|
||||
|
@ -559,7 +559,18 @@ Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve
|
||||
Symtab *symtab = sym_vendor->GetSymtab();
|
||||
if (symtab && so_addr.IsSectionOffset())
|
||||
{
|
||||
sc.symbol = symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
|
||||
Symbol *matching_symbol = nullptr;
|
||||
|
||||
symtab->ForEachSymbolContainingFileAddress(so_addr.GetFileAddress(),
|
||||
[&matching_symbol](Symbol *symbol) -> bool {
|
||||
if (symbol->GetType() != eSymbolTypeInvalid)
|
||||
{
|
||||
matching_symbol = symbol;
|
||||
return false; // Stop iterating
|
||||
}
|
||||
return true; // Keep iterating
|
||||
});
|
||||
sc.symbol = matching_symbol;
|
||||
if (!sc.symbol &&
|
||||
resolve_scope & eSymbolContextFunction && !(resolved_flags & eSymbolContextFunction))
|
||||
{
|
||||
|
@ -35,12 +35,12 @@ using namespace lldb_private;
|
||||
|
||||
static char ID;
|
||||
|
||||
#define VALID_POINTER_CHECK_NAME "$__lldb_valid_pointer_check"
|
||||
#define VALID_POINTER_CHECK_NAME "_$__lldb_valid_pointer_check"
|
||||
#define VALID_OBJC_OBJECT_CHECK_NAME "$__lldb_objc_object_check"
|
||||
|
||||
static const char g_valid_pointer_check_text[] =
|
||||
"extern \"C\" void\n"
|
||||
"$__lldb_valid_pointer_check (unsigned char *$__lldb_arg_ptr)\n"
|
||||
"_$__lldb_valid_pointer_check (unsigned char *$__lldb_arg_ptr)\n"
|
||||
"{\n"
|
||||
" unsigned char $__lldb_local_val = *$__lldb_arg_ptr;\n"
|
||||
"}";
|
||||
|
@ -242,16 +242,27 @@ ABISysV_mips::PrepareTrivialCall (Thread &thread,
|
||||
const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
|
||||
const RegisterInfo *ra_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
|
||||
const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0);
|
||||
const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0);
|
||||
|
||||
if (log)
|
||||
log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
|
||||
log->Printf("Writing R0: 0x%" PRIx64, (uint64_t)0);
|
||||
|
||||
/* Write r0 with 0, in case we are stopped in syscall,
|
||||
* such setting prevents automatic decrement of the PC.
|
||||
* This clears the bug 23659 for MIPS.
|
||||
*/
|
||||
if (!reg_ctx->WriteRegisterFromUnsigned (r0_info, (uint64_t)0))
|
||||
return false;
|
||||
|
||||
if (log)
|
||||
log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
|
||||
|
||||
// Set "sp" to the requested value
|
||||
if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_info, sp))
|
||||
return false;
|
||||
|
||||
if (log)
|
||||
log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
|
||||
log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
|
||||
|
||||
// Set "ra" to the return address
|
||||
if (!reg_ctx->WriteRegisterFromUnsigned (ra_reg_info, return_addr))
|
||||
|
@ -207,16 +207,27 @@ ABISysV_mips64::PrepareTrivialCall (Thread &thread,
|
||||
const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
|
||||
const RegisterInfo *ra_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
|
||||
const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0);
|
||||
const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0);
|
||||
|
||||
if (log)
|
||||
log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
|
||||
log->Printf("Writing R0: 0x%" PRIx64, (uint64_t)0);
|
||||
|
||||
/* Write r0 with 0, in case we are stopped in syscall,
|
||||
* such setting prevents automatic decrement of the PC.
|
||||
* This clears the bug 23659 for MIPS.
|
||||
*/
|
||||
if (!reg_ctx->WriteRegisterFromUnsigned (r0_info, (uint64_t)0))
|
||||
return false;
|
||||
|
||||
if (log)
|
||||
log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
|
||||
|
||||
// Set "sp" to the requested value
|
||||
if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_info, sp))
|
||||
return false;
|
||||
|
||||
if (log)
|
||||
log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
|
||||
log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
|
||||
|
||||
// Set "ra" to the return address
|
||||
if (!reg_ctx->WriteRegisterFromUnsigned (ra_reg_info, return_addr))
|
||||
|
@ -169,6 +169,18 @@ ObjectFilePECOFF::MagicBytesMatch (DataBufferSP& data_sp)
|
||||
return magic == IMAGE_DOS_SIGNATURE;
|
||||
}
|
||||
|
||||
lldb::SymbolType
|
||||
ObjectFilePECOFF::MapSymbolType(uint16_t coff_symbol_type)
|
||||
{
|
||||
// TODO: We need to complete this mapping of COFF symbol types to LLDB ones.
|
||||
// For now, here's a hack to make sure our function have types.
|
||||
const auto complex_type = coff_symbol_type >> llvm::COFF::SCT_COMPLEX_TYPE_SHIFT;
|
||||
if (complex_type == llvm::COFF::IMAGE_SYM_DTYPE_FUNCTION)
|
||||
{
|
||||
return lldb::eSymbolTypeCode;
|
||||
}
|
||||
return lldb::eSymbolTypeInvalid;
|
||||
}
|
||||
|
||||
ObjectFilePECOFF::ObjectFilePECOFF (const lldb::ModuleSP &module_sp,
|
||||
DataBufferSP& data_sp,
|
||||
@ -534,8 +546,8 @@ ObjectFilePECOFF::GetSymtab()
|
||||
{
|
||||
const uint32_t symbol_size = 18;
|
||||
const uint32_t addr_byte_size = GetAddressByteSize ();
|
||||
const size_t symbol_data_size = num_syms * symbol_size;
|
||||
// Include the 4 bytes string table size at the end of the symbols
|
||||
const size_t symbol_data_size = num_syms * symbol_size;
|
||||
// Include the 4-byte string table size at the end of the symbols
|
||||
DataBufferSP symtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff, symbol_data_size + 4));
|
||||
DataExtractor symtab_data (symtab_data_sp, GetByteOrder(), addr_byte_size);
|
||||
lldb::offset_t offset = symbol_data_size;
|
||||
@ -556,8 +568,8 @@ ObjectFilePECOFF::GetSymtab()
|
||||
coff_symbol_t symbol;
|
||||
const uint32_t symbol_offset = offset;
|
||||
const char *symbol_name_cstr = NULL;
|
||||
// If the first 4 bytes of the symbol string are zero, then we
|
||||
// it is followed by a 4 byte string table offset. Else these
|
||||
// If the first 4 bytes of the symbol string are zero, then they
|
||||
// are followed by a 4-byte string table offset. Else these
|
||||
// 8 bytes contain the symbol name
|
||||
if (symtab_data.GetU32 (&offset) == 0)
|
||||
{
|
||||
@ -586,6 +598,7 @@ ObjectFilePECOFF::GetSymtab()
|
||||
{
|
||||
Address symbol_addr(sect_list->GetSectionAtIndex(symbol.sect-1), symbol.value);
|
||||
symbols[i].GetAddressRef() = symbol_addr;
|
||||
symbols[i].SetType(MapSymbolType(symbol.type));
|
||||
}
|
||||
|
||||
if (symbol.naux > 0)
|
||||
|
@ -101,7 +101,10 @@ class ObjectFilePECOFF :
|
||||
|
||||
static bool
|
||||
MagicBytesMatch (lldb::DataBufferSP& data_sp);
|
||||
|
||||
|
||||
static lldb::SymbolType
|
||||
MapSymbolType(uint16_t coff_symbol_type);
|
||||
|
||||
bool
|
||||
ParseHeader() override;
|
||||
|
||||
@ -116,7 +119,7 @@ class ObjectFilePECOFF :
|
||||
|
||||
uint32_t
|
||||
GetAddressByteSize() const override;
|
||||
|
||||
|
||||
// virtual lldb_private::AddressClass
|
||||
// GetAddressClass (lldb::addr_t file_addr);
|
||||
|
||||
|
@ -8,6 +8,25 @@
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
LLDB_LEVEL := ../../../..
|
||||
LEVEL := $(LLDB_LEVEL)/../..
|
||||
|
||||
include $(LEVEL)/Makefile.config
|
||||
|
||||
SOURCES += PlatformDarwin.cpp \
|
||||
PlatformDarwinKernel.cpp \
|
||||
PlatformMacOSX.cpp \
|
||||
PlatformRemoteiOS.cpp \
|
||||
PlatformRemoteAppleTV.cpp \
|
||||
PlatformRemoteAppleWatch.cpp
|
||||
|
||||
ifeq ($(HOST_OS),Darwin)
|
||||
SOURCES += PlatformAppleSimulator.cpp \
|
||||
PlatformiOSSimulator.cpp \
|
||||
PlatformiOSSimulatorCoreSimulatorSupport.mm \
|
||||
PlatformAppleTVSimulator.cpp \
|
||||
PlatformAppleWatchSimulator.cpp
|
||||
endif
|
||||
|
||||
LIBRARYNAME := lldbPluginPlatformMacOSX
|
||||
BUILD_ARCHIVE = 1
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Core/UniqueCStringMap.h"
|
||||
#include "lldb/Core/ValueObject.h"
|
||||
#include "lldb/DataFormatters/StringPrinter.h"
|
||||
@ -1268,13 +1269,115 @@ GoASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, const
|
||||
//----------------------------------------------------------------------
|
||||
// Dumping types
|
||||
//----------------------------------------------------------------------
|
||||
#define DEPTH_INCREMENT 2
|
||||
|
||||
void
|
||||
GoASTContext::DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format,
|
||||
const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size,
|
||||
const DataExtractor &data, lldb::offset_t data_byte_offset, size_t data_byte_size,
|
||||
uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types, bool show_summary,
|
||||
bool verbose, uint32_t depth)
|
||||
{
|
||||
assert(false);
|
||||
if (IsTypedefType(type))
|
||||
type = GetTypedefedType(type).GetOpaqueQualType();
|
||||
if (!type)
|
||||
return;
|
||||
GoType *t = static_cast<GoType *>(type);
|
||||
|
||||
if (GoStruct *st = t->GetStruct())
|
||||
{
|
||||
if (GetCompleteType(type))
|
||||
{
|
||||
uint32_t field_idx = 0;
|
||||
for (auto* field = st->GetField(field_idx); field != nullptr; field_idx++)
|
||||
{
|
||||
// Print the starting squiggly bracket (if this is the
|
||||
// first member) or comma (for member 2 and beyond) for
|
||||
// the struct/union/class member.
|
||||
if (field_idx == 0)
|
||||
s->PutChar('{');
|
||||
else
|
||||
s->PutChar(',');
|
||||
|
||||
// Indent
|
||||
s->Printf("\n%*s", depth + DEPTH_INCREMENT, "");
|
||||
|
||||
// Print the member type if requested
|
||||
if (show_types)
|
||||
{
|
||||
ConstString field_type_name = field->m_type.GetTypeName();
|
||||
s->Printf("(%s) ", field_type_name.AsCString());
|
||||
}
|
||||
// Print the member name and equal sign
|
||||
s->Printf("%s = ", field->m_name.AsCString());
|
||||
|
||||
|
||||
// Dump the value of the member
|
||||
CompilerType field_type = field->m_type;
|
||||
field_type.DumpValue (exe_ctx,
|
||||
s, // Stream to dump to
|
||||
field_type.GetFormat(), // The format with which to display the member
|
||||
data, // Data buffer containing all bytes for this type
|
||||
data_byte_offset + field->m_byte_offset,// Offset into "data" where to grab value from
|
||||
field->m_type.GetByteSize(exe_ctx->GetBestExecutionContextScope()), // Size of this type in bytes
|
||||
0, // Bitfield bit size
|
||||
0, // 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 + DEPTH_INCREMENT); // Scope depth for any types that have children
|
||||
}
|
||||
|
||||
// Indent the trailing squiggly bracket
|
||||
if (field_idx > 0)
|
||||
s->Printf("\n%*s}", depth, "");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (GoArray *a = t->GetArray()) {
|
||||
CompilerType element_clang_type = a->GetElementType();
|
||||
lldb::Format element_format = element_clang_type.GetFormat();
|
||||
uint32_t element_byte_size = element_clang_type.GetByteSize(exe_ctx->GetBestExecutionContextScope());
|
||||
|
||||
uint64_t element_idx;
|
||||
for (element_idx = 0; element_idx < a->GetLength(); ++element_idx)
|
||||
{
|
||||
// Print the starting squiggly bracket (if this is the
|
||||
// first member) or comman (for member 2 and beyong) for
|
||||
// the struct/union/class member.
|
||||
if (element_idx == 0)
|
||||
s->PutChar('{');
|
||||
else
|
||||
s->PutChar(',');
|
||||
|
||||
// Indent and print the index
|
||||
s->Printf("\n%*s[%" PRIu64 "] ", depth + DEPTH_INCREMENT, "", element_idx);
|
||||
|
||||
// Figure out the field offset within the current struct/union/class type
|
||||
uint64_t element_offset = element_idx * element_byte_size;
|
||||
|
||||
// Dump the value of the member
|
||||
element_clang_type.DumpValue (exe_ctx,
|
||||
s, // Stream to dump to
|
||||
element_format, // The format with which to display the element
|
||||
data, // Data buffer containing all bytes for this type
|
||||
data_byte_offset + element_offset,// Offset into "data" where to grab value from
|
||||
element_byte_size, // Size of this type in bytes
|
||||
0, // Bitfield bit size
|
||||
0, // 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 + DEPTH_INCREMENT); // Scope depth for any types that have children
|
||||
}
|
||||
|
||||
// Indent the trailing squiggly bracket
|
||||
if (element_idx > 0)
|
||||
s->Printf("\n%*s}", depth, "");
|
||||
}
|
||||
|
||||
if (show_summary)
|
||||
DumpSummary (type, exe_ctx, s, data, data_byte_offset, data_byte_size);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1371,19 +1474,55 @@ void
|
||||
GoASTContext::DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, const DataExtractor &data,
|
||||
lldb::offset_t data_offset, size_t data_byte_size)
|
||||
{
|
||||
assert(false);
|
||||
if (type && GoType::KIND_STRING == static_cast<GoType *>(type)->GetGoKind())
|
||||
{
|
||||
// TODO(ribrdb): read length and data
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GoASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type)
|
||||
{
|
||||
assert(false);
|
||||
} // Dump to stdout
|
||||
// Dump to stdout
|
||||
StreamFile s (stdout, false);
|
||||
DumpTypeDescription (type, &s);
|
||||
}
|
||||
|
||||
void
|
||||
GoASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type, Stream *s)
|
||||
{
|
||||
assert(false);
|
||||
if (!type)
|
||||
return;
|
||||
ConstString name = GetTypeName(type);
|
||||
GoType *t = static_cast<GoType *>(type);
|
||||
|
||||
if (GoStruct *st = t->GetStruct())
|
||||
{
|
||||
if (GetCompleteType(type))
|
||||
{
|
||||
if (NULL == strchr(name.AsCString(), '{'))
|
||||
s->Printf("type %s ", name.AsCString());
|
||||
s->PutCString("struct {");
|
||||
if (st->GetNumFields() == 0) {
|
||||
s->PutChar('}');
|
||||
return;
|
||||
}
|
||||
s->IndentMore();
|
||||
uint32_t field_idx = 0;
|
||||
for (auto* field = st->GetField(field_idx); field != nullptr; field_idx++)
|
||||
{
|
||||
s->PutChar('\n');
|
||||
s->Indent();
|
||||
s->Printf("%s %s", field->m_name.AsCString(), field->m_type.GetTypeName().AsCString());
|
||||
}
|
||||
s->IndentLess();
|
||||
s->PutChar('\n');
|
||||
s->Indent("}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
s->PutCString(name.AsCString());
|
||||
}
|
||||
|
||||
CompilerType
|
||||
|
@ -1070,6 +1070,26 @@ Symtab::FindSymbolContainingFileAddress (addr_t file_addr)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
Symtab::ForEachSymbolContainingFileAddress(addr_t file_addr, std::function<bool(Symbol *)> const &callback)
|
||||
{
|
||||
Mutex::Locker locker (m_mutex);
|
||||
|
||||
if (!m_file_addr_to_index_computed)
|
||||
InitAddressIndexes();
|
||||
|
||||
std::vector<uint32_t> all_addr_indexes;
|
||||
|
||||
// Get all symbols with file_addr
|
||||
const size_t addr_match_count = m_file_addr_to_index.FindEntryIndexesThatContain(file_addr, all_addr_indexes);
|
||||
|
||||
for (size_t i = 0; i < addr_match_count; ++i)
|
||||
{
|
||||
if (!callback(SymbolAtIndex(all_addr_indexes[i])))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Symtab::SymbolIndicesToSymbolContextList (std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list)
|
||||
{
|
||||
|
@ -2442,18 +2442,18 @@ Target::GetBreakableLoadAddress (lldb::addr_t addr)
|
||||
SymbolContext sc;
|
||||
uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
|
||||
temp_addr_module_sp->ResolveSymbolContextForAddress(resolved_addr, resolve_scope, sc);
|
||||
Address sym_addr;
|
||||
if (sc.function)
|
||||
{
|
||||
function_start = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(this);
|
||||
if (function_start == LLDB_INVALID_ADDRESS)
|
||||
function_start = sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
|
||||
}
|
||||
sym_addr = sc.function->GetAddressRange().GetBaseAddress();
|
||||
else if (sc.symbol)
|
||||
{
|
||||
Address sym_addr = sc.symbol->GetAddress();
|
||||
sym_addr = sc.symbol->GetAddress();
|
||||
|
||||
function_start = sym_addr.GetLoadAddress(this);
|
||||
if (function_start == LLDB_INVALID_ADDRESS)
|
||||
function_start = sym_addr.GetFileAddress();
|
||||
}
|
||||
current_offset = addr - function_start;
|
||||
|
||||
if (function_start)
|
||||
current_offset = addr - function_start;
|
||||
}
|
||||
|
||||
// If breakpoint address is start of function then we dont have to do anything.
|
||||
|
@ -33,24 +33,19 @@ add_lldb_executable(lldb-server
|
||||
LLDBServerUtilities.cpp
|
||||
)
|
||||
|
||||
if (BUILD_SHARED_LIBS )
|
||||
target_link_libraries(lldb-server liblldb)
|
||||
target_link_libraries(lldb-server ${LLDB_SYSTEM_LIBS})
|
||||
# The Darwin linker doesn't understand --start-group/--end-group.
|
||||
if (LLDB_LINKER_SUPPORTS_GROUPS)
|
||||
target_link_libraries(lldb-server
|
||||
-Wl,--start-group ${LLDB_USED_LIBS} -Wl,--end-group)
|
||||
target_link_libraries(lldb-server
|
||||
-Wl,--start-group ${CLANG_USED_LIBS} -Wl,--end-group)
|
||||
else()
|
||||
# The Darwin linker doesn't understand --start-group/--end-group.
|
||||
if (LLDB_LINKER_SUPPORTS_GROUPS)
|
||||
target_link_libraries(lldb-server
|
||||
-Wl,--start-group ${LLDB_USED_LIBS} -Wl,--end-group)
|
||||
target_link_libraries(lldb-server
|
||||
-Wl,--start-group ${CLANG_USED_LIBS} -Wl,--end-group)
|
||||
else()
|
||||
target_link_libraries(lldb-server ${LLDB_USED_LIBS})
|
||||
target_link_libraries(lldb-server ${CLANG_USED_LIBS})
|
||||
endif()
|
||||
llvm_config(lldb-server ${LLVM_LINK_COMPONENTS})
|
||||
|
||||
target_link_libraries(lldb-server ${LLDB_SYSTEM_LIBS})
|
||||
target_link_libraries(lldb-server ${LLDB_USED_LIBS})
|
||||
target_link_libraries(lldb-server ${CLANG_USED_LIBS})
|
||||
endif()
|
||||
llvm_config(lldb-server ${LLVM_LINK_COMPONENTS})
|
||||
|
||||
target_link_libraries(lldb-server ${LLDB_SYSTEM_LIBS})
|
||||
|
||||
set_target_properties(lldb-server PROPERTIES VERSION ${LLDB_VERSION})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user