[llvm] Modify llvm-gsymutil lookups to handle overlapping ranges correctly. (PR #72350)
Alexander Yermolovich via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 15 16:19:21 PST 2023
================
@@ -253,49 +253,66 @@ GsymReader::getAddressIndex(const uint64_t Addr) const {
}
-llvm::Expected<FunctionInfo> GsymReader::getFunctionInfo(uint64_t Addr) const {
- Expected<uint64_t> AddressIndex = getAddressIndex(Addr);
- if (!AddressIndex)
- return AddressIndex.takeError();
- // Address info offsets size should have been checked in parse().
- assert(*AddressIndex < AddrInfoOffsets.size());
- auto AddrInfoOffset = AddrInfoOffsets[*AddressIndex];
- assert(
- (Endian == llvm::endianness::big || Endian == llvm::endianness::little) &&
- "Endian must be either big or little");
- DataExtractor Data(MemBuffer->getBuffer().substr(AddrInfoOffset),
- Endian == llvm::endianness::little, 4);
- if (std::optional<uint64_t> OptAddr = getAddress(*AddressIndex)) {
- auto ExpectedFI = FunctionInfo::decode(Data, *OptAddr);
- if (ExpectedFI) {
- if (ExpectedFI->Range.contains(Addr) || ExpectedFI->Range.size() == 0)
- return ExpectedFI;
+llvm::Expected<DataExtractor>
+GsymReader::getFunctionInfoData(uint64_t Addr, uint64_t &FuncAddr) const {
+ Expected<uint64_t> ExpectedAddrIdx = getAddressIndex(Addr);
+ if (!ExpectedAddrIdx)
+ return ExpectedAddrIdx.takeError();
+ const uint64_t FirstAddrIdx = *ExpectedAddrIdx;
+ std::optional<uint64_t> OptFirstAddr = getAddress(FirstAddrIdx);
+ if (!OptFirstAddr)
+ return createStringError(std::errc::invalid_argument,
+ "failed to extract address[%" PRIu64 "]",
+ FirstAddrIdx);
+ // The AddrIdx is the first index of the function info entries that match
+ // \a Addr. We need to iterate over all function info objects that start with
+ // the same address until we find a match.
+ const auto FirstAddr = *OptFirstAddr;
+ const size_t NumAddresses = getNumAddresses();
+ assert((Endian == endianness::big || Endian == endianness::little) &&
+ "Endian must be either big or little");
+ for (uint64_t AddrIdx = FirstAddrIdx; AddrIdx < NumAddresses; ++AddrIdx) {
+ // Extract the function address and make sure it matches FirstAddr
+ std::optional<uint64_t> OptFuncAddr = getAddress(AddrIdx);
+ if (!OptFuncAddr)
return createStringError(std::errc::invalid_argument,
- "address 0x%" PRIx64 " is not in GSYM", Addr);
+ "failed to extract address[%" PRIu64 "]",
+ AddrIdx);
+ if (*OptFuncAddr != FirstAddr)
+ break; // Done with consecutive function info entries with same address.
+
+ // Address info offsets size should have been checked in parse().
+ auto AddrInfoOffset = AddrInfoOffsets[AddrIdx];
----------------
ayermolo wrote:
I realize it was auto in original code, but can we change it to actual type?
https://github.com/llvm/llvm-project/pull/72350
More information about the llvm-commits
mailing list