Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
DWARFExpression.cpp
Go to the documentation of this file.
1//===-- DWARFExpression.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 "llvm/DebugInfo/DWARF/DWARFExpression.h"
10#include "llvm/ADT/SmallString.h"
11#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
12#include "llvm/Support/Format.h"
13#include <cassert>
14#include <cstdint>
15#include <vector>
16
17using namespacellvm;
18using namespacedwarf;
19
20namespacellvm {
21
22typedefDWARFExpression::OperationOp;
23typedefOp::DescriptionDesc;
24
25static std::vector<Desc>getOpDescriptions() {
26 std::vector<Desc> Descriptions;
27 Descriptions.resize(0xff);
28 Descriptions[DW_OP_addr] =Desc(Op::Dwarf2,Op::SizeAddr);
29 Descriptions[DW_OP_deref] =Desc(Op::Dwarf2);
30 Descriptions[DW_OP_const1u] =Desc(Op::Dwarf2,Op::Size1);
31 Descriptions[DW_OP_const1s] =Desc(Op::Dwarf2,Op::SignedSize1);
32 Descriptions[DW_OP_const2u] =Desc(Op::Dwarf2,Op::Size2);
33 Descriptions[DW_OP_const2s] =Desc(Op::Dwarf2,Op::SignedSize2);
34 Descriptions[DW_OP_const4u] =Desc(Op::Dwarf2,Op::Size4);
35 Descriptions[DW_OP_const4s] =Desc(Op::Dwarf2,Op::SignedSize4);
36 Descriptions[DW_OP_const8u] =Desc(Op::Dwarf2,Op::Size8);
37 Descriptions[DW_OP_const8s] =Desc(Op::Dwarf2,Op::SignedSize8);
38 Descriptions[DW_OP_constu] =Desc(Op::Dwarf2,Op::SizeLEB);
39 Descriptions[DW_OP_consts] =Desc(Op::Dwarf2,Op::SignedSizeLEB);
40 Descriptions[DW_OP_dup] =Desc(Op::Dwarf2);
41 Descriptions[DW_OP_drop] =Desc(Op::Dwarf2);
42 Descriptions[DW_OP_over] =Desc(Op::Dwarf2);
43 Descriptions[DW_OP_pick] =Desc(Op::Dwarf2,Op::Size1);
44 Descriptions[DW_OP_swap] =Desc(Op::Dwarf2);
45 Descriptions[DW_OP_rot] =Desc(Op::Dwarf2);
46 Descriptions[DW_OP_xderef] =Desc(Op::Dwarf2);
47 Descriptions[DW_OP_abs] =Desc(Op::Dwarf2);
48 Descriptions[DW_OP_and] =Desc(Op::Dwarf2);
49 Descriptions[DW_OP_div] =Desc(Op::Dwarf2);
50 Descriptions[DW_OP_minus] =Desc(Op::Dwarf2);
51 Descriptions[DW_OP_mod] =Desc(Op::Dwarf2);
52 Descriptions[DW_OP_mul] =Desc(Op::Dwarf2);
53 Descriptions[DW_OP_neg] =Desc(Op::Dwarf2);
54 Descriptions[DW_OP_not] =Desc(Op::Dwarf2);
55 Descriptions[DW_OP_or] =Desc(Op::Dwarf2);
56 Descriptions[DW_OP_plus] =Desc(Op::Dwarf2);
57 Descriptions[DW_OP_plus_uconst] =Desc(Op::Dwarf2,Op::SizeLEB);
58 Descriptions[DW_OP_shl] =Desc(Op::Dwarf2);
59 Descriptions[DW_OP_shr] =Desc(Op::Dwarf2);
60 Descriptions[DW_OP_shra] =Desc(Op::Dwarf2);
61 Descriptions[DW_OP_xor] =Desc(Op::Dwarf2);
62 Descriptions[DW_OP_bra] =Desc(Op::Dwarf2,Op::SignedSize2);
63 Descriptions[DW_OP_eq] =Desc(Op::Dwarf2);
64 Descriptions[DW_OP_ge] =Desc(Op::Dwarf2);
65 Descriptions[DW_OP_gt] =Desc(Op::Dwarf2);
66 Descriptions[DW_OP_le] =Desc(Op::Dwarf2);
67 Descriptions[DW_OP_lt] =Desc(Op::Dwarf2);
68 Descriptions[DW_OP_ne] =Desc(Op::Dwarf2);
69 Descriptions[DW_OP_skip] =Desc(Op::Dwarf2,Op::SignedSize2);
70for (uint16_t LA = DW_OP_lit0; LA <= DW_OP_lit31; ++LA)
71 Descriptions[LA] =Desc(Op::Dwarf2);
72for (uint16_t LA = DW_OP_reg0; LA <= DW_OP_reg31; ++LA)
73 Descriptions[LA] =Desc(Op::Dwarf2);
74for (uint16_t LA = DW_OP_breg0; LA <= DW_OP_breg31; ++LA)
75 Descriptions[LA] =Desc(Op::Dwarf2,Op::SignedSizeLEB);
76 Descriptions[DW_OP_regx] =Desc(Op::Dwarf2,Op::SizeLEB);
77 Descriptions[DW_OP_fbreg] =Desc(Op::Dwarf2,Op::SignedSizeLEB);
78 Descriptions[DW_OP_bregx] =Desc(Op::Dwarf2,Op::SizeLEB,Op::SignedSizeLEB);
79 Descriptions[DW_OP_piece] =Desc(Op::Dwarf2,Op::SizeLEB);
80 Descriptions[DW_OP_deref_size] =Desc(Op::Dwarf2,Op::Size1);
81 Descriptions[DW_OP_xderef_size] =Desc(Op::Dwarf2,Op::Size1);
82 Descriptions[DW_OP_nop] =Desc(Op::Dwarf2);
83 Descriptions[DW_OP_push_object_address] =Desc(Op::Dwarf3);
84 Descriptions[DW_OP_call2] =Desc(Op::Dwarf3,Op::Size2);
85 Descriptions[DW_OP_call4] =Desc(Op::Dwarf3,Op::Size4);
86 Descriptions[DW_OP_call_ref] =Desc(Op::Dwarf3,Op::SizeRefAddr);
87 Descriptions[DW_OP_form_tls_address] =Desc(Op::Dwarf3);
88 Descriptions[DW_OP_call_frame_cfa] =Desc(Op::Dwarf3);
89 Descriptions[DW_OP_bit_piece] =Desc(Op::Dwarf3,Op::SizeLEB,Op::SizeLEB);
90 Descriptions[DW_OP_implicit_value] =
91Desc(Op::Dwarf4,Op::SizeLEB,Op::SizeBlock);
92 Descriptions[DW_OP_stack_value] =Desc(Op::Dwarf4);
93 Descriptions[DW_OP_implicit_pointer] =
94Desc(Op::Dwarf5,Op::SizeRefAddr,Op::SignedSizeLEB);
95 Descriptions[DW_OP_addrx] =Desc(Op::Dwarf5,Op::SizeLEB);
96 Descriptions[DW_OP_constx] =Desc(Op::Dwarf5,Op::SizeLEB);
97 Descriptions[DW_OP_entry_value] =Desc(Op::Dwarf5,Op::SizeLEB);
98 Descriptions[DW_OP_convert] =Desc(Op::Dwarf5,Op::BaseTypeRef);
99 Descriptions[DW_OP_regval_type] =
100Desc(Op::Dwarf5,Op::SizeLEB,Op::BaseTypeRef);
101 Descriptions[DW_OP_WASM_location] =
102Desc(Op::Dwarf4,Op::SizeLEB,Op::WasmLocationArg);
103 Descriptions[DW_OP_GNU_push_tls_address] =Desc(Op::Dwarf3);
104 Descriptions[DW_OP_GNU_addr_index] =Desc(Op::Dwarf4,Op::SizeLEB);
105 Descriptions[DW_OP_GNU_const_index] =Desc(Op::Dwarf4,Op::SizeLEB);
106 Descriptions[DW_OP_GNU_entry_value] =Desc(Op::Dwarf4,Op::SizeLEB);
107// This Description acts as a marker that getSubOpDesc must be called
108// to fetch the final Description for the operation. Each such final
109// Description must share the same first SizeSubOpLEB operand.
110 Descriptions[DW_OP_LLVM_user] =Desc(Op::Dwarf5,Op::SizeSubOpLEB);
111return Descriptions;
112}
113
114staticDescgetDescImpl(ArrayRef<Desc> Descriptions,unsigned Opcode) {
115// Handle possible corrupted or unsupported operation.
116if (Opcode >= Descriptions.size())
117return {};
118return Descriptions[Opcode];
119}
120
121staticDescgetOpDesc(unsigned Opcode) {
122static std::vector<Desc> Descriptions =getOpDescriptions();
123returngetDescImpl(Descriptions, Opcode);
124}
125
126static std::vector<Desc>getSubOpDescriptions() {
127staticconstexprunsigned LlvmUserDescriptionsSize = 1
128#define HANDLE_DW_OP_LLVM_USEROP(ID, NAME) +1
129#include "llvm/BinaryFormat/Dwarf.def"
130 ;
131 std::vector<Desc> Descriptions;
132 Descriptions.resize(LlvmUserDescriptionsSize);
133 Descriptions[DW_OP_LLVM_nop] =Desc(Op::Dwarf5,Op::SizeSubOpLEB);
134return Descriptions;
135}
136
137staticDescgetSubOpDesc(unsigned Opcode,unsigned SubOpcode) {
138assert(Opcode == DW_OP_LLVM_user);
139static std::vector<Desc> Descriptions =getSubOpDescriptions();
140returngetDescImpl(Descriptions, SubOpcode);
141}
142
143bool DWARFExpression::Operation::extract(DataExtractorData,
144uint8_t AddressSize,uint64_tOffset,
145 std::optional<DwarfFormat>Format) {
146 EndOffset =Offset;
147 Opcode = Data.getU8(&Offset);
148
149Desc =getOpDesc(Opcode);
150if (Desc.Version ==Operation::DwarfNA)
151returnfalse;
152
153 Operands.resize(Desc.Op.size());
154 OperandEndOffsets.resize(Desc.Op.size());
155for (unsigned Operand = 0; Operand <Desc.Op.size(); ++Operand) {
156unsignedSize =Desc.Op[Operand];
157unsignedSigned =Size &Operation::SignBit;
158
159switch (Size & ~Operation::SignBit) {
160caseOperation::SizeSubOpLEB:
161assert(Operand == 0 &&"SubOp operand must be the first operand");
162 Operands[Operand] = Data.getULEB128(&Offset);
163Desc =getSubOpDesc(Opcode, Operands[Operand]);
164if (Desc.Version ==Operation::DwarfNA)
165returnfalse;
166assert(Desc.Op[Operand] ==Operation::SizeSubOpLEB &&
167"SizeSubOpLEB Description must begin with SizeSubOpLEB operand");
168break;
169caseOperation::Size1:
170 Operands[Operand] = Data.getU8(&Offset);
171if (Signed)
172 Operands[Operand] = (int8_t)Operands[Operand];
173break;
174caseOperation::Size2:
175 Operands[Operand] = Data.getU16(&Offset);
176if (Signed)
177 Operands[Operand] = (int16_t)Operands[Operand];
178break;
179caseOperation::Size4:
180 Operands[Operand] = Data.getU32(&Offset);
181if (Signed)
182 Operands[Operand] = (int32_t)Operands[Operand];
183break;
184caseOperation::Size8:
185 Operands[Operand] = Data.getU64(&Offset);
186break;
187caseOperation::SizeAddr:
188 Operands[Operand] = Data.getUnsigned(&Offset, AddressSize);
189break;
190caseOperation::SizeRefAddr:
191if (!Format)
192returnfalse;
193 Operands[Operand] =
194 Data.getUnsigned(&Offset,dwarf::getDwarfOffsetByteSize(*Format));
195break;
196caseOperation::SizeLEB:
197if (Signed)
198 Operands[Operand] = Data.getSLEB128(&Offset);
199else
200 Operands[Operand] = Data.getULEB128(&Offset);
201break;
202caseOperation::BaseTypeRef:
203 Operands[Operand] = Data.getULEB128(&Offset);
204break;
205caseOperation::WasmLocationArg:
206assert(Operand == 1);
207switch (Operands[0]) {
208case 0:
209case 1:
210case 2:
211case 4:
212 Operands[Operand] = Data.getULEB128(&Offset);
213break;
214case 3:// global as uint32
215 Operands[Operand] = Data.getU32(&Offset);
216break;
217default:
218returnfalse;// Unknown Wasm location
219 }
220break;
221caseOperation::SizeBlock:
222// We need a size, so this cannot be the first operand
223if (Operand == 0)
224returnfalse;
225// Store the offset of the block as the value.
226 Operands[Operand] =Offset;
227Offset += Operands[Operand - 1];
228break;
229default:
230llvm_unreachable("Unknown DWARFExpression Op size");
231 }
232
233 OperandEndOffsets[Operand] =Offset;
234 }
235
236 EndOffset =Offset;
237returntrue;
238}
239
240staticvoidprettyPrintBaseTypeRef(DWARFUnit *U,raw_ostream &OS,
241DIDumpOptions DumpOpts,
242ArrayRef<uint64_t>Operands,
243unsigned Operand) {
244assert(Operand <Operands.size() &&"operand out of bounds");
245if (!U) {
246OS <<format(" <base_type ref: 0x%" PRIx64">",Operands[Operand]);
247return;
248 }
249auto Die = U->getDIEForOffset(U->getOffset() +Operands[Operand]);
250if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
251OS <<" (";
252if (DumpOpts.Verbose)
253OS <<format("0x%08" PRIx64" -> ",Operands[Operand]);
254OS <<format("0x%08" PRIx64")", U->getOffset() +Operands[Operand]);
255if (autoName =dwarf::toString(Die.find(dwarf::DW_AT_name)))
256OS <<" \"" << *Name <<"\"";
257 }else {
258OS <<format(" <invalid base_type ref: 0x%" PRIx64">",Operands[Operand]);
259 }
260}
261
262boolDWARFExpression::prettyPrintRegisterOp(DWARFUnit *U,raw_ostream &OS,
263DIDumpOptions DumpOpts,
264uint8_t Opcode,
265ArrayRef<uint64_t>Operands) {
266if (!DumpOpts.GetNameForDWARFReg)
267returnfalse;
268
269uint64_t DwarfRegNum;
270unsigned OpNum = 0;
271
272if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
273 Opcode == DW_OP_regval_type)
274 DwarfRegNum =Operands[OpNum++];
275elseif (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx)
276 DwarfRegNum = Opcode - DW_OP_breg0;
277else
278 DwarfRegNum = Opcode - DW_OP_reg0;
279
280autoRegName = DumpOpts.GetNameForDWARFReg(DwarfRegNum, DumpOpts.IsEH);
281if (!RegName.empty()) {
282if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
283 Opcode == DW_OP_bregx)
284OS <<' ' <<RegName <<format("%+" PRId64,Operands[OpNum]);
285else
286OS <<' ' <<RegName.data();
287
288if (Opcode == DW_OP_regval_type)
289prettyPrintBaseTypeRef(U,OS, DumpOpts,Operands, 1);
290returntrue;
291 }
292
293returnfalse;
294}
295
296std::optional<unsigned>DWARFExpression::Operation::getSubCode() const{
297if (!Desc.Op.size() ||Desc.Op[0] !=Operation::SizeSubOpLEB)
298return std::nullopt;
299returnOperands[0];
300}
301
302boolDWARFExpression::Operation::print(raw_ostream &OS,DIDumpOptions DumpOpts,
303constDWARFExpression *Expr,
304DWARFUnit *U) const{
305if (Error) {
306OS <<"<decoding error>";
307returnfalse;
308 }
309
310StringRefName =OperationEncodingString(Opcode);
311assert(!Name.empty() &&"DW_OP has no name!");
312OS <<Name;
313
314if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
315 (Opcode >= DW_OP_reg0 && Opcode <= DW_OP_reg31) ||
316 Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
317 Opcode == DW_OP_regval_type)
318if (prettyPrintRegisterOp(U,OS, DumpOpts, Opcode,Operands))
319returntrue;
320
321for (unsigned Operand = 0; Operand <Desc.Op.size(); ++Operand) {
322unsignedSize =Desc.Op[Operand];
323unsignedSigned =Size &Operation::SignBit;
324
325if (Size ==Operation::SizeSubOpLEB) {
326StringRef SubName =SubOperationEncodingString(Opcode,Operands[Operand]);
327assert(!SubName.empty() &&"DW_OP SubOp has no name!");
328OS <<" " << SubName;
329 }elseif (Size ==Operation::BaseTypeRef && U) {
330// For DW_OP_convert the operand may be 0 to indicate that conversion to
331// the generic type should be done. The same holds for DW_OP_reinterpret,
332// which is currently not supported.
333if (Opcode == DW_OP_convert &&Operands[Operand] == 0)
334OS <<" 0x0";
335else
336prettyPrintBaseTypeRef(U,OS, DumpOpts,Operands, Operand);
337 }elseif (Size ==Operation::WasmLocationArg) {
338assert(Operand == 1);
339switch (Operands[0]) {
340case 0:
341case 1:
342case 2:
343case 3:// global as uint32
344case 4:
345OS <<format(" 0x%" PRIx64,Operands[Operand]);
346break;
347default:assert(false);
348 }
349 }elseif (Size ==Operation::SizeBlock) {
350uint64_tOffset =Operands[Operand];
351for (unsigned i = 0; i <Operands[Operand - 1]; ++i)
352OS <<format(" 0x%02x", Expr->Data.getU8(&Offset));
353 }else {
354if (Signed)
355OS <<format(" %+" PRId64, (int64_t)Operands[Operand]);
356elseif (Opcode != DW_OP_entry_value &&
357 Opcode != DW_OP_GNU_entry_value)
358OS <<format(" 0x%" PRIx64,Operands[Operand]);
359 }
360 }
361returntrue;
362}
363
364voidDWARFExpression::print(raw_ostream &OS,DIDumpOptions DumpOpts,
365DWARFUnit *U,bool IsEH) const{
366uint32_t EntryValExprSize = 0;
367uint64_t EntryValStartOffset = 0;
368if (Data.getData().empty())
369OS <<"<empty>";
370
371for (auto &Op : *this) {
372 DumpOpts.IsEH = IsEH;
373if (!Op.print(OS, DumpOpts,this, U)) {
374uint64_t FailOffset =Op.getEndOffset();
375while (FailOffset < Data.getData().size())
376OS <<format(" %02x", Data.getU8(&FailOffset));
377return;
378 }
379
380if (Op.getCode() == DW_OP_entry_value ||
381Op.getCode() == DW_OP_GNU_entry_value) {
382OS <<"(";
383 EntryValExprSize =Op.getRawOperand(0);
384 EntryValStartOffset =Op.getEndOffset();
385continue;
386 }
387
388if (EntryValExprSize) {
389 EntryValExprSize -=Op.getEndOffset() - EntryValStartOffset;
390if (EntryValExprSize == 0)
391OS <<")";
392 }
393
394if (Op.getEndOffset() < Data.getData().size())
395OS <<", ";
396 }
397}
398
399boolDWARFExpression::Operation::verify(constOperation &Op,DWARFUnit *U) {
400for (unsigned Operand = 0; Operand <Op.Desc.Op.size(); ++Operand) {
401unsignedSize =Op.Desc.Op[Operand];
402
403if (Size ==Operation::BaseTypeRef) {
404// For DW_OP_convert the operand may be 0 to indicate that conversion to
405// the generic type should be done, so don't look up a base type in that
406// case. The same holds for DW_OP_reinterpret, which is currently not
407// supported.
408if (Op.Opcode == DW_OP_convert &&Op.Operands[Operand] == 0)
409continue;
410auto Die = U->getDIEForOffset(U->getOffset() +Op.Operands[Operand]);
411if (!Die || Die.getTag() != dwarf::DW_TAG_base_type)
412returnfalse;
413 }
414 }
415
416returntrue;
417}
418
419boolDWARFExpression::verify(DWARFUnit *U) {
420for (auto &Op : *this)
421if (!Operation::verify(Op, U))
422returnfalse;
423
424returntrue;
425}
426
427/// A user-facing string representation of a DWARF expression. This might be an
428/// Address expression, in which case it will be implicitly dereferenced, or a
429/// Value expression.
430structPrintedExpr {
431enumExprKind {
432Address,
433Value,
434 };
435ExprKindKind;
436SmallString<16>String;
437
438PrintedExpr(ExprKind K = Address) : Kind(K) {}
439};
440
441staticboolprintCompactDWARFExpr(
442raw_ostream &OS,DWARFExpression::iteratorI,
443constDWARFExpression::iterator E,
444 std::function<StringRef(uint64_t RegNum,bool IsEH)> GetNameForDWARFReg =
445nullptr) {
446SmallVector<PrintedExpr, 4> Stack;
447
448while (I != E) {
449constDWARFExpression::Operation &Op = *I;
450uint8_t Opcode =Op.getCode();
451switch (Opcode) {
452case dwarf::DW_OP_regx: {
453// DW_OP_regx: A register, with the register num given as an operand.
454// Printed as the plain register name.
455uint64_t DwarfRegNum =Op.getRawOperand(0);
456autoRegName = GetNameForDWARFReg(DwarfRegNum,false);
457if (RegName.empty())
458returnfalse;
459raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
460 S <<RegName;
461break;
462 }
463case dwarf::DW_OP_bregx: {
464int DwarfRegNum =Op.getRawOperand(0);
465 int64_tOffset =Op.getRawOperand(1);
466autoRegName = GetNameForDWARFReg(DwarfRegNum,false);
467if (RegName.empty())
468returnfalse;
469raw_svector_ostream S(Stack.emplace_back().String);
470 S <<RegName;
471if (Offset)
472 S <<format("%+" PRId64,Offset);
473break;
474 }
475case dwarf::DW_OP_entry_value:
476case dwarf::DW_OP_GNU_entry_value: {
477// DW_OP_entry_value contains a sub-expression which must be rendered
478// separately.
479uint64_t SubExprLength =Op.getRawOperand(0);
480DWARFExpression::iterator SubExprEnd =I.skipBytes(SubExprLength);
481 ++I;
482raw_svector_ostream S(Stack.emplace_back().String);
483 S <<"entry(";
484printCompactDWARFExpr(S,I, SubExprEnd, GetNameForDWARFReg);
485 S <<")";
486I = SubExprEnd;
487continue;
488 }
489case dwarf::DW_OP_stack_value: {
490// The top stack entry should be treated as the actual value of tne
491// variable, rather than the address of the variable in memory.
492assert(!Stack.empty());
493 Stack.back().Kind =PrintedExpr::Value;
494break;
495 }
496case dwarf::DW_OP_nop: {
497break;
498 }
499case dwarf::DW_OP_LLVM_user: {
500assert(Op.getSubCode() && *Op.getSubCode() == dwarf::DW_OP_LLVM_nop);
501break;
502 }
503default:
504if (Opcode >= dwarf::DW_OP_reg0 && Opcode <= dwarf::DW_OP_reg31) {
505// DW_OP_reg<N>: A register, with the register num implied by the
506// opcode. Printed as the plain register name.
507uint64_t DwarfRegNum = Opcode - dwarf::DW_OP_reg0;
508autoRegName = GetNameForDWARFReg(DwarfRegNum,false);
509if (RegName.empty())
510returnfalse;
511raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
512 S <<RegName;
513 }elseif (Opcode >= dwarf::DW_OP_breg0 &&
514 Opcode <= dwarf::DW_OP_breg31) {
515int DwarfRegNum = Opcode - dwarf::DW_OP_breg0;
516 int64_tOffset =Op.getRawOperand(0);
517autoRegName = GetNameForDWARFReg(DwarfRegNum,false);
518if (RegName.empty())
519returnfalse;
520raw_svector_ostream S(Stack.emplace_back().String);
521 S <<RegName;
522if (Offset)
523 S <<format("%+" PRId64,Offset);
524 }else {
525// If we hit an unknown operand, we don't know its effect on the stack,
526// so bail out on the whole expression.
527OS <<"<unknown op " <<dwarf::OperationEncodingString(Opcode) <<" ("
528 << (int)Opcode <<")>";
529returnfalse;
530 }
531break;
532 }
533 ++I;
534 }
535
536if (Stack.size() != 1) {
537OS <<"<stack of size " << Stack.size() <<", expected 1>";
538returnfalse;
539 }
540
541if (Stack.front().Kind ==PrintedExpr::Address)
542OS <<"[" << Stack.front().String <<"]";
543else
544OS << Stack.front().String;
545
546returntrue;
547}
548
549boolDWARFExpression::printCompact(
550raw_ostream &OS,
551 std::function<StringRef(uint64_t RegNum,bool IsEH)> GetNameForDWARFReg) {
552returnprintCompactDWARFExpr(OS,begin(),end(), GetNameForDWARFReg);
553}
554
555boolDWARFExpression::operator==(constDWARFExpression &RHS) const{
556if (AddressSize !=RHS.AddressSize || Format !=RHS.Format)
557returnfalse;
558return Data.getData() ==RHS.Data.getData();
559}
560
561}// namespace llvm
DWARFExpression.h
DWARFUnit.h
Name
std::string Name
Definition:ELFObjHandler.cpp:77
Size
uint64_t Size
Definition:ELFObjHandler.cpp:81
Format.h
RegName
#define RegName(no)
I
#define I(x, y, z)
Definition:MD5.cpp:58
Operands
mir Rename Register Operands
Definition:MIRNamerPass.cpp:74
Signed
@ Signed
Definition:NVPTXISelLowering.cpp:4789
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
OS
raw_pwrite_stream & OS
Definition:SampleProfWriter.cpp:51
SmallString.h
This file defines the SmallString class.
RHS
Value * RHS
Definition:X86PartialReduction.cpp:74
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition:ArrayRef.h:41
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition:ArrayRef.h:168
llvm::DWARFExpression::Operation
This class represents an Operation in the Expression.
Definition:DWARFExpression.h:32
llvm::DWARFExpression::Operation::getSubCode
std::optional< unsigned > getSubCode() const
Definition:DWARFExpression.cpp:296
llvm::DWARFExpression::Operation::getCode
uint8_t getCode() const
Definition:DWARFExpression.h:88
llvm::DWARFExpression::Operation::Dwarf5
@ Dwarf5
Definition:DWARFExpression.h:62
llvm::DWARFExpression::Operation::Dwarf2
@ Dwarf2
Definition:DWARFExpression.h:59
llvm::DWARFExpression::Operation::Dwarf3
@ Dwarf3
Definition:DWARFExpression.h:60
llvm::DWARFExpression::Operation::Dwarf4
@ Dwarf4
Definition:DWARFExpression.h:61
llvm::DWARFExpression::Operation::DwarfNA
@ DwarfNA
Serves as a marker for unused entries.
Definition:DWARFExpression.h:58
llvm::DWARFExpression::Operation::verify
static bool verify(const Operation &Op, DWARFUnit *U)
Verify Op. Does not affect the return of isError().
Definition:DWARFExpression.cpp:399
llvm::DWARFExpression::Operation::print
bool print(raw_ostream &OS, DIDumpOptions DumpOpts, const DWARFExpression *Expr, DWARFUnit *U) const
Definition:DWARFExpression.cpp:302
llvm::DWARFExpression::Operation::getEndOffset
uint64_t getEndOffset() const
Definition:DWARFExpression.h:99
llvm::DWARFExpression::Operation::Size2
@ Size2
Definition:DWARFExpression.h:37
llvm::DWARFExpression::Operation::BaseTypeRef
@ BaseTypeRef
Definition:DWARFExpression.h:44
llvm::DWARFExpression::Operation::SignedSize2
@ SignedSize2
Definition:DWARFExpression.h:51
llvm::DWARFExpression::Operation::Size8
@ Size8
Definition:DWARFExpression.h:39
llvm::DWARFExpression::Operation::SignBit
@ SignBit
Definition:DWARFExpression.h:49
llvm::DWARFExpression::Operation::WasmLocationArg
@ WasmLocationArg
Definition:DWARFExpression.h:48
llvm::DWARFExpression::Operation::SizeSubOpLEB
@ SizeSubOpLEB
The operand is a ULEB128 encoded SubOpcode.
Definition:DWARFExpression.h:47
llvm::DWARFExpression::Operation::SizeRefAddr
@ SizeRefAddr
Definition:DWARFExpression.h:42
llvm::DWARFExpression::Operation::SizeBlock
@ SizeBlock
Preceding operand contains block size.
Definition:DWARFExpression.h:43
llvm::DWARFExpression::Operation::SignedSize1
@ SignedSize1
Definition:DWARFExpression.h:50
llvm::DWARFExpression::Operation::SignedSize4
@ SignedSize4
Definition:DWARFExpression.h:52
llvm::DWARFExpression::Operation::SizeAddr
@ SizeAddr
Definition:DWARFExpression.h:41
llvm::DWARFExpression::Operation::SizeLEB
@ SizeLEB
Definition:DWARFExpression.h:40
llvm::DWARFExpression::Operation::SignedSize8
@ SignedSize8
Definition:DWARFExpression.h:53
llvm::DWARFExpression::Operation::SignedSizeLEB
@ SignedSizeLEB
Definition:DWARFExpression.h:54
llvm::DWARFExpression::Operation::Size1
@ Size1
Definition:DWARFExpression.h:36
llvm::DWARFExpression::Operation::Size4
@ Size4
Definition:DWARFExpression.h:38
llvm::DWARFExpression::Operation::getRawOperand
uint64_t getRawOperand(unsigned Idx) const
Definition:DWARFExpression.h:92
llvm::DWARFExpression::iterator
An iterator to go through the expression operations.
Definition:DWARFExpression.h:115
llvm::DWARFExpression
Definition:DWARFExpression.h:23
llvm::DWARFExpression::verify
bool verify(DWARFUnit *U)
Definition:DWARFExpression.cpp:419
llvm::DWARFExpression::end
iterator end() const
Definition:DWARFExpression.h:153
llvm::DWARFExpression::begin
iterator begin() const
Definition:DWARFExpression.h:152
llvm::DWARFExpression::printCompact
bool printCompact(raw_ostream &OS, std::function< StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg=nullptr)
Print the expression in a format intended to be compact and useful to a user, but not perfectly unamb...
Definition:DWARFExpression.cpp:549
llvm::DWARFExpression::operator==
bool operator==(const DWARFExpression &RHS) const
Definition:DWARFExpression.cpp:555
llvm::DWARFExpression::print
void print(raw_ostream &OS, DIDumpOptions DumpOpts, DWARFUnit *U, bool IsEH=false) const
Definition:DWARFExpression.cpp:364
llvm::DWARFExpression::prettyPrintRegisterOp
static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, DIDumpOptions DumpOpts, uint8_t Opcode, const ArrayRef< uint64_t > Operands)
Definition:DWARFExpression.cpp:262
llvm::DWARFUnit
Definition:DWARFUnit.h:211
llvm::DataExtractor
Definition:DataExtractor.h:41
llvm::DataExtractor::getU8
uint8_t getU8(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint8_t value from *offset_ptr.
Definition:DataExtractor.cpp:80
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition:Error.h:160
llvm::SmallString
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition:SmallString.h:26
llvm::SmallVectorBase::size
size_t size() const
Definition:SmallVector.h:78
llvm::SmallVectorImpl::resize
void resize(size_type N)
Definition:SmallVector.h:638
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition:SmallVector.h:1196
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition:StringRef.h:147
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition:raw_ostream.h:52
llvm::raw_svector_ostream
A raw_ostream that writes to an SmallVector or SmallString.
Definition:raw_ostream.h:691
uint16_t
uint32_t
uint64_t
uint8_t
llvm::dwarf::SubOperationEncodingString
StringRef SubOperationEncodingString(unsigned OpEncoding, unsigned SubOpEncoding)
Definition:Dwarf.cpp:202
llvm::dwarf::OperationEncodingString
StringRef OperationEncodingString(unsigned Encoding)
Definition:Dwarf.cpp:138
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition:ErrorHandling.h:143
llvm::dwarf::toString
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
Definition:DWARFFormValue.h:177
llvm::dwarf::getDwarfOffsetByteSize
uint8_t getDwarfOffsetByteSize(DwarfFormat Format)
The size of a reference determined by the DWARF 32/64-bit format.
Definition:Dwarf.h:1071
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::Offset
@ Offset
Definition:DWP.cpp:480
llvm::getSubOpDesc
static Desc getSubOpDesc(unsigned Opcode, unsigned SubOpcode)
Definition:DWARFExpression.cpp:137
llvm::getOpDescriptions
static std::vector< Desc > getOpDescriptions()
Definition:DWARFExpression.cpp:25
llvm::Desc
Op::Description Desc
Definition:DWARFExpression.cpp:23
llvm::printCompactDWARFExpr
static bool printCompactDWARFExpr(raw_ostream &OS, DWARFExpression::iterator I, const DWARFExpression::iterator E, std::function< StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg=nullptr)
Definition:DWARFExpression.cpp:441
llvm::prettyPrintBaseTypeRef
static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS, DIDumpOptions DumpOpts, ArrayRef< uint64_t > Operands, unsigned Operand)
Definition:DWARFExpression.cpp:240
llvm::format
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition:Format.h:125
llvm::getDescImpl
static Desc getDescImpl(ArrayRef< Desc > Descriptions, unsigned Opcode)
Definition:DWARFExpression.cpp:114
llvm::Op
DWARFExpression::Operation Op
Definition:DWARFExpression.cpp:22
llvm::ReplacementType::Format
@ Format
llvm::getOpDesc
static Desc getOpDesc(unsigned Opcode)
Definition:DWARFExpression.cpp:121
llvm::Data
@ Data
Definition:SIMachineScheduler.h:55
llvm::getSubOpDescriptions
static std::vector< Desc > getSubOpDescriptions()
Definition:DWARFExpression.cpp:126
llvm::DIDumpOptions
Container for dump options that control which debug information will be dumped.
Definition:DIContext.h:196
llvm::DIDumpOptions::IsEH
bool IsEH
Definition:DIContext.h:209
llvm::DIDumpOptions::GetNameForDWARFReg
std::function< llvm::StringRef(uint64_t DwarfRegNum, bool IsEH)> GetNameForDWARFReg
Definition:DIContext.h:214
llvm::DIDumpOptions::Verbose
bool Verbose
Definition:DIContext.h:207
llvm::DWARFExpression::Operation::Description
Description of the encoding of one expression Op.
Definition:DWARFExpression.h:66
llvm::DWARFExpression::Operation::Description::Version
DwarfVersion Version
Dwarf version where the Op was introduced.
Definition:DWARFExpression.h:67
llvm::DWARFExpression::Operation::Description::Op
SmallVector< Encoding > Op
Encoding for Op operands.
Definition:DWARFExpression.h:68
llvm::PrintedExpr
A user-facing string representation of a DWARF expression.
Definition:DWARFExpression.cpp:430
llvm::PrintedExpr::ExprKind
ExprKind
Definition:DWARFExpression.cpp:431
llvm::PrintedExpr::Address
@ Address
Definition:DWARFExpression.cpp:432
llvm::PrintedExpr::Value
@ Value
Definition:DWARFExpression.cpp:433
llvm::PrintedExpr::PrintedExpr
PrintedExpr(ExprKind K=Address)
Definition:DWARFExpression.cpp:438
llvm::PrintedExpr::Kind
ExprKind Kind
Definition:DWARFExpression.cpp:435
llvm::PrintedExpr::String
SmallString< 16 > String
Definition:DWARFExpression.cpp:436

Generated on Sun Jul 20 2025 09:09:07 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp