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