1 //===- bolt/Utils/Utils.cpp - Common helper functions ---------------------===//
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 // Common helper functions.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "bolt/Utils/Utils.h"
14 #include "llvm/BinaryFormat/Dwarf.h"
15 #include "llvm/MC/MCDwarf.h"
16 #include "llvm/Support/LEB128.h"
17 #include "llvm/Support/raw_ostream.h"
18
19 namespace llvm {
20 namespace bolt {
21
report_error(StringRef Message,std::error_code EC)22 void report_error(StringRef Message, std::error_code EC) {
23 assert(EC);
24 errs() << "BOLT-ERROR: '" << Message << "': " << EC.message() << ".\n";
25 exit(1);
26 }
27
report_error(StringRef Message,Error E)28 void report_error(StringRef Message, Error E) {
29 assert(E);
30 errs() << "BOLT-ERROR: '" << Message << "': " << toString(std::move(E))
31 << ".\n";
32 exit(1);
33 }
34
check_error(std::error_code EC,StringRef Message)35 void check_error(std::error_code EC, StringRef Message) {
36 if (!EC)
37 return;
38 report_error(Message, EC);
39 }
40
check_error(Error E,Twine Message)41 void check_error(Error E, Twine Message) {
42 if (!E)
43 return;
44 handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EIB) {
45 llvm::errs() << "BOLT-ERROR: '" << Message << "': " << EIB.message()
46 << '\n';
47 exit(1);
48 });
49 }
50
getEscapedName(const StringRef & Name)51 std::string getEscapedName(const StringRef &Name) {
52 std::string Output = Name.str();
53 for (size_t I = 0; I < Output.size(); ++I)
54 if (Output[I] == ' ' || Output[I] == '\\')
55 Output.insert(I++, 1, '\\');
56
57 return Output;
58 }
59
getUnescapedName(const StringRef & Name)60 std::string getUnescapedName(const StringRef &Name) {
61 std::string Output = Name.str();
62 for (size_t I = 0; I < Output.size(); ++I)
63 if (Output[I] == '\\')
64 Output.erase(I++, 1);
65
66 return Output;
67 }
68
readDWARFExpressionTargetReg(StringRef ExprBytes)69 Optional<uint8_t> readDWARFExpressionTargetReg(StringRef ExprBytes) {
70 uint8_t Opcode = ExprBytes[0];
71 if (Opcode == dwarf::DW_CFA_def_cfa_expression)
72 return NoneType();
73 assert((Opcode == dwarf::DW_CFA_expression ||
74 Opcode == dwarf::DW_CFA_val_expression) &&
75 "invalid DWARF expression CFI");
76 assert(ExprBytes.size() > 1 && "DWARF expression CFI is too short");
77 const uint8_t *const Start =
78 reinterpret_cast<const uint8_t *>(ExprBytes.drop_front(1).data());
79 const uint8_t *const End =
80 reinterpret_cast<const uint8_t *>(Start + ExprBytes.size() - 1);
81 uint8_t Reg = decodeULEB128(Start, nullptr, End);
82 return Reg;
83 }
84
85 } // namespace bolt
86
operator ==(const llvm::MCCFIInstruction & L,const llvm::MCCFIInstruction & R)87 bool operator==(const llvm::MCCFIInstruction &L,
88 const llvm::MCCFIInstruction &R) {
89 if (L.getOperation() != R.getOperation())
90 return false;
91 switch (L.getOperation()) {
92 case MCCFIInstruction::OpRestore:
93 case MCCFIInstruction::OpSameValue:
94 case MCCFIInstruction::OpUndefined:
95 case MCCFIInstruction::OpDefCfaRegister:
96 return L.getRegister() == R.getRegister();
97 case MCCFIInstruction::OpRegister:
98 return L.getRegister() == R.getRegister() &&
99 L.getRegister2() == R.getRegister2();
100 case MCCFIInstruction::OpOffset:
101 case MCCFIInstruction::OpRelOffset:
102 case MCCFIInstruction::OpDefCfa:
103 return L.getRegister() == R.getRegister() && L.getOffset() == R.getOffset();
104 case MCCFIInstruction::OpEscape:
105 return L.getValues() == R.getValues();
106 case MCCFIInstruction::OpRememberState:
107 case MCCFIInstruction::OpRestoreState:
108 return true;
109 case MCCFIInstruction::OpDefCfaOffset:
110 case MCCFIInstruction::OpAdjustCfaOffset:
111 return L.getOffset() == R.getOffset();
112 default:
113 return false;
114 }
115 }
116
117 } // namespace llvm
118