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