[llvm] [llvm-symbolizer] Make symbolizer parse section relative syntax (PR #168524)

via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 18 04:20:34 PST 2025


github-actions[bot] wrote:

<!--LLVM CODE FORMAT COMMENT: {clang-format}-->


:warning: C/C++ code formatter, clang-format found issues in your code. :warning:

<details>
<summary>
You can test this locally with the following command:
</summary>

``````````bash
git-clang-format --diff origin/main HEAD --extensions cpp -- llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp --diff_from_common_commit
``````````

:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:

</details>

<details>
<summary>
View the diff from clang-format here.
</summary>

``````````diff
diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
index 3bdbce55c..b370d572e 100644
--- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
+++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
@@ -25,7 +25,6 @@
 #include "llvm/DebugInfo/Symbolize/MarkupFilter.h"
 #include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
 #include "llvm/DebugInfo/Symbolize/Symbolize.h"
-#include "llvm/Object/XCOFFObjectFile.h"
 #include "llvm/Debuginfod/BuildIDFetcher.h"
 #include "llvm/Debuginfod/Debuginfod.h"
 #include "llvm/Debuginfod/HTTPClient.h"
@@ -162,88 +161,92 @@ static Error makeStringError(StringRef Msg) {
 }
 
 // Helper function to get XCOFF section type flag from string
- static std::optional<XCOFF::SectionTypeFlags> parseXCOFFSectionType(StringRef TypeStr) {
-   return StringSwitch<std::optional<XCOFF::SectionTypeFlags>>(TypeStr)
-       .Case("PAD", XCOFF::STYP_PAD)
-       .Case("DWARF", XCOFF::STYP_DWARF)
-       .Case("TEXT", XCOFF::STYP_TEXT)
-       .Case("DATA", XCOFF::STYP_DATA)
-       .Case("BSS", XCOFF::STYP_BSS)
-       .Case("EXCEPT", XCOFF::STYP_EXCEPT)
-       .Case("INFO", XCOFF::STYP_INFO)
-       .Case("TDATA", XCOFF::STYP_TDATA)
-       .Case("TBSS", XCOFF::STYP_TBSS)
-       .Case("LOADER", XCOFF::STYP_LOADER)
-       .Case("DEBUG", XCOFF::STYP_DEBUG)
-       .Case("TYPCHK", XCOFF::STYP_TYPCHK)
-       .Case("OVRFLO", XCOFF::STYP_OVRFLO)
-       .Default(std::nullopt);
- }
-
- // Find the base VMA of the first section matching the given type for XCOFF.
- // The syntax (SECTION_TYPE)(+offset) represents an offset from the section base,
- // so we return the section's base address to compute: VMA = base + offset.
- static Expected<uint64_t> getXCOFFSectionBaseAddress(
-     const object::XCOFFObjectFile *XCOFFObj,
-     XCOFF::SectionTypeFlags TypeFlag) {
-
-   for (const auto &Section : XCOFFObj->sections()) {
-     DataRefImpl SecRef = Section.getRawDataRefImpl();
-     int32_t Flags = XCOFFObj->getSectionFlags(SecRef);
-
-     if ((Flags & 0xFFFF) == TypeFlag) {
-       return Section.getAddress();
-     }
-   }
-
-   return createStringError(inconvertibleErrorCode(),
-                            "section type not found in XCOFF object");
- }
-
- static Expected<uint64_t> validateSectionType(StringRef ModulePath,
-                                                 StringRef SectionType,
-                                                 uint64_t &Offset,
-                                                 LLVMSymbolizer &Symbolizer) {
-   // Parse the section type string
-   auto SectionTypeFlag = parseXCOFFSectionType(SectionType);
-   if (!SectionTypeFlag) {
-     return createStringError(inconvertibleErrorCode(),
+static std::optional<XCOFF::SectionTypeFlags>
+parseXCOFFSectionType(StringRef TypeStr) {
+  return StringSwitch<std::optional<XCOFF::SectionTypeFlags>>(TypeStr)
+      .Case("PAD", XCOFF::STYP_PAD)
+      .Case("DWARF", XCOFF::STYP_DWARF)
+      .Case("TEXT", XCOFF::STYP_TEXT)
+      .Case("DATA", XCOFF::STYP_DATA)
+      .Case("BSS", XCOFF::STYP_BSS)
+      .Case("EXCEPT", XCOFF::STYP_EXCEPT)
+      .Case("INFO", XCOFF::STYP_INFO)
+      .Case("TDATA", XCOFF::STYP_TDATA)
+      .Case("TBSS", XCOFF::STYP_TBSS)
+      .Case("LOADER", XCOFF::STYP_LOADER)
+      .Case("DEBUG", XCOFF::STYP_DEBUG)
+      .Case("TYPCHK", XCOFF::STYP_TYPCHK)
+      .Case("OVRFLO", XCOFF::STYP_OVRFLO)
+      .Default(std::nullopt);
+}
+
+// Find the base VMA of the first section matching the given type for XCOFF.
+// The syntax (SECTION_TYPE)(+offset) represents an offset from the section
+// base, so we return the section's base address to compute: VMA = base +
+// offset.
+static Expected<uint64_t>
+getXCOFFSectionBaseAddress(const object::XCOFFObjectFile *XCOFFObj,
+                           XCOFF::SectionTypeFlags TypeFlag) {
+
+  for (const auto &Section : XCOFFObj->sections()) {
+    DataRefImpl SecRef = Section.getRawDataRefImpl();
+    int32_t Flags = XCOFFObj->getSectionFlags(SecRef);
+
+    if ((Flags & 0xFFFF) == TypeFlag) {
+      return Section.getAddress();
+    }
+  }
+
+  return createStringError(inconvertibleErrorCode(),
+                           "section type not found in XCOFF object");
+}
+
+static Expected<uint64_t> validateSectionType(StringRef ModulePath,
+                                              StringRef SectionType,
+                                              uint64_t &Offset,
+                                              LLVMSymbolizer &Symbolizer) {
+  // Parse the section type string
+  auto SectionTypeFlag = parseXCOFFSectionType(SectionType);
+  if (!SectionTypeFlag) {
+    return createStringError(inconvertibleErrorCode(),
                              "unknown section type: " + SectionType.str());
-   }
-
-   // Get the module info to access the object file
-   auto ModuleOrErr = Symbolizer.getOrCreateModuleInfo(ModulePath);
-   if (!ModuleOrErr) {
-     return ModuleOrErr.takeError();
-   }
-
-   auto BinaryOrErr = object::createBinary(ModulePath);
-   if (!BinaryOrErr) {
-     return BinaryOrErr.takeError();
-   }
-
-   object::Binary *Binary = BinaryOrErr->getBinary();
-   if (auto *XCOFFObj = dyn_cast<object::XCOFFObjectFile>(Binary)) {
-     // Get the base VMA of the section matching the type
-     auto SectionBaseOrErr = getXCOFFSectionBaseAddress(XCOFFObj, *SectionTypeFlag);
-     if (!SectionBaseOrErr)
-       return SectionBaseOrErr.takeError();
-
-     uint64_t SectionBase = *SectionBaseOrErr;
-     uint64_t SectionRelativeOffset = Offset;
-
-     // Convert section-relative offset to absolute VMA
-     // VMA = section_base + offset
-     Offset = SectionBase + SectionRelativeOffset;
-
-     // Return UndefSection - XCOFF symbolizer doesn't support SectionedAddress,
-     // so we use absolute VMA addressing instead.
-     return object::SectionedAddress::UndefSection;
-   }
-
-   return createStringError(inconvertibleErrorCode(),
-                           "section type syntax is only supported for XCOFF objects");
- }
+  }
+
+  // Get the module info to access the object file
+  auto ModuleOrErr = Symbolizer.getOrCreateModuleInfo(ModulePath);
+  if (!ModuleOrErr) {
+    return ModuleOrErr.takeError();
+  }
+
+  auto BinaryOrErr = object::createBinary(ModulePath);
+  if (!BinaryOrErr) {
+    return BinaryOrErr.takeError();
+  }
+
+  object::Binary *Binary = BinaryOrErr->getBinary();
+  if (auto *XCOFFObj = dyn_cast<object::XCOFFObjectFile>(Binary)) {
+    // Get the base VMA of the section matching the type
+    auto SectionBaseOrErr =
+        getXCOFFSectionBaseAddress(XCOFFObj, *SectionTypeFlag);
+    if (!SectionBaseOrErr)
+      return SectionBaseOrErr.takeError();
+
+    uint64_t SectionBase = *SectionBaseOrErr;
+    uint64_t SectionRelativeOffset = Offset;
+
+    // Convert section-relative offset to absolute VMA
+    // VMA = section_base + offset
+    Offset = SectionBase + SectionRelativeOffset;
+
+    // Return UndefSection - XCOFF symbolizer doesn't support SectionedAddress,
+    // so we use absolute VMA addressing instead.
+    return object::SectionedAddress::UndefSection;
+  }
+
+  return createStringError(
+      inconvertibleErrorCode(),
+      "section type syntax is only supported for XCOFF objects");
+}
 
 static Error parseCommand(StringRef BinaryName, bool IsAddr2Line,
                           StringRef InputString, Command &Cmd,
@@ -336,36 +339,38 @@ static Error parseCommand(StringRef BinaryName, bool IsAddr2Line,
   }
 
   // Check for section-relative address syntax: (SECTION_TYPE)(+0x0)
-   if (AddrSpec.starts_with("(")) {
-     size_t FirstClose = AddrSpec.find(')');
-     if (FirstClose != StringRef::npos && FirstClose + 1 < AddrSpec.size() &&
-         AddrSpec[FirstClose + 1] == '(') {
-       size_t SecondOpen = FirstClose + 1;
-       size_t SecondClose = AddrSpec.find(')', SecondOpen);
-       if (SecondClose != StringRef::npos) {
-         // Extract section type from first parentheses
-         SectionType = AddrSpec.substr(1, FirstClose - 1);
-
-         // Validate that section type is not empty
-         if (SectionType.empty())
-           return makeStringError("unknown section type: empty section type");
-
-         // Extract offset from second parentheses
-         StringRef OffsetPart = AddrSpec.substr(SecondOpen + 1, SecondClose - SecondOpen - 1);
-
-         // The offset should start with '+'
-         if (!OffsetPart.consume_front("+"))
-           return makeStringError("section-relative offset must start with '+'");
-
-         // Parse the offset - auto-detect base (0x prefix = hex, otherwise decimal)
-         if (OffsetPart.getAsInteger(0, Offset))
-           return makeStringError("invalid offset in section-relative address");
-
-         Symbol = StringRef();
-         return Error::success();
-       }
-     }
-   }
+  if (AddrSpec.starts_with("(")) {
+    size_t FirstClose = AddrSpec.find(')');
+    if (FirstClose != StringRef::npos && FirstClose + 1 < AddrSpec.size() &&
+        AddrSpec[FirstClose + 1] == '(') {
+      size_t SecondOpen = FirstClose + 1;
+      size_t SecondClose = AddrSpec.find(')', SecondOpen);
+      if (SecondClose != StringRef::npos) {
+        // Extract section type from first parentheses
+        SectionType = AddrSpec.substr(1, FirstClose - 1);
+
+        // Validate that section type is not empty
+        if (SectionType.empty())
+          return makeStringError("unknown section type: empty section type");
+
+        // Extract offset from second parentheses
+        StringRef OffsetPart =
+            AddrSpec.substr(SecondOpen + 1, SecondClose - SecondOpen - 1);
+
+        // The offset should start with '+'
+        if (!OffsetPart.consume_front("+"))
+          return makeStringError("section-relative offset must start with '+'");
+
+        // Parse the offset - auto-detect base (0x prefix = hex, otherwise
+        // decimal)
+        if (OffsetPart.getAsInteger(0, Offset))
+          return makeStringError("invalid offset in section-relative address");
+
+        Symbol = StringRef();
+        return Error::success();
+      }
+    }
+  }
 
   // If address specification is a number, treat it as a module offset.
   if (!AddrSpec.getAsInteger(IsAddr2Line ? 16 : 0, Offset)) {
@@ -408,8 +413,8 @@ void executeCommand(StringRef ModuleName, const T &ModuleSpec, Command Cmd,
                     bool ShouldInline, OutputStyle Style,
                     LLVMSymbolizer &Symbolizer, DIPrinter &Printer,
                     uint64_t SectionIndex) {
-   uint64_t AdjustedOffset = Offset - AdjustVMA;
-   object::SectionedAddress Address = {AdjustedOffset, SectionIndex};
+  uint64_t AdjustedOffset = Offset - AdjustVMA;
+  object::SectionedAddress Address = {AdjustedOffset, SectionIndex};
 
   Request SymRequest = {
       ModuleName, Symbol.empty() ? std::make_optional(Offset) : std::nullopt,
@@ -489,11 +494,12 @@ static void symbolizeInput(const opt::InputArgList &Args,
   // Validate section index from section type if specified
   uint64_t SectionIndex = object::SectionedAddress::UndefSection;
   if (!SectionType.empty() && !ModuleName.empty()) {
-    auto SectionIndexOrErr = validateSectionType(ModuleName, SectionType, Offset, Symbolizer);
+    auto SectionIndexOrErr =
+        validateSectionType(ModuleName, SectionType, Offset, Symbolizer);
     if (!SectionIndexOrErr) {
-      handleAllErrors(SectionIndexOrErr.takeError(), [&](const ErrorInfoBase &EI) {
-        printError(EI, InputString);
-      });
+      handleAllErrors(
+          SectionIndexOrErr.takeError(),
+          [&](const ErrorInfoBase &EI) { printError(EI, InputString); });
       printUnknownLineInfo(ModuleName, Printer);
       return;
     }
@@ -509,10 +515,10 @@ static void symbolizeInput(const opt::InputArgList &Args,
     // Note: Section type resolution is not supported for BuildID-based lookup
     executeCommand(BuildIDStr, BuildID, Cmd, Symbol, Offset, AdjustVMA,
                    ShouldInline, Style, Symbolizer, Printer,
-                    object::SectionedAddress::UndefSection);
+                   object::SectionedAddress::UndefSection);
   } else {
     executeCommand(ModuleName, ModuleName, Cmd, Symbol, Offset, AdjustVMA,
-ShouldInline, Style, Symbolizer, Printer, SectionIndex);
+                   ShouldInline, Style, Symbolizer, Printer, SectionIndex);
   }
 }
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/168524


More information about the llvm-commits mailing list