Skip to content

Conversation

@labath
Copy link
Collaborator

@labath labath commented Aug 8, 2025

Reverts #151301 - build breakage on multiple bots.

@llvmbot
Copy link
Member

llvmbot commented Aug 8, 2025

@llvm/pr-subscribers-llvm-binary-utilities

Author: Pavel Labath (labath)

Changes

Reverts llvm/llvm-project#151301 - build breakage on multiple bots.


Patch is 23.68 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/152650.diff

7 Files Affected:

  • (modified) llvm/include/llvm/BinaryFormat/SFrame.h (-1)
  • (modified) llvm/include/llvm/Object/SFrameParser.h (-51)
  • (modified) llvm/lib/BinaryFormat/SFrame.cpp (-8)
  • (modified) llvm/lib/Object/SFrameParser.cpp (+4-128)
  • (modified) llvm/test/tools/llvm-readobj/ELF/sframe-fde.test (+2-8)
  • (removed) llvm/test/tools/llvm-readobj/ELF/sframe-fre.test (-284)
  • (modified) llvm/tools/llvm-readobj/ELFDumper.cpp (+1-28)
diff --git a/llvm/include/llvm/BinaryFormat/SFrame.h b/llvm/include/llvm/BinaryFormat/SFrame.h
index 74e47ea8acca9..0c6c4d176eaec 100644
--- a/llvm/include/llvm/BinaryFormat/SFrame.h
+++ b/llvm/include/llvm/BinaryFormat/SFrame.h
@@ -169,7 +169,6 @@ LLVM_ABI ArrayRef<EnumEntry<FREType>> getFRETypes();
 LLVM_ABI ArrayRef<EnumEntry<FDEType>> getFDETypes();
 LLVM_ABI ArrayRef<EnumEntry<AArch64PAuthKey>> getAArch64PAuthKeys();
 LLVM_ABI ArrayRef<EnumEntry<FREOffset>> getFREOffsets();
-LLVM_ABI ArrayRef<EnumEntry<BaseReg>> getBaseRegisters();
 
 } // namespace sframe
 } // namespace llvm
diff --git a/llvm/include/llvm/Object/SFrameParser.h b/llvm/include/llvm/Object/SFrameParser.h
index 539bb1872cc99..245e7ba40d0b8 100644
--- a/llvm/include/llvm/Object/SFrameParser.h
+++ b/llvm/include/llvm/Object/SFrameParser.h
@@ -10,7 +10,6 @@
 #define LLVM_OBJECT_SFRAME_H
 
 #include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/fallible_iterator.h"
 #include "llvm/BinaryFormat/SFrame.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Error.h"
@@ -20,8 +19,6 @@ namespace llvm {
 namespace object {
 
 template <endianness E> class SFrameParser {
-  class FallibleFREIterator;
-
 public:
   static Expected<SFrameParser> create(ArrayRef<uint8_t> Contents,
                                        uint64_t SectionAddress);
@@ -45,21 +42,6 @@ template <endianness E> class SFrameParser {
   // objects returned by the `fdes()` function.
   uint64_t getAbsoluteStartAddress(typename FDERange::iterator FDE) const;
 
-  struct FrameRowEntry {
-    uint32_t StartAddress;
-    sframe::FREInfo<endianness::native> Info;
-    SmallVector<int32_t, 3> Offsets;
-  };
-
-  using fre_iterator = fallible_iterator<FallibleFREIterator>;
-  iterator_range<fre_iterator> fres(const sframe::FuncDescEntry<E> &FDE,
-                                    Error &Err) const;
-
-  std::optional<int32_t> getCFAOffset(const FrameRowEntry &FRE) const;
-  std::optional<int32_t> getRAOffset(const FrameRowEntry &FRE) const;
-  std::optional<int32_t> getFPOffset(const FrameRowEntry &FRE) const;
-  ArrayRef<int32_t> getExtraOffsets(const FrameRowEntry &FRE) const;
-
 private:
   ArrayRef<uint8_t> Data;
   uint64_t SectionAddress;
@@ -72,39 +54,6 @@ template <endianness E> class SFrameParser {
   uint64_t getFDEBase() const {
     return sizeof(Header) + Header.AuxHdrLen + Header.FDEOff;
   }
-
-  uint64_t getFREBase() const {
-    return getFDEBase() + Header.NumFDEs * sizeof(sframe::FuncDescEntry<E>);
-  }
-};
-
-template <endianness E> class SFrameParser<E>::FallibleFREIterator {
-public:
-  // NB: This iterator starts out in the before_begin() state. It must be
-  // ++'ed to reach the first element.
-  FallibleFREIterator(ArrayRef<uint8_t> Data, sframe::FREType FREType,
-                      uint32_t Idx, uint32_t Size, uint64_t Offset)
-      : Data(Data), FREType(FREType), Idx(Idx), Size(Size), Offset(Offset) {}
-
-  Error inc();
-  const FrameRowEntry &operator*() const { return FRE; }
-
-  friend bool operator==(const FallibleFREIterator &LHS,
-                         const FallibleFREIterator &RHS) {
-    assert(LHS.Data.data() == RHS.Data.data());
-    assert(LHS.Data.size() == RHS.Data.size());
-    assert(LHS.FREType == RHS.FREType);
-    assert(LHS.Size == RHS.Size);
-    return LHS.Idx == RHS.Idx;
-  }
-
-private:
-  ArrayRef<uint8_t> Data;
-  sframe::FREType FREType;
-  uint32_t Idx;
-  uint32_t Size;
-  uint64_t Offset;
-  FrameRowEntry FRE;
 };
 
 extern template class LLVM_TEMPLATE_ABI SFrameParser<endianness::big>;
diff --git a/llvm/lib/BinaryFormat/SFrame.cpp b/llvm/lib/BinaryFormat/SFrame.cpp
index 8076a26f27f32..f1765d7f3e852 100644
--- a/llvm/lib/BinaryFormat/SFrame.cpp
+++ b/llvm/lib/BinaryFormat/SFrame.cpp
@@ -68,11 +68,3 @@ ArrayRef<EnumEntry<sframe::FREOffset>> sframe::getFREOffsets() {
   };
   return ArrayRef(FREOffsets);
 }
-
-ArrayRef<EnumEntry<sframe::BaseReg>> sframe::getBaseRegisters() {
-  static constexpr EnumEntry<sframe::BaseReg> BaseRegs[] = {
-      {"FP", sframe::BaseReg::FP},
-      {"SP", sframe::BaseReg::SP},
-  };
-  return ArrayRef(BaseRegs);
-}
diff --git a/llvm/lib/Object/SFrameParser.cpp b/llvm/lib/Object/SFrameParser.cpp
index 825b7af368211..5863490634e32 100644
--- a/llvm/lib/Object/SFrameParser.cpp
+++ b/llvm/lib/Object/SFrameParser.cpp
@@ -32,25 +32,14 @@ getDataSlice(ArrayRef<uint8_t> Data, uint64_t Offset, uint64_t Size) {
 }
 
 template <typename T>
-static Expected<ArrayRef<T>>
-getDataSliceAsArrayOf(ArrayRef<uint8_t> Data, uint64_t Offset, uint64_t Count) {
+static Expected<const T &> getDataSliceAs(ArrayRef<uint8_t> Data,
+                                          uint64_t Offset) {
   static_assert(std::is_trivial_v<T>);
-  Expected<ArrayRef<uint8_t>> Slice =
-      getDataSlice(Data, Offset, sizeof(T) * Count);
+  Expected<ArrayRef<uint8_t>> Slice = getDataSlice(Data, Offset, sizeof(T));
   if (!Slice)
     return Slice.takeError();
 
-  return ArrayRef(reinterpret_cast<const T *>(Slice->data()), Count);
-}
-
-template <typename T>
-static Expected<const T &> getDataSliceAs(ArrayRef<uint8_t> Data,
-                                          uint64_t Offset) {
-  Expected<ArrayRef<T>> Array = getDataSliceAsArrayOf<T>(Data, Offset, 1);
-  if (!Array)
-    return Array.takeError();
-
-  return Array->front();
+  return *reinterpret_cast<const T *>(Slice->data());
 }
 
 template <endianness E>
@@ -111,119 +100,6 @@ uint64_t SFrameParser<E>::getAbsoluteStartAddress(
   return Result;
 }
 
-template <typename EndianT>
-static Error readArray(ArrayRef<uint8_t> Data, uint64_t Count, uint64_t &Offset,
-                       SmallVectorImpl<int32_t> &Vec) {
-  Expected<ArrayRef<EndianT>> RawArray =
-      getDataSliceAsArrayOf<EndianT>(Data, Offset, Count);
-  if (!RawArray)
-    return RawArray.takeError();
-  Offset += Count * sizeof(EndianT);
-  Vec.resize(Count);
-  llvm::copy(*RawArray, Vec.begin());
-  return Error::success();
-}
-
-template <typename T, endianness E>
-static Error readFRE(ArrayRef<uint8_t> Data, uint64_t &Offset,
-                     typename SFrameParser<E>::FrameRowEntry &FRE) {
-  Expected<sframe::FrameRowEntry<T, E>> RawFRE =
-      getDataSliceAs<sframe::FrameRowEntry<T, E>>(Data, Offset);
-  if (!RawFRE)
-    return RawFRE.takeError();
-
-  Offset += sizeof(*RawFRE);
-  FRE.StartAddress = RawFRE->StartAddress;
-  FRE.Info.Info = RawFRE->Info.Info;
-
-  switch (FRE.Info.getOffsetSize()) {
-  case sframe::FREOffset::B1:
-    return readArray<sframe::detail::packed<int8_t, E>>(
-        Data, FRE.Info.getOffsetCount(), Offset, FRE.Offsets);
-  case sframe::FREOffset::B2:
-    return readArray<sframe::detail::packed<int16_t, E>>(
-        Data, FRE.Info.getOffsetCount(), Offset, FRE.Offsets);
-  case sframe::FREOffset::B4:
-    return readArray<sframe::detail::packed<int32_t, E>>(
-        Data, FRE.Info.getOffsetCount(), Offset, FRE.Offsets);
-  default:
-    return createError("unsupported/unknown offset size");
-  }
-}
-
-template <endianness E> Error SFrameParser<E>::FallibleFREIterator::inc() {
-  if (++Idx == Size)
-    return Error::success();
-
-  switch (FREType) {
-  case sframe::FREType::Addr1:
-    return readFRE<uint8_t, E>(Data, Offset, FRE);
-  case sframe::FREType::Addr2:
-    return readFRE<uint16_t, E>(Data, Offset, FRE);
-  case sframe::FREType::Addr4:
-    return readFRE<uint32_t, E>(Data, Offset, FRE);
-  default:
-    return createError("invalid/unsupported FRE type");
-  }
-}
-
-template <endianness E>
-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),
-      Err);
-  fre_iterator End = make_fallible_end(
-      FallibleFREIterator(Data, FDE.getFREType(), FDE.NumFREs, FDE.NumFREs,
-                          /*Offset=*/0));
-  return {++BeforeBegin, End};
-}
-
-static std::optional<int32_t> getOffset(ArrayRef<int32_t> Offsets, size_t Idx) {
-  if (Offsets.size() > Idx)
-    return Offsets[Idx];
-  return std::nullopt;
-}
-
-// The interpretation of offsets is ABI-specific. The implementation of this and
-// the following functions may need to be adjusted when adding support for a new
-// ABI.
-template <endianness E>
-std::optional<int32_t>
-SFrameParser<E>::getCFAOffset(const FrameRowEntry &FRE) const {
-  return getOffset(FRE.Offsets, 0);
-}
-
-template <endianness E>
-std::optional<int32_t>
-SFrameParser<E>::getRAOffset(const FrameRowEntry &FRE) const {
-  if (usesFixedRAOffset())
-    return Header.CFAFixedRAOffset;
-  return getOffset(FRE.Offsets, 1);
-}
-
-template <endianness E>
-std::optional<int32_t>
-SFrameParser<E>::getFPOffset(const FrameRowEntry &FRE) const {
-  if (usesFixedFPOffset())
-    return Header.CFAFixedFPOffset;
-  return getOffset(FRE.Offsets, usesFixedRAOffset() ? 1 : 2);
-}
-
-template <endianness E>
-ArrayRef<int32_t>
-SFrameParser<E>::getExtraOffsets(const FrameRowEntry &FRE) const {
-  size_t UsedOffsets = 1; // CFA
-  if (!usesFixedRAOffset())
-    ++UsedOffsets;
-  if (!usesFixedFPOffset())
-    ++UsedOffsets;
-  if (FRE.Offsets.size() > UsedOffsets)
-    return ArrayRef(FRE.Offsets).drop_front(UsedOffsets);
-  return {};
-}
-
 template class LLVM_EXPORT_TEMPLATE llvm::object::SFrameParser<endianness::big>;
 template class LLVM_EXPORT_TEMPLATE
     llvm::object::SFrameParser<endianness::little>;
diff --git a/llvm/test/tools/llvm-readobj/ELF/sframe-fde.test b/llvm/test/tools/llvm-readobj/ELF/sframe-fde.test
index b9075a81eba4b..dee40180c42e6 100644
--- a/llvm/test/tools/llvm-readobj/ELF/sframe-fde.test
+++ b/llvm/test/tools/llvm-readobj/ELF/sframe-fde.test
@@ -108,8 +108,6 @@ Sections:
 #  CASE1-NEXT:      }
 #  CASE1-NEXT:      Repetitive block size: 0xDE
 #  CASE1-NEXT:      Padding2: 0xAD
-#  CASE1-NEXT:      FREs [
-#  CASE1-NEXT:      ]
 #  CASE1-NEXT:    }
 #  CASE1-NEXT:  ]
 #  CASE1-NEXT:}
@@ -171,8 +169,6 @@ Sections:
 #  CASE1-NEXT:      }
 #  CASE1-NEXT:      Repetitive block size (unused): 0xDE
 #  CASE1-NEXT:      Padding2: 0xAD
-#  CASE1-NEXT:      FREs [
-#  CASE1-NEXT:      ]
 #  CASE1-NEXT:    }
 #  CASE1-NEXT:  ]
 #  CASE1-NEXT:}
@@ -200,7 +196,7 @@ Sections:
       0x00, 0xde, 0xad, 0x00,  # Start Address
       0x00, 0x00, 0x01, 0xbe,  # Size
       0x00, 0x00, 0x00, 0x10,  # Start FRE Offset
-      0x00, 0x00, 0x00, 0x00,  # Number of FREs
+      0x00, 0x00, 0x00, 0x10,  # Number of FREs
       0x02, 0xde, 0xad, 0x00,  # Info, RepSize, Padding2
     ]
 # CASE2-LABEL:SFrame section '.sframe' {
@@ -227,7 +223,7 @@ Sections:
 #  CASE2-NEXT:      PC: 0xDEAD1C
 #  CASE2-NEXT:      Size: 0x1BE
 #  CASE2-NEXT:      Start FRE Offset: 0x10
-#  CASE2-NEXT:      Num FREs: 0
+#  CASE2-NEXT:      Num FREs: 16
 #  CASE2-NEXT:      Info {
 #  CASE2-NEXT:        FRE Type: Addr4 (0x2)
 #  CASE2-NEXT:        FDE Type: PCInc (0x0)
@@ -236,8 +232,6 @@ Sections:
 #  CASE2-NEXT:      }
 #  CASE2-NEXT:      Repetitive block size (unused): 0xDE
 #  CASE2-NEXT:      Padding2: 0xAD00
-#  CASE2-NEXT:      FREs [
-#  CASE2-NEXT:      ]
 #  CASE2-NEXT:    }
 #  CASE2-NEXT:  ]
 #  CASE2-NEXT:}
diff --git a/llvm/test/tools/llvm-readobj/ELF/sframe-fre.test b/llvm/test/tools/llvm-readobj/ELF/sframe-fre.test
deleted file mode 100644
index 9711d04fe7974..0000000000000
--- a/llvm/test/tools/llvm-readobj/ELF/sframe-fre.test
+++ /dev/null
@@ -1,284 +0,0 @@
-# RUN: yaml2obj --docnum=1 %s -o %t.1
-# RUN: llvm-readobj --sframe=.sframe_eof_address --sframe=.sframe_eof_offset --sframe \
-# RUN:   %t.1 2>&1 | \
-# RUN:   FileCheck %s --strict-whitespace --match-full-lines \
-# RUN:   -DFILE=%t.1 --check-prefix=CASE1
-
-# RUN: yaml2obj --docnum=2 %s -o %t.2
-# RUN: llvm-readobj --sframe %t.2 2>&1 | \
-# RUN:   FileCheck %s --strict-whitespace --match-full-lines \
-# RUN:   -DFILE=%t.2 --check-prefix=CASE2
-
---- !ELF
-FileHeader:
-  Class:   ELFCLASS64
-  Data:    ELFDATA2LSB
-  Type:    ET_EXEC
-Sections:
-  - Name:  .sframe_eof_address
-    Type:  SHT_GNU_SFRAME
-    Flags: [ SHF_ALLOC ]
-    ContentArray: [
-      0xe2, 0xde, 0x02, 0x04,  # Preamble (magic, version, flags)
-      # Header:
-      0x03, 0x42, 0x47, 0x00,  # ABI, Fixed FP offset, Fixed RA Offset, AUX header length
-      0x01, 0x00, 0x00, 0x00,  # Number of FDEs
-      0x01, 0x00, 0x00, 0x00,  # Number of FREs
-      0x00, 0x10, 0x00, 0x00,  # FRE length
-      0x00, 0x00, 0x00, 0x00,  # FDE offset
-      0x00, 0x00, 0x00, 0x00,  # FRE offset
-
-      # FDE[0]:
-      0x00, 0xde, 0xad, 0x00,  # Start Address
-      0xbe, 0x01, 0x00, 0x00,  # Size
-      0x00, 0x00, 0x00, 0x00,  # Start FRE Offset
-      0x01, 0x00, 0x00, 0x00,  # Number of FREs
-      0x00, 0xde, 0xad, 0x00,  # Info, RepSize, Padding2
-
-      # FRE[0]:
-      0x00                     # Start Address, (missing) Info
-    ]
-# CASE1-LABEL:SFrame section '.sframe_eof_address' {
-#       CASE1:    FuncDescEntry [0] {
-#       CASE1:      Info {
-#  CASE1-NEXT:        FRE Type: Addr1 (0x0)
-#  CASE1-NEXT:        FDE Type: PCInc (0x0)
-#       CASE1:      FREs [
-#  CASE1-NEXT:{{.*}}: warning: '[[FILE]]': unexpected end of data at offset 0x31 while reading [0x30, 0x32)
-#  CASE1-NEXT:      ]
-
-  - Name:  .sframe_eof_offset
-    Type:  SHT_GNU_SFRAME
-    Flags: [ SHF_ALLOC ]
-    ContentArray: [
-      0xe2, 0xde, 0x02, 0x04,  # Preamble (magic, version, flags)
-      # Header:
-      0x03, 0x42, 0x47, 0x00,  # ABI, Fixed FP offset, Fixed RA Offset, AUX header length
-      0x01, 0x00, 0x00, 0x00,  # Number of FDEs
-      0x01, 0x00, 0x00, 0x00,  # Number of FREs
-      0x00, 0x10, 0x00, 0x00,  # FRE length
-      0x00, 0x00, 0x00, 0x00,  # FDE offset
-      0x00, 0x00, 0x00, 0x00,  # FRE offset
-
-      # FDE[0]:
-      0x00, 0xde, 0xad, 0x00,  # Start Address
-      0xbe, 0x01, 0x00, 0x00,  # Size
-      0x00, 0x00, 0x00, 0x00,  # Start FRE Offset
-      0x01, 0x00, 0x00, 0x00,  # Number of FREs
-      0x00, 0xde, 0xad, 0x00,  # Info, RepSize, Padding2
-
-      # FRE[0]:
-      0x00, 0x02               # Start Address, Info, (missing) Offsets
-    ]
-# CASE1-LABEL:SFrame section '.sframe_eof_offset' {
-#       CASE1:    FuncDescEntry [0] {
-#       CASE1:      Info {
-#  CASE1-NEXT:        FRE Type: Addr1 (0x0)
-#  CASE1-NEXT:        FDE Type: PCInc (0x0)
-#       CASE1:      FREs [
-#  CASE1-NEXT:{{.*}}: warning: '[[FILE]]': unexpected end of data at offset 0x32 while reading [0x32, 0x33)
-#  CASE1-NEXT:      ]
-
-  - Name:  .sframe
-    Type:  SHT_GNU_SFRAME
-    Flags: [ SHF_ALLOC ]
-    ContentArray: [
-      0xe2, 0xde, 0x02, 0x04,  # Preamble (magic, version, flags)
-      # Header:
-      0x03, 0x42, 0x40, 0x00,  # ABI, Fixed FP offset, Fixed RA Offset, AUX header length
-      0x02, 0x00, 0x00, 0x00,  # Number of FDEs
-      0x01, 0x00, 0x00, 0x00,  # Number of FREs
-      0x00, 0x10, 0x00, 0x00,  # FRE length
-      0x00, 0x00, 0x00, 0x00,  # FDE offset
-      0x00, 0x00, 0x00, 0x00,  # FRE offset
-
-      # FDE[0]:
-      0x00, 0x00, 0xde, 0x00,  # Start Address
-      0xbe, 0x01, 0x00, 0x00,  # Size
-      0x00, 0x00, 0x00, 0x00,  # Start FRE Offset
-      0x02, 0x00, 0x00, 0x00,  # Number of FREs
-      0x00, 0xde, 0xad, 0x00,  # Info, RepSize, Padding2
-
-      # FDE[1]:
-      0x00, 0x00, 0xad, 0x00,  # Start Address
-      0xbe, 0x01, 0x00, 0x00,  # Size
-      0x08, 0x00, 0x00, 0x00,  # Start FRE Offset
-      0x03, 0x00, 0x00, 0x00,  # Number of FREs
-      0x11, 0xde, 0xad, 0x00,  # Info, RepSize, Padding2
-
-      # FRE[0,0]: Zero offsets
-      0x00, 0x00,              # Start Address, Info
-
-      # FRE[0,1]: One four-byte offset, SP-based
-      0x01, 0x43,              # Start Address, Info
-      0x74, 0x00, 0x00, 0x00,  # Offset[0]
-
-      # FRE[1,0]: Two two-byte offsets, FP-based
-      0x00, 0x00, 0x24,        # Start Address, Info
-      0x10, 0x00, 0x20, 0x00,  # Offset[0], Offset[1]
-
-      # FRE[1,1]: Four one-byte offsets, FP-based
-      0x00, 0x01, 0x08,        # Start Address, Info
-      0x10, 0x20, 0x30, 0x40,  # Offset[0-3]
-    ]
-## Testing:
-## - little-endian support
-## - AMD64 ABI
-## - one and two byte address sizes
-## - PCInc and PCMask FDE types
-## - all offset sizes
-## - various offset counts
-## - hitting EOF after printing some number of FREs
-# CASE1-LABEL:SFrame section '.sframe' {
-#       CASE1:    ABI: AMD64EndianLittle (0x3)
-#       CASE1:    CFA fixed RA offset: 64
-#       CASE1:    FuncDescEntry [0] {
-#  CASE1-NEXT:      PC: 0xDE007F
-#       CASE1:      Info {
-#  CASE1-NEXT:        FRE Type: Addr1 (0x0)
-#  CASE1-NEXT:        FDE Type: PCInc (0x0)
-#       CASE1:      FREs [
-#  CASE1-NEXT:        Frame Row Entry {
-#  CASE1-NEXT:          Start Address: 0xDE007F
-#  CASE1-NEXT:          Return Address Signed: No
-#  CASE1-NEXT:          Offset Size: B1 (0x0)
-#  CASE1-NEXT:          Base Register: FP (0x0)
-#  CASE1-NEXT:          RA Offset: 64
-#  CASE1-NEXT:        }
-#  CASE1-NEXT:        Frame Row Entry {
-#  CASE1-NEXT:          Start Address: 0xDE0080
-#  CASE1-NEXT:          Return Address Signed: No
-#  CASE1-NEXT:          Offset Size: B4 (0x2)
-#  CASE1-NEXT:          Base Register: SP (0x1)
-#  CASE1-NEXT:          CFA Offset: 116
-#  CASE1-NEXT:          RA Offset: 64
-#  CASE1-NEXT:        }
-#  CASE1-NEXT:      ]
-#       CASE1:    FuncDescEntry [1] {
-#  CASE1-NEXT:      PC: 0xAD0093
-#       CASE1:      Info {
-#  CASE1-NEXT:        FRE Type: Addr2 (0x1)
-#  CASE1-NEXT:        FDE Type: PCMask (0x1)
-#       CASE1:      FREs [
-#  CASE1-NEXT:        Frame Row Entry {
-#  CASE1-NEXT:          Start Address: 0x0
-#  CASE1-NEXT:          Return Address Signed: No
-#  CASE1-NEXT:          Offset Size: B2 (0x1)
-#  CASE1-NEXT:          Base Register: FP (0x0)
-#  CASE1-NEXT:          CFA Offset: 16
-#  CASE1-NEXT:          RA Offset: 64
-#  CASE1-NEXT:          FP Offset: 32
-#  CASE1-NEXT:        }
-#  CASE1-NEXT:        Frame Row Entry {
-#  CASE1-NEXT:          Start Address: 0x100
-#  CASE1-NEXT:          Return Address Signed: No
-#  CASE1-NEXT:          Offset Size: B1 (0x0)
-#  CASE1-NEXT:          Base Register: FP (0x0)
-#  CASE1-NEXT:          CFA Offset: 16
-#  CASE1-NEXT:          RA Offset: 64
-#  CASE1-NEXT:          FP Offset: 32
-#  CASE1-NEXT:          Extra Offsets: [48, 64]
-#  CASE1-NEXT:        }
-#  CASE1-NEXT:{{.*}}: warning: '[[FILE]]': unexpected end of data at offset 0x5a while reading [0x5a, 0x5d)
-
---- !ELF
-FileHeader:
-  Class: ELFCLASS64
-  Data:  ELFDATA2MSB
-  Type:  ET_EXEC
-Sections:
-  - Name:  .sframe
-    Type:  SHT_GNU_SFRAME
-    Flags: [ SHF_ALLOC ]
-    ContentArray: [
-      0xde, 0xe2, 0x02, 0x05,  # Preamble (magic, version, flags)
-      # Header:
-      0x01, 0x42, 0x47, 0x00,  # ABI, Fixed FP offset, Fixed RA Offset, AUX header length
-      0x00, 0x00, 0x00, 0x01,  # Number of FDEs
-      0x00, 0x00, 0x00, 0x10,  # Number of FREs
-      0x00, 0x00, 0x10, 0x00,  # FRE length
-      0x00, 0x00, 0x00, 0x00,  # FDE offset
-      0x00, 0x00, 0x01, 0x00,  # FRE offset
-
-      # FDE:
-      0x00, 0xde, 0x00, 0x00,  # Start Address
-      0x00, 0x00, 0x01, 0xbe,  # Size
-      0x00, 0x00, 0x00, 0x00,  # Start FRE Offset
-      0x00, 0x00, 0x00, 0x05,  # Number of FREs
-      0x02, 0xde, 0xad, 0x00,  # Info, RepSize, Padding2
-
-      # FRE[0]: Zero offsets
-      0x00, 0x00, 0x00, 0x00,  # Start Address
-      0x00,                    # Info
-
-      # FRE[1]: One offset
-      0x00, 0x00, 0x00, 0x01,  # Start Address
-      0x82, 0x10,              # Info, Offset[0]
-
-      # FRE[2]: Two offsets
-      0x00, 0x00, 0x00, 0x02,  # Start Address
-      0x04, 0x10, 0x20,        # Info, Offset[0-1]
-
-      # FRE[3]: Three offsets
-      0x00, 0x00, 0x00, 0x03,  # Start Address
-      0x86, 0x10, 0x20, 0x30,  # Info, Offset[0-2]
-
-      # FRE[4]: Four offsets
-      0x00, 0x00, 0x00, 0x04,  # Start Address
-      0x08,                    # Info
-      0x10, 0x20, 0x30, 0x40,  # Offset[0-3]
-    ]
-## Testing:
-## - big-endian support
-## - ARM64 ABI
-## - four-byte address sizes
-## - return address signing
-## - various offset counts
-# CASE2-LABEL:SFrame section '.sframe' {
-#       CASE2:    ABI: AArch64EndianBig (0x1)
-#       CASE2:    FuncDescEntry [0] {
-#  CASE2-NEXT:      PC: 0xDE001C
-#       CASE2:      Info {
-#  CASE2-NEXT:        FRE Type: Addr4 (0x2)
-#  CASE2-NEXT:        FDE Type: PCInc (0x0)
-#       CAS...
[truncated]

@labath labath merged commit 7e8a251 into main Aug 8, 2025
9 of 11 checks passed
@labath labath deleted the revert-151301-sframe2 branch August 8, 2025 06:30
@labath labath added the skip-precommit-approval PR for CI feedback, not intended for review label Aug 8, 2025
labath added a commit that referenced this pull request Aug 12, 2025
…152650) (#152695)

This reapplies #152650 with a build fix for clang-11 (need explicit
template parameters for ArrayRef construction) and avoiding the
default-in-a-switch-covering-enum warning. It also adds two new tests.

The original commit message was:

The trickiest part here is that the FREs have a variable size, in two
(or three?) dimensions:
- the size of the StartAddress field. This determined by the FDE they
are in, so it is uniform across all FREs in one FDE.
- the number and sizes of offsets following the FRE. This can be
different for each FRE.
    
While vending this information through a template API would be possible,
I believe such an approach would be very unwieldy, and it would still
require a sequential scan through the FRE list. This is why I'm
implementing this by reading the data into a common data structure using
the fallible iterator pattern.
    
For more information about the SFrame unwind format, see the
[specification](https://sourceware.org/binutils/wiki/sframe) and the
related
[RFC](https://discourse.llvm.org/t/rfc-adding-sframe-support-to-llvm/86900).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

llvm:binary-utilities skip-precommit-approval PR for CI feedback, not intended for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants