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