[llvm] [GSYM] Fix the initialization of DataExtractor (PR #67904)

Kazu Hirata via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 1 00:20:46 PDT 2023


https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/67904

Without this patch, we pass Endian as one of the parameters to the
constructor of DataExtractor.  The problem is that Endian is of:

  enum endianness {big, little, native};

whereas the constructor is expecting "bool IsLittleEndian".  That is,
we are relying on an implicit conversion to convert big and little to
false and true, respectively.

When we migrate llvm::support::endianness to std::endian in future, we
can no longer rely on an implicit conversion because std::endian is
declared with "enum class".  Even if we could, the conversion would
not be guaranteed to work because, for example, libcxx defines:

  enum class endian {
    little = 0xDEAD,
    big = 0xFACE,
    :

where big and little are not boolean values.

This patch fixes the problem by properly converting Endian to a
boolean value.


>From 698e592df0328330577aa5ee57304cb85680b270 Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Sat, 30 Sep 2023 23:17:41 -0700
Subject: [PATCH] [GSYM] Fix the initialization of DataExtractor

Without this patch, we pass Endian as one of the parameters to the
constructor of DataExtractor.  The problem is that Endian is of:

  enum endianness {big, little, native};

whereas the constructor is expecting "bool IsLittleEndian".  That is,
we are relying on an implicit conversion to convert big and little to
false and true, respectively.

When we migrate llvm::support::endianness to std::endian in future, we
can no longer rely on an implicit conversion because std::endian is
declared with "enum class".  Even if we could, the conversion would
not be guaranteed to work because, for example, libcxx defines:

  enum class endian {
    little = 0xDEAD,
    big = 0xFACE,
    :

where big and little are not boolean values.

This patch fixes the problem by properly converting Endian to a
boolean value.
---
 llvm/lib/DebugInfo/GSYM/GsymReader.cpp | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/DebugInfo/GSYM/GsymReader.cpp b/llvm/lib/DebugInfo/GSYM/GsymReader.cpp
index 6afaeea8f598e12..689d8f83f4b2204 100644
--- a/llvm/lib/DebugInfo/GSYM/GsymReader.cpp
+++ b/llvm/lib/DebugInfo/GSYM/GsymReader.cpp
@@ -261,7 +261,10 @@ llvm::Expected<FunctionInfo> GsymReader::getFunctionInfo(uint64_t Addr) const {
   // Address info offsets size should have been checked in parse().
   assert(*AddressIndex < AddrInfoOffsets.size());
   auto AddrInfoOffset = AddrInfoOffsets[*AddressIndex];
-  DataExtractor Data(MemBuffer->getBuffer().substr(AddrInfoOffset), Endian, 4);
+  assert((Endian == support::big || Endian == support::little) &&
+         "Endian must be either big or little");
+  DataExtractor Data(MemBuffer->getBuffer().substr(AddrInfoOffset),
+                     Endian == support::little, 4);
   if (std::optional<uint64_t> OptAddr = getAddress(*AddressIndex)) {
     auto ExpectedFI = FunctionInfo::decode(Data, *OptAddr);
     if (ExpectedFI) {
@@ -283,7 +286,10 @@ llvm::Expected<LookupResult> GsymReader::lookup(uint64_t Addr) const {
   // Address info offsets size should have been checked in parse().
   assert(*AddressIndex < AddrInfoOffsets.size());
   auto AddrInfoOffset = AddrInfoOffsets[*AddressIndex];
-  DataExtractor Data(MemBuffer->getBuffer().substr(AddrInfoOffset), Endian, 4);
+  assert((Endian == support::big || Endian == support::little) &&
+         "Endian must be either big or little");
+  DataExtractor Data(MemBuffer->getBuffer().substr(AddrInfoOffset),
+                     Endian == support::little, 4);
   if (std::optional<uint64_t> OptAddr = getAddress(*AddressIndex))
     return FunctionInfo::lookup(Data, *this, *OptAddr, Addr);
   return createStringError(std::errc::invalid_argument,



More information about the llvm-commits mailing list