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 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 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 35 void check_error(std::error_code EC, StringRef Message) { 36 if (!EC) 37 return; 38 report_error(Message, EC); 39 } 40 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 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 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 69 std::optional<StringRef> getCommonName(const StringRef Name, bool KeepSuffix, 70 ArrayRef<StringRef> Suffixes) { 71 for (StringRef Suffix : Suffixes) { 72 size_t LTOSuffixPos = Name.find(Suffix); 73 if (LTOSuffixPos != StringRef::npos) 74 return Name.substr(0, LTOSuffixPos + (KeepSuffix ? Suffix.size() : 0)); 75 } 76 return std::nullopt; 77 } 78 79 std::optional<StringRef> getLTOCommonName(const StringRef Name) { 80 return getCommonName(Name, true, 81 {".__uniq.", ".lto_priv.", ".constprop.", ".llvm."}); 82 } 83 84 std::optional<uint8_t> readDWARFExpressionTargetReg(StringRef ExprBytes) { 85 uint8_t Opcode = ExprBytes[0]; 86 if (Opcode == dwarf::DW_CFA_def_cfa_expression) 87 return std::nullopt; 88 assert((Opcode == dwarf::DW_CFA_expression || 89 Opcode == dwarf::DW_CFA_val_expression) && 90 "invalid DWARF expression CFI"); 91 assert(ExprBytes.size() > 1 && "DWARF expression CFI is too short"); 92 const uint8_t *const Start = 93 reinterpret_cast<const uint8_t *>(ExprBytes.drop_front(1).data()); 94 const uint8_t *const End = 95 reinterpret_cast<const uint8_t *>(Start + ExprBytes.size() - 1); 96 uint8_t Reg = decodeULEB128(Start, nullptr, End); 97 return Reg; 98 } 99 100 } // namespace bolt 101 102 bool operator==(const llvm::MCCFIInstruction &L, 103 const llvm::MCCFIInstruction &R) { 104 if (L.getOperation() != R.getOperation()) 105 return false; 106 switch (L.getOperation()) { 107 case MCCFIInstruction::OpRestore: 108 case MCCFIInstruction::OpSameValue: 109 case MCCFIInstruction::OpUndefined: 110 case MCCFIInstruction::OpDefCfaRegister: 111 return L.getRegister() == R.getRegister(); 112 case MCCFIInstruction::OpRegister: 113 return L.getRegister() == R.getRegister() && 114 L.getRegister2() == R.getRegister2(); 115 case MCCFIInstruction::OpOffset: 116 case MCCFIInstruction::OpRelOffset: 117 case MCCFIInstruction::OpDefCfa: 118 return L.getRegister() == R.getRegister() && L.getOffset() == R.getOffset(); 119 case MCCFIInstruction::OpEscape: 120 return L.getValues() == R.getValues(); 121 case MCCFIInstruction::OpRememberState: 122 case MCCFIInstruction::OpRestoreState: 123 return true; 124 case MCCFIInstruction::OpDefCfaOffset: 125 case MCCFIInstruction::OpAdjustCfaOffset: 126 return L.getOffset() == R.getOffset(); 127 default: 128 return false; 129 } 130 } 131 132 } // namespace llvm 133