[llvm] [llvm-symbolizer] Make symbolizer parse section relative syntax (PR #168524)
James Henderson via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 17 01:42:54 PST 2026
================
@@ -157,11 +161,105 @@ static Error makeStringError(StringRef Msg) {
return make_error<StringError>(Msg, inconvertibleErrorCode());
}
+// Helper function to get XCOFF section type flag from string.
+// Only TEXT and DATA are supported since:
+// - These are the only sections mapped by the AIX process map (procmap).
+// - BSS addresses are relative to DATA section base.
+// - Thread-local sections (TDATA, TBSS) cannot be symbolized from runtime
+// addresses.
+static std::optional<XCOFF::SectionTypeFlags>
+parseXCOFFSectionType(StringRef TypeStr) {
+ return StringSwitch<std::optional<XCOFF::SectionTypeFlags>>(TypeStr)
+ .Case("TEXT", XCOFF::STYP_TEXT)
+ .Case("DATA", XCOFF::STYP_DATA)
+ .Default(std::nullopt);
+}
+
+// Find the base VMA of the unique 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. This function verifies there is exactly one section of the given
+// type, as multiple sections of the same type would make the address ambiguous.
+static Expected<uint64_t>
+getXCOFFSectionBaseAddress(const object::XCOFFObjectFile *XCOFFObj,
+ XCOFF::SectionTypeFlags TypeFlag) {
+ std::optional<uint64_t> SectionBase;
+
+ for (const auto &Section : XCOFFObj->sections()) {
+ DataRefImpl SecRef = Section.getRawDataRefImpl();
+ int32_t Flags = XCOFFObj->getSectionFlags(SecRef);
+
+ if ((Flags & 0xFFFF) == TypeFlag) {
+ if (SectionBase)
+ return createStringError(
+ inconvertibleErrorCode(),
+ "multiple sections of the same type found in XCOFF object");
+ SectionBase = Section.getAddress();
+ }
+ }
+
+ if (!SectionBase)
+ return createStringError(inconvertibleErrorCode(),
+ "section type not found in XCOFF object");
+
+ return *SectionBase;
+}
+
+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 or unsupported 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);
----------------
jh7370 wrote:
I'm concerned this will be done for every single input address, which could be costly in performance. Should the binary be cached?
https://github.com/llvm/llvm-project/pull/168524
More information about the llvm-commits
mailing list