[llvm] [BOLT] Fix LSDA section handling (PR #71821)

Vladislav Khmelevsky via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 9 08:34:51 PST 2023


https://github.com/yota9 created https://github.com/llvm/llvm-project/pull/71821

Currently BOLT finds LSDA secition by it's name .gcc_except_table.main .
But sometimes it might have suffix e.g. .gcc_except_table.main. Find
LSDA section by it's address, rather by it's name.
Fixes #71804


>From 54fa5a6aab6ae5319d64a26731ffedbec766cfac Mon Sep 17 00:00:00 2001
From: Vladislav Khmelevsky <och95 at yandex.ru>
Date: Thu, 9 Nov 2023 20:32:17 +0400
Subject: [PATCH] [BOLT] Fix LSDA section handling

Currently BOLT finds LSDA secition by it's name .gcc_except_table.main .
But sometimes it might have suffix e.g. .gcc_except_table.main. Find
LSDA section by it's address, rather by it's name.
Fixes #71804
---
 bolt/include/bolt/Rewrite/RewriteInstance.h |  6 ---
 bolt/lib/Rewrite/RewriteInstance.cpp        | 18 ++++----
 bolt/test/Inputs/lsda.ldscript              |  6 +++
 bolt/test/lsda.cpp                          | 47 +++++++++++++++++++++
 4 files changed, 61 insertions(+), 16 deletions(-)
 create mode 100644 bolt/test/Inputs/lsda.ldscript
 create mode 100644 bolt/test/lsda.cpp

diff --git a/bolt/include/bolt/Rewrite/RewriteInstance.h b/bolt/include/bolt/Rewrite/RewriteInstance.h
index 2a421c5cfaa4f89..9251fc806025a45 100644
--- a/bolt/include/bolt/Rewrite/RewriteInstance.h
+++ b/bolt/include/bolt/Rewrite/RewriteInstance.h
@@ -391,12 +391,6 @@ class RewriteInstance {
   /// Manage a pipeline of metadata handlers.
   class MetadataManager MetadataManager;
 
-  /// Get the contents of the LSDA section for this binary.
-  ArrayRef<uint8_t> getLSDAData();
-
-  /// Get the mapped address of the LSDA section for this binary.
-  uint64_t getLSDAAddress();
-
   static const char TimerGroupName[];
 
   static const char TimerGroupDesc[];
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index abdbb79e8eb60ef..77e36f368175527 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -1706,13 +1706,6 @@ void RewriteInstance::relocateEHFrameSection() {
   check_error(std::move(E), "failed to patch EH frame");
 }
 
-ArrayRef<uint8_t> RewriteInstance::getLSDAData() {
-  return ArrayRef<uint8_t>(LSDASection->getData(),
-                           LSDASection->getContents().size());
-}
-
-uint64_t RewriteInstance::getLSDAAddress() { return LSDASection->getAddress(); }
-
 Error RewriteInstance::readSpecialSections() {
   NamedRegionTimer T("readSpecialSections", "read special sections",
                      TimerGroupName, TimerGroupDesc, opts::TimeRewrite);
@@ -1751,7 +1744,6 @@ Error RewriteInstance::readSpecialSections() {
 
   HasTextRelocations = (bool)BC->getUniqueSectionByName(".rela.text");
   HasSymbolTable = (bool)BC->getUniqueSectionByName(".symtab");
-  LSDASection = BC->getUniqueSectionByName(".gcc_except_table");
   EHFrameSection = BC->getUniqueSectionByName(".eh_frame");
   BuildIDSection = BC->getUniqueSectionByName(".note.gnu.build-id");
 
@@ -3109,8 +3101,14 @@ void RewriteInstance::disassembleFunctions() {
 
     // Parse LSDA.
     if (Function.getLSDAAddress() != 0 &&
-        !BC->getFragmentsToSkip().count(&Function))
-      Function.parseLSDA(getLSDAData(), getLSDAAddress());
+        !BC->getFragmentsToSkip().count(&Function)) {
+      ErrorOr<BinarySection &> LSDASection =
+          BC->getSectionForAddress(Function.getLSDAAddress());
+      check_error(LSDASection.getError(), "failed to get LSDA section");
+      ArrayRef<uint8_t> LSDAData = ArrayRef<uint8_t>(
+          LSDASection->getData(), LSDASection->getContents().size());
+      Function.parseLSDA(LSDAData, LSDASection->getAddress());
+    }
   }
 }
 
diff --git a/bolt/test/Inputs/lsda.ldscript b/bolt/test/Inputs/lsda.ldscript
new file mode 100644
index 000000000000000..5ca7951e20e0d6a
--- /dev/null
+++ b/bolt/test/Inputs/lsda.ldscript
@@ -0,0 +1,6 @@
+SECTIONS {
+  .text : { *(.text*) }
+  . = 0x20000;
+  .eh_frame : { *(.eh_frame) }
+  . = 0x80000;
+}
diff --git a/bolt/test/lsda.cpp b/bolt/test/lsda.cpp
new file mode 100644
index 000000000000000..b7905a58b532dab
--- /dev/null
+++ b/bolt/test/lsda.cpp
@@ -0,0 +1,47 @@
+// This test check that LSDA section named by .gcc_except_table.main is
+// disassembled by BOLT.
+
+// RUN: %clang++ %cxxflags -O3 -flto=thin -no-pie -c %s -o %t.o
+// RUN: %clang++ %cxxflags -flto=thin -no-pie -fuse-ld=lld %t.o -o %t.exe \
+// RUN:   -Wl,-q -Wl,--script=%S/Inputs/lsda.ldscript
+// RUN: llvm-readelf -SW %t.exe | FileCheck %s
+// RUN: llvm-bolt %t.exe -o %t.bolt
+
+// CHECK: .gcc_except_table.main
+
+#include <iostream>
+
+class MyException : public std::exception {
+public:
+  const char *what() const throw() {
+    return "Custom Exception: an error occurred!";
+  }
+};
+
+int divide(int a, int b) {
+  if (b == 0) {
+    throw MyException();
+  }
+  return a / b;
+}
+
+int main() {
+  try {
+    int result = divide(10, 2); // normal case
+    std::cout << "Result: " << result << std::endl;
+    result = divide(5, 0); // will cause exception
+    std::cout << "Result: " << result << std::endl;
+    // this line will not execute
+  } catch (const MyException &e) {
+    // catch custom exception
+    std::cerr << "Caught exception: " << e.what() << std::endl;
+  } catch (const std::exception &e) {
+    // catch other C++ exceptions
+    std::cerr << "Caught exception: " << e.what() << std::endl;
+  } catch (...) {
+    // catch all other exceptions
+    std::cerr << "Caught unknown exception" << std::endl;
+  }
+
+  return 0;
+}



More information about the llvm-commits mailing list