[llvm] Move function info word into its own data structure (PR #153627)

via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 14 13:25:36 PDT 2025


https://github.com/Sterling-Augustine updated https://github.com/llvm/llvm-project/pull/153627

>From a2b6288eba18d506969d93c2a9ac335946e214df Mon Sep 17 00:00:00 2001
From: Sterling Augustine <saugustine at google.com>
Date: Thu, 14 Aug 2025 10:28:53 -0700
Subject: [PATCH 1/2] Move function info word into its own data structure

The sframe generator needs to construct this word separately from
FDEs themselves, so split them into a separate data structure.
---
 llvm/include/llvm/BinaryFormat/SFrame.h    | 20 ++++++----
 llvm/lib/Object/SFrameParser.cpp           |  4 +-
 llvm/tools/llvm-readobj/ELFDumper.cpp      | 21 ++++++-----
 llvm/unittests/BinaryFormat/SFrameTest.cpp | 44 +++++++++++-----------
 4 files changed, 48 insertions(+), 41 deletions(-)

diff --git a/llvm/include/llvm/BinaryFormat/SFrame.h b/llvm/include/llvm/BinaryFormat/SFrame.h
index 74e47ea8acca9..a02b1589f81c9 100644
--- a/llvm/include/llvm/BinaryFormat/SFrame.h
+++ b/llvm/include/llvm/BinaryFormat/SFrame.h
@@ -104,14 +104,8 @@ template <endianness E> struct Header {
   detail::packed<uint32_t, E> FREOff;
 };
 
-template <endianness E> struct FuncDescEntry {
-  detail::packed<int32_t, E> StartAddress;
-  detail::packed<uint32_t, E> Size;
-  detail::packed<uint32_t, E> StartFREOff;
-  detail::packed<uint32_t, E> NumFREs;
-  detail::packed<uint8_t, E> Info;
-  detail::packed<uint8_t, E> RepSize;
-  detail::packed<uint16_t, E> Padding2;
+struct FDEInfo {
+  uint8_t Info;
 
   uint8_t getPAuthKey() const { return (Info >> 5) & 1; }
   FDEType getFDEType() const { return static_cast<FDEType>((Info >> 4) & 1); }
@@ -125,6 +119,16 @@ template <endianness E> struct FuncDescEntry {
   }
 };
 
+template <endianness E> struct FuncDescEntry {
+  detail::packed<int32_t, E> StartAddress;
+  detail::packed<uint32_t, E> Size;
+  detail::packed<uint32_t, E> StartFREOff;
+  detail::packed<uint32_t, E> NumFREs;
+  FDEInfo Info;
+  detail::packed<uint8_t, E> RepSize;
+  detail::packed<uint16_t, E> Padding2;
+};
+
 template <endianness E> struct FREInfo {
   detail::packed<uint8_t, E> Info;
 
diff --git a/llvm/lib/Object/SFrameParser.cpp b/llvm/lib/Object/SFrameParser.cpp
index 847067a7ae989..c49a02907367f 100644
--- a/llvm/lib/Object/SFrameParser.cpp
+++ b/llvm/lib/Object/SFrameParser.cpp
@@ -173,10 +173,10 @@ iterator_range<typename SFrameParser<E>::fre_iterator>
 SFrameParser<E>::fres(const sframe::FuncDescEntry<E> &FDE, Error &Err) const {
   uint64_t Offset = getFREBase() + FDE.StartFREOff;
   fre_iterator BeforeBegin = make_fallible_itr(
-      FallibleFREIterator(Data, FDE.getFREType(), -1, FDE.NumFREs, Offset),
+      FallibleFREIterator(Data, FDE.Info.getFREType(), -1, FDE.NumFREs, Offset),
       Err);
   fre_iterator End = make_fallible_end(
-      FallibleFREIterator(Data, FDE.getFREType(), FDE.NumFREs, FDE.NumFREs,
+      FallibleFREIterator(Data, FDE.Info.getFREType(), FDE.NumFREs, FDE.NumFREs,
                           /*Offset=*/0));
   return {++BeforeBegin, End};
 }
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index ed29e0bf3f7cd..731250532402a 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -6505,12 +6505,13 @@ void ELFDumper<ELFT>::printSFrameFDEs(
 
     {
       DictScope InfoScope(W, "Info");
-      W.printEnum("FRE Type", It->getFREType(), sframe::getFRETypes());
-      W.printEnum("FDE Type", It->getFDEType(), sframe::getFDETypes());
+      W.printEnum("FRE Type", It->Info.getFREType(), sframe::getFRETypes());
+      W.printEnum("FDE Type", It->Info.getFDEType(), sframe::getFDETypes());
       switch (Parser.getHeader().ABIArch) {
       case sframe::ABI::AArch64EndianBig:
       case sframe::ABI::AArch64EndianLittle:
-        W.printEnum("PAuth Key", sframe::AArch64PAuthKey(It->getPAuthKey()),
+        W.printEnum("PAuth Key",
+                    sframe::AArch64PAuthKey(It->Info.getPAuthKey()),
                     sframe::getAArch64PAuthKeys());
         break;
       case sframe::ABI::AMD64EndianLittle:
@@ -6518,12 +6519,13 @@ void ELFDumper<ELFT>::printSFrameFDEs(
         break;
       }
 
-      W.printHex("Raw", It->Info);
+      W.printHex("Raw", It->Info.Info);
     }
 
     W.printHex(
         ("Repetitive block size" +
-         Twine(It->getFDEType() == sframe::FDEType::PCMask ? "" : " (unused)"))
+         Twine(It->Info.getFDEType() == sframe::FDEType::PCMask ? ""
+                                                                : " (unused)"))
             .str(),
         It->RepSize);
 
@@ -6534,10 +6536,11 @@ void ELFDumper<ELFT>::printSFrameFDEs(
     for (const typename SFrameParser<ELFT::Endianness>::FrameRowEntry &FRE :
          Parser.fres(*It, Err)) {
       DictScope FREScope(W, "Frame Row Entry");
-      W.printHex(
-          "Start Address",
-          (It->getFDEType() == sframe::FDEType::PCInc ? FDEStartAddress : 0) +
-              FRE.StartAddress);
+      W.printHex("Start Address",
+                 (It->Info.getFDEType() == sframe::FDEType::PCInc
+                      ? FDEStartAddress
+                      : 0) +
+                     FRE.StartAddress);
       W.printBoolean("Return Address Signed", FRE.Info.isReturnAddressSigned());
       W.printEnum("Offset Size", FRE.Info.getOffsetSize(),
                   sframe::getFREOffsets());
diff --git a/llvm/unittests/BinaryFormat/SFrameTest.cpp b/llvm/unittests/BinaryFormat/SFrameTest.cpp
index 394e382e041e9..ab7b0fe20b750 100644
--- a/llvm/unittests/BinaryFormat/SFrameTest.cpp
+++ b/llvm/unittests/BinaryFormat/SFrameTest.cpp
@@ -54,28 +54,28 @@ TYPED_TEST_SUITE(SFrameTest, Types, NameGenerator);
 
 TYPED_TEST(SFrameTest, FDEFlags) {
   FuncDescEntry<TestFixture::Endian> FDE = {};
-  EXPECT_EQ(FDE.Info, 0u);
-  EXPECT_EQ(FDE.getPAuthKey(), 0);
-  EXPECT_EQ(FDE.getFDEType(), FDEType::PCInc);
-  EXPECT_EQ(FDE.getFREType(), FREType::Addr1);
-
-  FDE.setPAuthKey(1);
-  EXPECT_EQ(FDE.Info, 0x20u);
-  EXPECT_EQ(FDE.getPAuthKey(), 1);
-  EXPECT_EQ(FDE.getFDEType(), FDEType::PCInc);
-  EXPECT_EQ(FDE.getFREType(), FREType::Addr1);
-
-  FDE.setFDEType(FDEType::PCMask);
-  EXPECT_EQ(FDE.Info, 0x30u);
-  EXPECT_EQ(FDE.getPAuthKey(), 1);
-  EXPECT_EQ(FDE.getFDEType(), FDEType::PCMask);
-  EXPECT_EQ(FDE.getFREType(), FREType::Addr1);
-
-  FDE.setFREType(FREType::Addr4);
-  EXPECT_EQ(FDE.Info, 0x32u);
-  EXPECT_EQ(FDE.getPAuthKey(), 1);
-  EXPECT_EQ(FDE.getFDEType(), FDEType::PCMask);
-  EXPECT_EQ(FDE.getFREType(), FREType::Addr4);
+  EXPECT_EQ(FDE.Info.Info, 0u);
+  EXPECT_EQ(FDE.Info.getPAuthKey(), 0);
+  EXPECT_EQ(FDE.Info.getFDEType(), FDEType::PCInc);
+  EXPECT_EQ(FDE.Info.getFREType(), FREType::Addr1);
+
+  FDE.Info.setPAuthKey(1);
+  EXPECT_EQ(FDE.Info.Info, 0x20u);
+  EXPECT_EQ(FDE.Info.getPAuthKey(), 1);
+  EXPECT_EQ(FDE.Info.getFDEType(), FDEType::PCInc);
+  EXPECT_EQ(FDE.Info.getFREType(), FREType::Addr1);
+
+  FDE.Info.setFDEType(FDEType::PCMask);
+  EXPECT_EQ(FDE.Info.Info, 0x30u);
+  EXPECT_EQ(FDE.Info.getPAuthKey(), 1);
+  EXPECT_EQ(FDE.Info.getFDEType(), FDEType::PCMask);
+  EXPECT_EQ(FDE.Info.getFREType(), FREType::Addr1);
+
+  FDE.Info.setFREType(FREType::Addr4);
+  EXPECT_EQ(FDE.Info.Info, 0x32u);
+  EXPECT_EQ(FDE.Info.getPAuthKey(), 1);
+  EXPECT_EQ(FDE.Info.getFDEType(), FDEType::PCMask);
+  EXPECT_EQ(FDE.Info.getFREType(), FREType::Addr4);
 }
 
 TYPED_TEST(SFrameTest, FREFlags) {

>From 16549c1f76daeb2db8742e65bafa66db5b8131e9 Mon Sep 17 00:00:00 2001
From: Sterling Augustine <saugustine at google.com>
Date: Thu, 14 Aug 2025 12:54:26 -0700
Subject: [PATCH 2/2] Endianify FuncInfo

---
 llvm/include/llvm/BinaryFormat/SFrame.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/include/llvm/BinaryFormat/SFrame.h b/llvm/include/llvm/BinaryFormat/SFrame.h
index a02b1589f81c9..095db18b9c254 100644
--- a/llvm/include/llvm/BinaryFormat/SFrame.h
+++ b/llvm/include/llvm/BinaryFormat/SFrame.h
@@ -104,8 +104,8 @@ template <endianness E> struct Header {
   detail::packed<uint32_t, E> FREOff;
 };
 
-struct FDEInfo {
-  uint8_t Info;
+template <endianness E> struct FDEInfo {
+  detail::packed<uint8_t, E> Info;
 
   uint8_t getPAuthKey() const { return (Info >> 5) & 1; }
   FDEType getFDEType() const { return static_cast<FDEType>((Info >> 4) & 1); }
@@ -124,7 +124,7 @@ template <endianness E> struct FuncDescEntry {
   detail::packed<uint32_t, E> Size;
   detail::packed<uint32_t, E> StartFREOff;
   detail::packed<uint32_t, E> NumFREs;
-  FDEInfo Info;
+  FDEInfo<E> Info;
   detail::packed<uint8_t, E> RepSize;
   detail::packed<uint16_t, E> Padding2;
 };



More information about the llvm-commits mailing list