[lldb] Refactor away UB in SBValue::GetLoadAddress (#141799)
The problem was in calling GetLoadAddress on a value in the error state, where `ValueObject::GetLoadAddress` could end up accessing the uninitialized "address type" by-ref return value from `GetAddressOf`. This probably happened because each function expected the other to initialize it. We can guarantee initialization by turning this into a proper return value. I've added a test, but it only (reliably) crashes if lldb is built with ubsan.
This commit is contained in:
parent
246d5da7fe
commit
e9fad0e91c
@ -573,10 +573,14 @@ public:
|
||||
/// child as well.
|
||||
void SetName(ConstString name) { m_name = name; }
|
||||
|
||||
virtual lldb::addr_t GetAddressOf(bool scalar_is_load_address = true,
|
||||
AddressType *address_type = nullptr);
|
||||
struct AddrAndType {
|
||||
lldb::addr_t address = LLDB_INVALID_ADDRESS;
|
||||
AddressType type = eAddressTypeInvalid;
|
||||
};
|
||||
|
||||
lldb::addr_t GetPointerValue(AddressType *address_type = nullptr);
|
||||
virtual AddrAndType GetAddressOf(bool scalar_is_load_address = true);
|
||||
|
||||
AddrAndType GetPointerValue();
|
||||
|
||||
lldb::ValueObjectSP GetSyntheticChild(ConstString key) const;
|
||||
|
||||
|
@ -86,8 +86,7 @@ public:
|
||||
|
||||
lldb::ValueObjectSP AddressOf(Status &error) override;
|
||||
|
||||
lldb::addr_t GetAddressOf(bool scalar_is_load_address = true,
|
||||
AddressType *address_type = nullptr) override;
|
||||
AddrAndType GetAddressOf(bool scalar_is_load_address = true) override;
|
||||
|
||||
size_t GetPointeeData(DataExtractor &data, uint32_t item_idx = 0,
|
||||
uint32_t item_count = 1) override;
|
||||
|
@ -48,8 +48,7 @@ public:
|
||||
|
||||
lldb::ValueObjectSP AddressOf(Status &error) override;
|
||||
|
||||
lldb::addr_t GetAddressOf(bool scalar_is_load_address = true,
|
||||
AddressType *address_type = nullptr) override;
|
||||
AddrAndType GetAddressOf(bool scalar_is_load_address = true) override;
|
||||
|
||||
size_t GetPointeeData(DataExtractor &data, uint32_t item_idx = 0,
|
||||
uint32_t item_count = 1) override;
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define LLDB_VALUEOBJECT_VALUEOBJECTCONSTRESULTIMPL_H
|
||||
|
||||
#include "lldb/Utility/ConstString.h"
|
||||
#include "lldb/ValueObject/ValueObject.h"
|
||||
#include "lldb/lldb-defines.h"
|
||||
#include "lldb/lldb-forward.h"
|
||||
#include "lldb/lldb-private-enumerations.h"
|
||||
@ -21,7 +22,6 @@ namespace lldb_private {
|
||||
class CompilerType;
|
||||
class DataExtractor;
|
||||
class Status;
|
||||
class ValueObject;
|
||||
} // namespace lldb_private
|
||||
|
||||
namespace lldb_private {
|
||||
@ -58,8 +58,8 @@ public:
|
||||
m_live_address_type = address_type;
|
||||
}
|
||||
|
||||
virtual lldb::addr_t GetAddressOf(bool scalar_is_load_address = true,
|
||||
AddressType *address_type = nullptr);
|
||||
virtual ValueObject::AddrAndType
|
||||
GetAddressOf(bool scalar_is_load_address = true);
|
||||
|
||||
virtual size_t GetPointeeData(DataExtractor &data, uint32_t item_idx = 0,
|
||||
uint32_t item_count = 1);
|
||||
|
@ -1336,10 +1336,8 @@ lldb::SBAddress SBValue::GetAddress() {
|
||||
if (value_sp) {
|
||||
TargetSP target_sp(value_sp->GetTargetSP());
|
||||
if (target_sp) {
|
||||
lldb::addr_t value = LLDB_INVALID_ADDRESS;
|
||||
const bool scalar_is_load_address = true;
|
||||
AddressType addr_type;
|
||||
value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type);
|
||||
auto [value, addr_type] =
|
||||
value_sp->GetAddressOf(/*scalar_is_load_address=*/true);
|
||||
if (addr_type == eAddressTypeFile) {
|
||||
ModuleSP module_sp(value_sp->GetModule());
|
||||
if (module_sp)
|
||||
|
@ -822,7 +822,6 @@ protected:
|
||||
|
||||
// We passed the sanity check for the command. Proceed to set the
|
||||
// watchpoint now.
|
||||
lldb::addr_t addr = 0;
|
||||
size_t size = 0;
|
||||
|
||||
VariableSP var_sp;
|
||||
@ -861,19 +860,7 @@ protected:
|
||||
|
||||
CompilerType compiler_type;
|
||||
|
||||
if (valobj_sp) {
|
||||
AddressType addr_type;
|
||||
addr = valobj_sp->GetAddressOf(false, &addr_type);
|
||||
if (addr_type == eAddressTypeLoad) {
|
||||
// We're in business.
|
||||
// Find out the size of this variable.
|
||||
size =
|
||||
m_option_watchpoint.watch_size.GetCurrentValue() == 0
|
||||
? llvm::expectedToOptional(valobj_sp->GetByteSize()).value_or(0)
|
||||
: m_option_watchpoint.watch_size.GetCurrentValue();
|
||||
}
|
||||
compiler_type = valobj_sp->GetCompilerType();
|
||||
} else {
|
||||
if (!valobj_sp) {
|
||||
const char *error_cstr = error.AsCString(nullptr);
|
||||
if (error_cstr)
|
||||
result.AppendError(error_cstr);
|
||||
@ -883,6 +870,16 @@ protected:
|
||||
command.GetArgumentAtIndex(0));
|
||||
return;
|
||||
}
|
||||
auto [addr, addr_type] = valobj_sp->GetAddressOf(false);
|
||||
if (addr_type == eAddressTypeLoad) {
|
||||
// We're in business.
|
||||
// Find out the size of this variable.
|
||||
size =
|
||||
m_option_watchpoint.watch_size.GetCurrentValue() == 0
|
||||
? llvm::expectedToOptional(valobj_sp->GetByteSize()).value_or(0)
|
||||
: m_option_watchpoint.watch_size.GetCurrentValue();
|
||||
}
|
||||
compiler_type = valobj_sp->GetCompilerType();
|
||||
|
||||
// Now it's time to create the watchpoint.
|
||||
uint32_t watch_type = 0;
|
||||
|
@ -24,8 +24,7 @@ using namespace lldb_private::formatters;
|
||||
bool lldb_private::formatters::CXXFunctionPointerSummaryProvider(
|
||||
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
|
||||
StreamString sstr;
|
||||
AddressType func_ptr_address_type = eAddressTypeInvalid;
|
||||
addr_t func_ptr_address = valobj.GetPointerValue(&func_ptr_address_type);
|
||||
auto [func_ptr_address, func_ptr_address_type] = valobj.GetPointerValue();
|
||||
if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS) {
|
||||
switch (func_ptr_address_type) {
|
||||
case eAddressTypeInvalid:
|
||||
|
@ -113,15 +113,16 @@ lldb_private::formatters::ExtractIndexFromString(const char *item_name) {
|
||||
|
||||
Address
|
||||
lldb_private::formatters::GetArrayAddressOrPointerValue(ValueObject &valobj) {
|
||||
lldb::addr_t data_addr = LLDB_INVALID_ADDRESS;
|
||||
AddressType type;
|
||||
ValueObject::AddrAndType data_addr;
|
||||
|
||||
if (valobj.IsPointerType())
|
||||
data_addr = valobj.GetPointerValue(&type);
|
||||
data_addr = valobj.GetPointerValue();
|
||||
else if (valobj.IsArrayType())
|
||||
data_addr = valobj.GetAddressOf(/*scalar_is_load_address=*/true, &type);
|
||||
if (data_addr != LLDB_INVALID_ADDRESS && type == eAddressTypeFile)
|
||||
return Address(data_addr, valobj.GetModule()->GetSectionList());
|
||||
data_addr = valobj.GetAddressOf(/*scalar_is_load_address=*/true);
|
||||
|
||||
return data_addr;
|
||||
if (data_addr.address != LLDB_INVALID_ADDRESS &&
|
||||
data_addr.type == eAddressTypeFile)
|
||||
return Address(data_addr.address, valobj.GetModule()->GetSectionList());
|
||||
|
||||
return data_addr.address;
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ bool TypeFormatImpl_Format::FormatObject(ValueObject *valobj,
|
||||
Status error;
|
||||
WritableDataBufferSP buffer_sp(
|
||||
new DataBufferHeap(max_len + 1, 0));
|
||||
Address address(valobj->GetPointerValue());
|
||||
Address address(valobj->GetPointerValue().address);
|
||||
target_sp->ReadCStringFromMemory(
|
||||
address, (char *)buffer_sp->GetBytes(), max_len, error);
|
||||
if (error.Success())
|
||||
|
@ -542,8 +542,7 @@ bool ValueObjectPrinter::ShouldPrintChildren(
|
||||
if (is_ptr || is_ref) {
|
||||
// We have a pointer or reference whose value is an address. Make sure
|
||||
// that address is not NULL
|
||||
AddressType ptr_address_type;
|
||||
if (valobj.GetPointerValue(&ptr_address_type) == 0)
|
||||
if (valobj.GetPointerValue().address == 0)
|
||||
return false;
|
||||
|
||||
const bool is_root_level = m_curr_depth == 0;
|
||||
|
@ -508,10 +508,8 @@ public:
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
AddressType address_type = eAddressTypeInvalid;
|
||||
const bool scalar_is_load_address = false;
|
||||
lldb::addr_t addr_of_valobj =
|
||||
valobj_sp->GetAddressOf(scalar_is_load_address, &address_type);
|
||||
valobj_sp->GetAddressOf(/*scalar_is_load_address=*/false).address;
|
||||
if (addr_of_valobj != LLDB_INVALID_ADDRESS) {
|
||||
Status write_error;
|
||||
map.WritePointerToMemory(load_addr, addr_of_valobj, write_error);
|
||||
|
@ -897,12 +897,13 @@ bool ClangUserExpression::AddArguments(ExecutionContext &exe_ctx,
|
||||
Status object_ptr_error;
|
||||
|
||||
if (m_ctx_obj) {
|
||||
AddressType address_type;
|
||||
object_ptr = m_ctx_obj->GetAddressOf(false, &address_type);
|
||||
if (object_ptr == LLDB_INVALID_ADDRESS ||
|
||||
address_type != eAddressTypeLoad)
|
||||
ValueObject::AddrAndType address = m_ctx_obj->GetAddressOf(false);
|
||||
if (address.address == LLDB_INVALID_ADDRESS ||
|
||||
address.type != eAddressTypeLoad)
|
||||
object_ptr_error = Status::FromErrorString("Can't get context object's "
|
||||
"debuggee address");
|
||||
else
|
||||
object_ptr = address.address;
|
||||
} else {
|
||||
if (m_in_cplusplus_method) {
|
||||
object_ptr =
|
||||
|
@ -32,8 +32,7 @@ static lldb::addr_t GetCoroFramePtrFromHandle(ValueObjectSP valobj_sp) {
|
||||
if (!ptr_sp->GetCompilerType().IsPointerType())
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
|
||||
AddressType addr_type;
|
||||
lldb::addr_t frame_ptr_addr = ptr_sp->GetPointerValue(&addr_type);
|
||||
auto [frame_ptr_addr, addr_type] = ptr_sp->GetPointerValue();
|
||||
if (!frame_ptr_addr || frame_ptr_addr == LLDB_INVALID_ADDRESS)
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
lldbassert(addr_type == AddressType::eAddressTypeLoad);
|
||||
|
@ -388,7 +388,7 @@ lldb::ValueObjectSP ListFrontEnd::GetChildAtIndex(uint32_t idx) {
|
||||
return lldb::ValueObjectSP();
|
||||
|
||||
// if we grabbed the __next_ pointer, then the child is one pointer deep-er
|
||||
lldb::addr_t addr = current_sp->GetParent()->GetPointerValue();
|
||||
lldb::addr_t addr = current_sp->GetParent()->GetPointerValue().address;
|
||||
addr = addr + 2 * process_sp->GetAddressByteSize();
|
||||
ExecutionContext exe_ctx(process_sp);
|
||||
current_sp =
|
||||
|
@ -240,16 +240,10 @@ VectorIteratorSyntheticFrontEnd::GetIndexOfChildWithName(ConstString name) {
|
||||
bool lldb_private::formatters::LibStdcppStringSummaryProvider(
|
||||
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
|
||||
const bool scalar_is_load_addr = true;
|
||||
AddressType addr_type;
|
||||
lldb::addr_t addr_of_string = LLDB_INVALID_ADDRESS;
|
||||
if (valobj.IsPointerOrReferenceType()) {
|
||||
Status error;
|
||||
ValueObjectSP pointee_sp = valobj.Dereference(error);
|
||||
if (pointee_sp && error.Success())
|
||||
addr_of_string = pointee_sp->GetAddressOf(scalar_is_load_addr, &addr_type);
|
||||
} else
|
||||
addr_of_string =
|
||||
valobj.GetAddressOf(scalar_is_load_addr, &addr_type);
|
||||
auto [addr_of_string, addr_type] =
|
||||
valobj.IsPointerOrReferenceType()
|
||||
? valobj.GetPointerValue()
|
||||
: valobj.GetAddressOf(scalar_is_load_addr);
|
||||
if (addr_of_string != LLDB_INVALID_ADDRESS) {
|
||||
switch (addr_type) {
|
||||
case eAddressTypeLoad: {
|
||||
@ -296,9 +290,7 @@ bool lldb_private::formatters::LibStdcppStringSummaryProvider(
|
||||
bool lldb_private::formatters::LibStdcppWStringSummaryProvider(
|
||||
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
|
||||
const bool scalar_is_load_addr = true;
|
||||
AddressType addr_type;
|
||||
lldb::addr_t addr_of_string =
|
||||
valobj.GetAddressOf(scalar_is_load_addr, &addr_type);
|
||||
auto [addr_of_string, addr_type] = valobj.GetAddressOf(scalar_is_load_addr);
|
||||
if (addr_of_string != LLDB_INVALID_ADDRESS) {
|
||||
switch (addr_type) {
|
||||
case eAddressTypeLoad: {
|
||||
|
@ -69,9 +69,8 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfo(
|
||||
LLDB_LOGF(log,
|
||||
"0x%16.16" PRIx64
|
||||
": static-type = '%s' has vtable symbol '%s'\n",
|
||||
in_value.GetPointerValue(),
|
||||
in_value.GetTypeName().GetCString(),
|
||||
symbol_name.str().c_str());
|
||||
in_value.GetPointerValue().address,
|
||||
in_value.GetTypeName().GetCString(), symbol_name.str().c_str());
|
||||
// We are a C++ class, that's good. Get the class name and look it
|
||||
// up:
|
||||
llvm::StringRef class_name = symbol_name;
|
||||
@ -111,7 +110,7 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfo(
|
||||
lldb::TypeSP type_sp;
|
||||
if (class_types.Empty()) {
|
||||
LLDB_LOGF(log, "0x%16.16" PRIx64 ": is not dynamic\n",
|
||||
in_value.GetPointerValue());
|
||||
in_value.GetPointerValue().address);
|
||||
return TypeAndOrName();
|
||||
}
|
||||
if (class_types.GetSize() == 1) {
|
||||
@ -119,13 +118,13 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfo(
|
||||
if (type_sp) {
|
||||
if (TypeSystemClang::IsCXXClassType(
|
||||
type_sp->GetForwardCompilerType())) {
|
||||
LLDB_LOGF(
|
||||
log,
|
||||
"0x%16.16" PRIx64
|
||||
": static-type = '%s' has dynamic type: uid={0x%" PRIx64
|
||||
"}, type-name='%s'\n",
|
||||
in_value.GetPointerValue(), in_value.GetTypeName().AsCString(),
|
||||
type_sp->GetID(), type_sp->GetName().GetCString());
|
||||
LLDB_LOGF(log,
|
||||
"0x%16.16" PRIx64
|
||||
": static-type = '%s' has dynamic type: uid={0x%" PRIx64
|
||||
"}, type-name='%s'\n",
|
||||
in_value.GetPointerValue().address,
|
||||
in_value.GetTypeName().AsCString(), type_sp->GetID(),
|
||||
type_sp->GetName().GetCString());
|
||||
type_info.SetTypeSP(type_sp);
|
||||
}
|
||||
}
|
||||
@ -135,14 +134,13 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfo(
|
||||
for (i = 0; i < class_types.GetSize(); i++) {
|
||||
type_sp = class_types.GetTypeAtIndex(i);
|
||||
if (type_sp) {
|
||||
LLDB_LOGF(
|
||||
log,
|
||||
"0x%16.16" PRIx64
|
||||
": static-type = '%s' has multiple matching dynamic "
|
||||
"types: uid={0x%" PRIx64 "}, type-name='%s'\n",
|
||||
in_value.GetPointerValue(),
|
||||
in_value.GetTypeName().AsCString(),
|
||||
type_sp->GetID(), type_sp->GetName().GetCString());
|
||||
LLDB_LOGF(log,
|
||||
"0x%16.16" PRIx64
|
||||
": static-type = '%s' has multiple matching dynamic "
|
||||
"types: uid={0x%" PRIx64 "}, type-name='%s'\n",
|
||||
in_value.GetPointerValue().address,
|
||||
in_value.GetTypeName().AsCString(), type_sp->GetID(),
|
||||
type_sp->GetName().GetCString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -152,14 +150,13 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfo(
|
||||
if (type_sp) {
|
||||
if (TypeSystemClang::IsCXXClassType(
|
||||
type_sp->GetForwardCompilerType())) {
|
||||
LLDB_LOGF(
|
||||
log,
|
||||
"0x%16.16" PRIx64 ": static-type = '%s' has multiple "
|
||||
"matching dynamic types, picking "
|
||||
"this one: uid={0x%" PRIx64 "}, type-name='%s'\n",
|
||||
in_value.GetPointerValue(),
|
||||
in_value.GetTypeName().AsCString(),
|
||||
type_sp->GetID(), type_sp->GetName().GetCString());
|
||||
LLDB_LOGF(log,
|
||||
"0x%16.16" PRIx64 ": static-type = '%s' has multiple "
|
||||
"matching dynamic types, picking "
|
||||
"this one: uid={0x%" PRIx64 "}, type-name='%s'\n",
|
||||
in_value.GetPointerValue().address,
|
||||
in_value.GetTypeName().AsCString(), type_sp->GetID(),
|
||||
type_sp->GetName().GetCString());
|
||||
type_info.SetTypeSP(type_sp);
|
||||
}
|
||||
}
|
||||
@ -170,7 +167,7 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfo(
|
||||
"0x%16.16" PRIx64
|
||||
": static-type = '%s' has multiple matching dynamic "
|
||||
"types, didn't find a C++ match\n",
|
||||
in_value.GetPointerValue(),
|
||||
in_value.GetPointerValue().address,
|
||||
in_value.GetTypeName().AsCString());
|
||||
}
|
||||
}
|
||||
@ -230,13 +227,10 @@ llvm::Expected<LanguageRuntime::VTableInfo>
|
||||
return llvm::createStringError(std::errc::invalid_argument,
|
||||
"invalid process");
|
||||
|
||||
AddressType address_type;
|
||||
lldb::addr_t original_ptr = LLDB_INVALID_ADDRESS;
|
||||
if (type.IsPointerOrReferenceType())
|
||||
original_ptr = in_value.GetPointerValue(&address_type);
|
||||
else
|
||||
original_ptr = in_value.GetAddressOf(/*scalar_is_load_address=*/true,
|
||||
&address_type);
|
||||
auto [original_ptr, address_type] =
|
||||
type.IsPointerOrReferenceType()
|
||||
? in_value.GetPointerValue()
|
||||
: in_value.GetAddressOf(/*scalar_is_load_address=*/true);
|
||||
if (original_ptr == LLDB_INVALID_ADDRESS || address_type != eAddressTypeLoad)
|
||||
return llvm::createStringError(std::errc::invalid_argument,
|
||||
"failed to get the address of the value");
|
||||
@ -357,7 +351,8 @@ bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress(
|
||||
return false;
|
||||
// So the dynamic type is a value that starts at offset_to_top above
|
||||
// the original address.
|
||||
lldb::addr_t dynamic_addr = in_value.GetPointerValue() + offset_to_top;
|
||||
lldb::addr_t dynamic_addr =
|
||||
in_value.GetPointerValue().address + offset_to_top;
|
||||
if (!m_process->GetTarget().ResolveLoadAddress(
|
||||
dynamic_addr, dynamic_address)) {
|
||||
dynamic_address.SetRawAddress(dynamic_addr);
|
||||
|
@ -55,7 +55,7 @@ bool AppleObjCRuntimeV1::GetDynamicTypeAndAddress(
|
||||
auto class_descriptor(GetClassDescriptor(in_value));
|
||||
if (class_descriptor && class_descriptor->IsValid() &&
|
||||
class_descriptor->GetClassName()) {
|
||||
const addr_t object_ptr = in_value.GetPointerValue();
|
||||
const addr_t object_ptr = in_value.GetPointerValue().address;
|
||||
address.SetRawAddress(object_ptr);
|
||||
class_type_or_name.SetName(class_descriptor->GetClassName());
|
||||
}
|
||||
|
@ -801,7 +801,7 @@ bool AppleObjCRuntimeV2::GetDynamicTypeAndAddress(
|
||||
// be the ISA pointer.
|
||||
ClassDescriptorSP objc_class_sp(GetNonKVOClassDescriptor(in_value));
|
||||
if (objc_class_sp) {
|
||||
const addr_t object_ptr = in_value.GetPointerValue();
|
||||
const addr_t object_ptr = in_value.GetPointerValue().address;
|
||||
address.SetRawAddress(object_ptr);
|
||||
|
||||
ConstString class_name(objc_class_sp->GetClassName());
|
||||
@ -1521,7 +1521,7 @@ AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) {
|
||||
// ObjC object)
|
||||
if (!valobj.GetCompilerType().IsValid())
|
||||
return objc_class_sp;
|
||||
addr_t isa_pointer = valobj.GetPointerValue();
|
||||
addr_t isa_pointer = valobj.GetPointerValue().address;
|
||||
|
||||
// tagged pointer
|
||||
if (IsTaggedPointer(isa_pointer))
|
||||
|
@ -270,7 +270,7 @@ ObjCLanguageRuntime::GetClassDescriptor(ValueObject &valobj) {
|
||||
// pointers returned by the expression parser, don't consider this a valid
|
||||
// ObjC object)
|
||||
if (valobj.GetCompilerType().IsValid()) {
|
||||
addr_t isa_pointer = valobj.GetPointerValue();
|
||||
addr_t isa_pointer = valobj.GetPointerValue().address;
|
||||
if (isa_pointer != LLDB_INVALID_ADDRESS) {
|
||||
ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
|
||||
|
||||
|
@ -656,9 +656,7 @@ bool ValueObject::IsCStringContainer(bool check_pointer) {
|
||||
return true;
|
||||
if (type_flags.Test(eTypeIsArray))
|
||||
return true;
|
||||
addr_t cstr_address = LLDB_INVALID_ADDRESS;
|
||||
AddressType cstr_address_type = eAddressTypeInvalid;
|
||||
cstr_address = GetPointerValue(&cstr_address_type);
|
||||
addr_t cstr_address = GetPointerValue().address;
|
||||
return (cstr_address != LLDB_INVALID_ADDRESS);
|
||||
}
|
||||
|
||||
@ -707,9 +705,8 @@ size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx,
|
||||
lldb::DataBufferSP data_sp(heap_buf_ptr =
|
||||
new lldb_private::DataBufferHeap());
|
||||
|
||||
AddressType addr_type;
|
||||
lldb::addr_t addr = is_pointer_type ? GetPointerValue(&addr_type)
|
||||
: GetAddressOf(true, &addr_type);
|
||||
auto [addr, addr_type] =
|
||||
is_pointer_type ? GetPointerValue() : GetAddressOf(true);
|
||||
|
||||
switch (addr_type) {
|
||||
case eAddressTypeFile: {
|
||||
@ -901,8 +898,7 @@ ValueObject::ReadPointedString(lldb::WritableDataBufferSP &buffer_sp,
|
||||
const Flags type_flags(GetTypeInfo(&elem_or_pointee_compiler_type));
|
||||
if (type_flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
|
||||
elem_or_pointee_compiler_type.IsCharType()) {
|
||||
addr_t cstr_address = LLDB_INVALID_ADDRESS;
|
||||
AddressType cstr_address_type = eAddressTypeInvalid;
|
||||
AddrAndType cstr_address;
|
||||
|
||||
size_t cstr_len = 0;
|
||||
bool capped_data = false;
|
||||
@ -917,14 +913,15 @@ ValueObject::ReadPointedString(lldb::WritableDataBufferSP &buffer_sp,
|
||||
cstr_len = max_length;
|
||||
}
|
||||
}
|
||||
cstr_address = GetAddressOf(true, &cstr_address_type);
|
||||
cstr_address = GetAddressOf(true);
|
||||
} else {
|
||||
// We have a pointer
|
||||
cstr_address = GetPointerValue(&cstr_address_type);
|
||||
cstr_address = GetPointerValue();
|
||||
}
|
||||
|
||||
if (cstr_address == 0 || cstr_address == LLDB_INVALID_ADDRESS) {
|
||||
if (cstr_address_type == eAddressTypeHost && is_array) {
|
||||
if (cstr_address.address == 0 ||
|
||||
cstr_address.address == LLDB_INVALID_ADDRESS) {
|
||||
if (cstr_address.type == eAddressTypeHost && is_array) {
|
||||
const char *cstr = GetDataExtractor().PeekCStr(0);
|
||||
if (cstr == nullptr) {
|
||||
s << "<invalid address>";
|
||||
@ -943,7 +940,7 @@ ValueObject::ReadPointedString(lldb::WritableDataBufferSP &buffer_sp,
|
||||
}
|
||||
}
|
||||
|
||||
Address cstr_so_addr(cstr_address);
|
||||
Address cstr_so_addr(cstr_address.address);
|
||||
DataExtractor data;
|
||||
if (cstr_len > 0 && honor_array) {
|
||||
// I am using GetPointeeData() here to abstract the fact that some
|
||||
@ -1198,7 +1195,7 @@ llvm::Expected<bool> ValueObject::GetValueAsBool() {
|
||||
return value_or_err->isNonZero();
|
||||
}
|
||||
if (val_type.IsArrayType())
|
||||
return GetAddressOf() != 0;
|
||||
return GetAddressOf().address != 0;
|
||||
|
||||
return llvm::make_error<llvm::StringError>("type cannot be converted to bool",
|
||||
llvm::inconvertibleErrorCode());
|
||||
@ -1599,70 +1596,55 @@ bool ValueObject::DumpPrintableRepresentation(
|
||||
return var_success;
|
||||
}
|
||||
|
||||
addr_t ValueObject::GetAddressOf(bool scalar_is_load_address,
|
||||
AddressType *address_type) {
|
||||
ValueObject::AddrAndType
|
||||
ValueObject::GetAddressOf(bool scalar_is_load_address) {
|
||||
// Can't take address of a bitfield
|
||||
if (IsBitfield())
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
return {};
|
||||
|
||||
if (!UpdateValueIfNeeded(false))
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
return {};
|
||||
|
||||
switch (m_value.GetValueType()) {
|
||||
case Value::ValueType::Invalid:
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
return {};
|
||||
case Value::ValueType::Scalar:
|
||||
if (scalar_is_load_address) {
|
||||
if (address_type)
|
||||
*address_type = eAddressTypeLoad;
|
||||
return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
|
||||
return {m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS),
|
||||
eAddressTypeLoad};
|
||||
}
|
||||
break;
|
||||
return {};
|
||||
|
||||
case Value::ValueType::LoadAddress:
|
||||
case Value::ValueType::FileAddress: {
|
||||
if (address_type)
|
||||
*address_type = m_value.GetValueAddressType();
|
||||
return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
|
||||
} break;
|
||||
case Value::ValueType::HostAddress: {
|
||||
if (address_type)
|
||||
*address_type = m_value.GetValueAddressType();
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
} break;
|
||||
case Value::ValueType::FileAddress:
|
||||
return {m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS),
|
||||
m_value.GetValueAddressType()};
|
||||
case Value::ValueType::HostAddress:
|
||||
return {LLDB_INVALID_ADDRESS, m_value.GetValueAddressType()};
|
||||
}
|
||||
if (address_type)
|
||||
*address_type = eAddressTypeInvalid;
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
llvm_unreachable("Unhandled value type!");
|
||||
}
|
||||
|
||||
addr_t ValueObject::GetPointerValue(AddressType *address_type) {
|
||||
addr_t address = LLDB_INVALID_ADDRESS;
|
||||
if (address_type)
|
||||
*address_type = eAddressTypeInvalid;
|
||||
|
||||
ValueObject::AddrAndType ValueObject::GetPointerValue() {
|
||||
if (!UpdateValueIfNeeded(false))
|
||||
return address;
|
||||
return {};
|
||||
|
||||
switch (m_value.GetValueType()) {
|
||||
case Value::ValueType::Invalid:
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
return {};
|
||||
case Value::ValueType::Scalar:
|
||||
address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
|
||||
break;
|
||||
return {m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS),
|
||||
GetAddressTypeOfChildren()};
|
||||
|
||||
case Value::ValueType::HostAddress:
|
||||
case Value::ValueType::LoadAddress:
|
||||
case Value::ValueType::FileAddress: {
|
||||
lldb::offset_t data_offset = 0;
|
||||
address = m_data.GetAddress(&data_offset);
|
||||
} break;
|
||||
return {m_data.GetAddress(&data_offset), GetAddressTypeOfChildren()};
|
||||
}
|
||||
}
|
||||
|
||||
if (address_type)
|
||||
*address_type = GetAddressTypeOfChildren();
|
||||
|
||||
return address;
|
||||
llvm_unreachable("Unhandled value type!");
|
||||
}
|
||||
|
||||
static const char *ConvertBoolean(lldb::LanguageType language_type,
|
||||
@ -2749,7 +2731,7 @@ ValueObjectSP ValueObject::CreateConstantValue(ConstString name) {
|
||||
|
||||
valobj_sp = ValueObjectConstResult::Create(
|
||||
exe_ctx.GetBestExecutionContextScope(), GetCompilerType(), name, data,
|
||||
GetAddressOf());
|
||||
GetAddressOf().address);
|
||||
}
|
||||
|
||||
if (!valobj_sp) {
|
||||
@ -2875,9 +2857,7 @@ ValueObjectSP ValueObject::AddressOf(Status &error) {
|
||||
if (m_addr_of_valobj_sp)
|
||||
return m_addr_of_valobj_sp;
|
||||
|
||||
AddressType address_type = eAddressTypeInvalid;
|
||||
const bool scalar_is_load_address = false;
|
||||
addr_t addr = GetAddressOf(scalar_is_load_address, &address_type);
|
||||
auto [addr, address_type] = GetAddressOf(/*scalar_is_load_address=*/false);
|
||||
error.Clear();
|
||||
if (addr != LLDB_INVALID_ADDRESS && address_type != eAddressTypeHost) {
|
||||
switch (address_type) {
|
||||
@ -2964,8 +2944,7 @@ lldb::ValueObjectSP ValueObject::Clone(ConstString new_name) {
|
||||
ValueObjectSP ValueObject::CastPointerType(const char *name,
|
||||
CompilerType &compiler_type) {
|
||||
ValueObjectSP valobj_sp;
|
||||
AddressType address_type;
|
||||
addr_t ptr_value = GetPointerValue(&address_type);
|
||||
addr_t ptr_value = GetPointerValue().address;
|
||||
|
||||
if (ptr_value != LLDB_INVALID_ADDRESS) {
|
||||
Address ptr_addr(ptr_value);
|
||||
@ -2978,8 +2957,7 @@ ValueObjectSP ValueObject::CastPointerType(const char *name,
|
||||
|
||||
ValueObjectSP ValueObject::CastPointerType(const char *name, TypeSP &type_sp) {
|
||||
ValueObjectSP valobj_sp;
|
||||
AddressType address_type;
|
||||
addr_t ptr_value = GetPointerValue(&address_type);
|
||||
addr_t ptr_value = GetPointerValue().address;
|
||||
|
||||
if (ptr_value != LLDB_INVALID_ADDRESS) {
|
||||
Address ptr_addr(ptr_value);
|
||||
@ -2991,11 +2969,9 @@ ValueObjectSP ValueObject::CastPointerType(const char *name, TypeSP &type_sp) {
|
||||
}
|
||||
|
||||
lldb::addr_t ValueObject::GetLoadAddress() {
|
||||
lldb::addr_t addr_value = LLDB_INVALID_ADDRESS;
|
||||
if (auto target_sp = GetTargetSP()) {
|
||||
const bool scalar_is_load_address = true;
|
||||
AddressType addr_type;
|
||||
addr_value = GetAddressOf(scalar_is_load_address, &addr_type);
|
||||
auto [addr_value, addr_type] = GetAddressOf(scalar_is_load_address);
|
||||
if (addr_type == eAddressTypeFile) {
|
||||
lldb::ModuleSP module_sp(GetModule());
|
||||
if (!module_sp)
|
||||
@ -3008,8 +2984,9 @@ lldb::addr_t ValueObject::GetLoadAddress() {
|
||||
} else if (addr_type == eAddressTypeHost ||
|
||||
addr_type == eAddressTypeInvalid)
|
||||
addr_value = LLDB_INVALID_ADDRESS;
|
||||
return addr_value;
|
||||
}
|
||||
return addr_value;
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
llvm::Expected<lldb::ValueObjectSP> ValueObject::CastDerivedToBaseType(
|
||||
|
@ -118,7 +118,7 @@ bool ValueObjectChild::UpdateValue() {
|
||||
(parent_type_flags.AnySet(lldb::eTypeInstanceIsPointer)));
|
||||
|
||||
if (parent->GetCompilerType().ShouldTreatScalarValueAsAddress()) {
|
||||
m_value.GetScalar() = parent->GetPointerValue();
|
||||
m_value.GetScalar() = parent->GetPointerValue().address;
|
||||
|
||||
switch (parent->GetAddressTypeOfChildren()) {
|
||||
case eAddressTypeFile: {
|
||||
|
@ -265,9 +265,9 @@ lldb::ValueObjectSP ValueObjectConstResult::AddressOf(Status &error) {
|
||||
return m_impl.AddressOf(error);
|
||||
}
|
||||
|
||||
lldb::addr_t ValueObjectConstResult::GetAddressOf(bool scalar_is_load_address,
|
||||
AddressType *address_type) {
|
||||
return m_impl.GetAddressOf(scalar_is_load_address, address_type);
|
||||
ValueObject::AddrAndType
|
||||
ValueObjectConstResult::GetAddressOf(bool scalar_is_load_address) {
|
||||
return m_impl.GetAddressOf(scalar_is_load_address);
|
||||
}
|
||||
|
||||
size_t ValueObjectConstResult::GetPointeeData(DataExtractor &data,
|
||||
|
@ -50,10 +50,9 @@ lldb::ValueObjectSP ValueObjectConstResultChild::AddressOf(Status &error) {
|
||||
return m_impl.AddressOf(error);
|
||||
}
|
||||
|
||||
lldb::addr_t
|
||||
ValueObjectConstResultChild::GetAddressOf(bool scalar_is_load_address,
|
||||
AddressType *address_type) {
|
||||
return m_impl.GetAddressOf(scalar_is_load_address, address_type);
|
||||
ValueObject::AddrAndType
|
||||
ValueObjectConstResultChild::GetAddressOf(bool scalar_is_load_address) {
|
||||
return m_impl.GetAddressOf(scalar_is_load_address);
|
||||
}
|
||||
|
||||
size_t ValueObjectConstResultChild::GetPointeeData(DataExtractor &data,
|
||||
|
@ -206,22 +206,16 @@ ValueObjectConstResultImpl::Cast(const CompilerType &compiler_type) {
|
||||
return result_cast->GetSP();
|
||||
}
|
||||
|
||||
lldb::addr_t
|
||||
ValueObjectConstResultImpl::GetAddressOf(bool scalar_is_load_address,
|
||||
AddressType *address_type) {
|
||||
ValueObject::AddrAndType
|
||||
ValueObjectConstResultImpl::GetAddressOf(bool scalar_is_load_address) {
|
||||
|
||||
if (m_impl_backend == nullptr)
|
||||
return 0;
|
||||
return {0, eAddressTypeInvalid};
|
||||
|
||||
if (m_live_address == LLDB_INVALID_ADDRESS) {
|
||||
return m_impl_backend->ValueObject::GetAddressOf(scalar_is_load_address,
|
||||
address_type);
|
||||
}
|
||||
if (m_live_address == LLDB_INVALID_ADDRESS)
|
||||
return m_impl_backend->ValueObject::GetAddressOf(scalar_is_load_address);
|
||||
|
||||
if (address_type)
|
||||
*address_type = m_live_address_type;
|
||||
|
||||
return m_live_address;
|
||||
return {m_live_address, m_live_address_type};
|
||||
}
|
||||
|
||||
size_t ValueObjectConstResultImpl::GetPointeeData(DataExtractor &data,
|
||||
|
@ -252,7 +252,7 @@ bool ValueObjectVTable::UpdateValue() {
|
||||
m_num_vtable_entries = (vtable_end_addr - vtable_start_addr) / m_addr_size;
|
||||
|
||||
m_value.SetValueType(Value::ValueType::LoadAddress);
|
||||
m_value.GetScalar() = parent->GetAddressOf();
|
||||
m_value.GetScalar() = parent->GetAddressOf().address;
|
||||
auto type_system_or_err =
|
||||
target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC_plus_plus);
|
||||
if (type_system_or_err) {
|
||||
|
@ -269,7 +269,14 @@ class ValueAPITestCase(TestBase):
|
||||
frame0.FindVariable("another_fixed_int_ptr").GetValue(),
|
||||
"0xaa",
|
||||
)
|
||||
a_null_int_ptr = frame0.FindVariable("a_null_int_ptr")
|
||||
self.assertEqual(a_null_int_ptr.GetValue(), "0x0")
|
||||
|
||||
# Check that dereferencing a null pointer produces reasonable results
|
||||
# (does not crash).
|
||||
self.assertEqual(
|
||||
frame0.FindVariable("a_null_int_ptr").GetValue(),
|
||||
"0x0",
|
||||
a_null_int_ptr.Dereference().GetError().GetCString(), "parent is NULL"
|
||||
)
|
||||
self.assertEqual(
|
||||
a_null_int_ptr.Dereference().GetLoadAddress(), lldb.LLDB_INVALID_ADDRESS
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user