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