1 //===-- TypeFormat.cpp ----------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "lldb/DataFormatters/TypeFormat.h"
10
11
12
13
14 #include "lldb/lldb-enumerations.h"
15 #include "lldb/lldb-public.h"
16
17 #include "lldb/Core/DumpDataExtractor.h"
18 #include "lldb/DataFormatters/FormatManager.h"
19 #include "lldb/Symbol/CompilerType.h"
20 #include "lldb/Symbol/SymbolContext.h"
21 #include "lldb/Symbol/SymbolFile.h"
22 #include "lldb/Symbol/TypeList.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Utility/DataExtractor.h"
25 #include "lldb/Utility/StreamString.h"
26
27 using namespace lldb;
28 using namespace lldb_private;
29
TypeFormatImpl(const Flags & flags)30 TypeFormatImpl::TypeFormatImpl(const Flags &flags)
31 : m_flags(flags), m_my_revision(0) {}
32
~TypeFormatImpl()33 TypeFormatImpl::~TypeFormatImpl() {}
34
TypeFormatImpl_Format(lldb::Format f,const TypeFormatImpl::Flags & flags)35 TypeFormatImpl_Format::TypeFormatImpl_Format(lldb::Format f,
36 const TypeFormatImpl::Flags &flags)
37 : TypeFormatImpl(flags), m_format(f) {}
38
~TypeFormatImpl_Format()39 TypeFormatImpl_Format::~TypeFormatImpl_Format() {}
40
FormatObject(ValueObject * valobj,std::string & dest) const41 bool TypeFormatImpl_Format::FormatObject(ValueObject *valobj,
42 std::string &dest) const {
43 if (!valobj)
44 return false;
45 if (valobj->CanProvideValue()) {
46 Value &value(valobj->GetValue());
47 const Value::ContextType context_type = value.GetContextType();
48 ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
49 DataExtractor data;
50
51 if (context_type == Value::eContextTypeRegisterInfo) {
52 const RegisterInfo *reg_info = value.GetRegisterInfo();
53 if (reg_info) {
54 Status error;
55 valobj->GetData(data, error);
56 if (error.Fail())
57 return false;
58
59 StreamString reg_sstr;
60 DumpDataExtractor(data, ®_sstr, 0, GetFormat(), reg_info->byte_size,
61 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0,
62 exe_ctx.GetBestExecutionContextScope());
63 dest = std::string(reg_sstr.GetString());
64 }
65 } else {
66 CompilerType compiler_type = value.GetCompilerType();
67 if (compiler_type) {
68 // put custom bytes to display in the DataExtractor to override the
69 // default value logic
70 if (GetFormat() == eFormatCString) {
71 lldb_private::Flags type_flags(compiler_type.GetTypeInfo(
72 nullptr)); // disambiguate w.r.t. TypeFormatImpl::Flags
73 if (type_flags.Test(eTypeIsPointer) &&
74 !type_flags.Test(eTypeIsObjC)) {
75 // if we are dumping a pointer as a c-string, get the pointee data
76 // as a string
77 TargetSP target_sp(valobj->GetTargetSP());
78 if (target_sp) {
79 size_t max_len = target_sp->GetMaximumSizeOfStringSummary();
80 Status error;
81 DataBufferSP buffer_sp(new DataBufferHeap(max_len + 1, 0));
82 Address address(valobj->GetPointerValue());
83 if (target_sp->ReadCStringFromMemory(
84 address, (char *)buffer_sp->GetBytes(), max_len, error) &&
85 error.Success())
86 data.SetData(buffer_sp);
87 }
88 }
89 } else {
90 Status error;
91 valobj->GetData(data, error);
92 if (error.Fail())
93 return false;
94 }
95
96 ExecutionContextScope *exe_scope =
97 exe_ctx.GetBestExecutionContextScope();
98 llvm::Optional<uint64_t> size = compiler_type.GetByteSize(exe_scope);
99 if (!size)
100 return false;
101 StreamString sstr;
102 compiler_type.DumpTypeValue(
103 &sstr, // The stream to use for display
104 GetFormat(), // Format to display this type with
105 data, // Data to extract from
106 0, // Byte offset into "m_data"
107 *size, // Byte size of item in "m_data"
108 valobj->GetBitfieldBitSize(), // Bitfield bit size
109 valobj->GetBitfieldBitOffset(), // Bitfield bit offset
110 exe_scope);
111 // Given that we do not want to set the ValueObject's m_error for a
112 // formatting error (or else we wouldn't be able to reformat until a
113 // next update), an empty string is treated as a "false" return from
114 // here, but that's about as severe as we get
115 // CompilerType::DumpTypeValue() should always return something, even
116 // if that something is an error message
117 dest = std::string(sstr.GetString());
118 }
119 }
120 return !dest.empty();
121 } else
122 return false;
123 }
124
GetDescription()125 std::string TypeFormatImpl_Format::GetDescription() {
126 StreamString sstr;
127 sstr.Printf("%s%s%s%s", FormatManager::GetFormatAsCString(GetFormat()),
128 Cascades() ? "" : " (not cascading)",
129 SkipsPointers() ? " (skip pointers)" : "",
130 SkipsReferences() ? " (skip references)" : "");
131 return std::string(sstr.GetString());
132 }
133
TypeFormatImpl_EnumType(ConstString type_name,const TypeFormatImpl::Flags & flags)134 TypeFormatImpl_EnumType::TypeFormatImpl_EnumType(
135 ConstString type_name, const TypeFormatImpl::Flags &flags)
136 : TypeFormatImpl(flags), m_enum_type(type_name), m_types() {}
137
~TypeFormatImpl_EnumType()138 TypeFormatImpl_EnumType::~TypeFormatImpl_EnumType() {}
139
FormatObject(ValueObject * valobj,std::string & dest) const140 bool TypeFormatImpl_EnumType::FormatObject(ValueObject *valobj,
141 std::string &dest) const {
142 dest.clear();
143 if (!valobj)
144 return false;
145 if (!valobj->CanProvideValue())
146 return false;
147 ProcessSP process_sp;
148 TargetSP target_sp;
149 void *valobj_key = (process_sp = valobj->GetProcessSP()).get();
150 if (!valobj_key)
151 valobj_key = (target_sp = valobj->GetTargetSP()).get();
152 else
153 target_sp = process_sp->GetTarget().shared_from_this();
154 if (!valobj_key)
155 return false;
156 auto iter = m_types.find(valobj_key), end = m_types.end();
157 CompilerType valobj_enum_type;
158 if (iter == end) {
159 // probably a redundant check
160 if (!target_sp)
161 return false;
162 const ModuleList &images(target_sp->GetImages());
163 TypeList types;
164 llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
165 images.FindTypes(nullptr, m_enum_type, false, UINT32_MAX,
166 searched_symbol_files, types);
167 if (types.Empty())
168 return false;
169 for (lldb::TypeSP type_sp : types.Types()) {
170 if (!type_sp)
171 continue;
172 if ((type_sp->GetForwardCompilerType().GetTypeInfo() &
173 eTypeIsEnumeration) == eTypeIsEnumeration) {
174 valobj_enum_type = type_sp->GetFullCompilerType();
175 m_types.emplace(valobj_key, valobj_enum_type);
176 break;
177 }
178 }
179 } else
180 valobj_enum_type = iter->second;
181 if (!valobj_enum_type.IsValid())
182 return false;
183 DataExtractor data;
184 Status error;
185 valobj->GetData(data, error);
186 if (error.Fail())
187 return false;
188 ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
189 StreamString sstr;
190 valobj_enum_type.DumpTypeValue(&sstr, lldb::eFormatEnum, data, 0,
191 data.GetByteSize(), 0, 0,
192 exe_ctx.GetBestExecutionContextScope());
193 if (!sstr.GetString().empty())
194 dest = std::string(sstr.GetString());
195 return !dest.empty();
196 }
197
GetDescription()198 std::string TypeFormatImpl_EnumType::GetDescription() {
199 StreamString sstr;
200 sstr.Printf("as type %s%s%s%s", m_enum_type.AsCString("<invalid type>"),
201 Cascades() ? "" : " (not cascading)",
202 SkipsPointers() ? " (skip pointers)" : "",
203 SkipsReferences() ? " (skip references)" : "");
204 return std::string(sstr.GetString());
205 }
206