diff --git a/llvm/lib/ProfileData/InstrProfCorrelator.cpp b/llvm/lib/ProfileData/InstrProfCorrelator.cpp --- a/llvm/lib/ProfileData/InstrProfCorrelator.cpp +++ b/llvm/lib/ProfileData/InstrProfCorrelator.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "llvm/ProfileData/InstrProfCorrelator.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h" #include "llvm/Object/MachO.h" #include "llvm/Support/Debug.h" #include "llvm/Support/FileSystem.h" @@ -127,6 +128,10 @@ Error InstrProfCorrelatorImpl::correlateProfileData() { assert(Data.empty() && CompressedNames.empty() && Names.empty()); correlateProfileDataImpl(); + if (Data.empty() || Names.empty()) + return make_error( + instrprof_error::unable_to_correlate_profile, + "could not find any profile metadata in debug info"); auto Result = collectPGOFuncNameStrings(Names, /*doCompression=*/true, CompressedNames); CounterOffsets.clear(); @@ -167,13 +172,27 @@ return {}; } auto &DU = *Die.getDwarfUnit(); + bool isLE = DICtx->isLittleEndian(); + auto AddressSize = DU.getAddressByteSize(); + const auto &DObj = DICtx->getDWARFObj(); + DWARFDataExtractor AddrSectionData(DObj, DObj.getAddrSection(), isLE, + AddressSize); for (auto &Location : *Locations) { - auto AddressSize = DU.getAddressByteSize(); - DataExtractor Data(Location.Expr, DICtx->isLittleEndian(), AddressSize); + DataExtractor Data(Location.Expr, isLE, AddressSize); DWARFExpression Expr(Data, AddressSize); - for (auto &Op : Expr) - if (Op.getCode() == dwarf::DW_OP_addr) + for (auto &Op : Expr) { + if (Op.getCode() == dwarf::DW_OP_addr) { return Op.getRawOperand(0); + } else if (Op.getCode() == dwarf::DW_OP_addrx) { + uint64_t Index = Op.getRawOperand(0); + auto Offset = DU.getAddrOffsetSectionBase(); + if (!Offset.hasValue()) + continue; + // FIXME: Perhaps we should be using DWARFDebugAddrTable + uint64_t RawOffset = *Offset + Index * AddressSize; + return AddrSectionData.getAddress(&RawOffset); + } + } } return {}; }