[Lldb-commits] [lldb] [lldb] Add SubtargetFeatures to ArchSpec (PR #173046)

David Spickett via lldb-commits lldb-commits at lists.llvm.org
Thu Feb 5 10:08:28 PST 2026


================
@@ -1405,6 +1409,117 @@ void ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length,
   }
 }
 
+static std::optional<lldb::offset_t>
+FindSubSectionOffsetByName(const DataExtractor &data, lldb::offset_t offset,
+                           uint32_t length, llvm::StringRef name) {
+  uint32_t section_length = 0;
+  llvm::StringRef section_name;
+  do {
+    offset += section_length;
+    // Sub-section's size and name are included in the total sub-section length.
+    // Don't shift the offset here, so it will point at the beginning of the
+    // sub-section and could be used as a return value.
+    auto tmp_offset = offset;
+    section_length = data.GetU32(&tmp_offset);
+    section_name = data.GetCStr(&tmp_offset);
+  } while (section_name != name && offset + section_length < length);
+  if (section_name == name)
+    return offset;
+  return std::nullopt;
+}
+
+static std::optional<lldb::offset_t>
+FindSubSubSectionOffsetByTag(const DataExtractor &data, lldb::offset_t offset,
+                             unsigned tag) {
+  // Consume a sub-section size and name to shift the offset at the beginning of
+  // the sub-sub-sections list.
+  auto upper_section_length = data.GetU32(&offset);
+  data.GetCStr(&offset);
+  auto upper_section_end_offset = offset + upper_section_length;
+
+  uint32_t section_length = 0;
+  unsigned section_tag = 0;
+  do {
+    offset += section_length;
+    // Similar to sub-section sub-sub-section's tag and size are included in the
+    // total sub-sub-section length.
+    auto tmp_offset = offset;
+    section_tag = data.GetULEB128(&tmp_offset);
+    section_length = data.GetU32(&tmp_offset);
+  } while (section_tag != tag &&
+           offset + section_length < upper_section_end_offset);
+  if (section_tag == tag)
+    return offset;
+  return std::nullopt;
+}
+
+static std::optional<std::variant<uint64_t, llvm::StringRef>>
+GetSubSubSubSectionValue(const DataExtractor &data, lldb::offset_t offset,
+                         unsigned tag) {
+  // Consume a sub-sub-section tag and size to shift the offset at the beginning
+  // of the sub-sub-sub-sections list.
+  data.GetULEB128(&offset);
+  auto upper_section_length = data.GetU32(&offset);
+  auto upper_section_end_offset = offset + upper_section_length;
+
+  std::variant<uint64_t, llvm::StringRef> result;
+  unsigned section_tag = 0;
+  do {
+    section_tag = data.GetULEB128(&offset);
+    // From the riscv psABI document:
+    // RISC-V attributes have a string value if the tag number is odd and an
+    // integer value if the tag number is even.
+    if (section_tag % 2)
+      result = data.GetCStr(&offset);
+    else
+      result = data.GetULEB128(&offset);
+  } while (section_tag != tag && offset < upper_section_end_offset);
+  if (section_tag == tag)
+    return result;
+  return std::nullopt;
+}
+
+void ObjectFileELF::ParseRISCVAttributes(DataExtractor &data, uint64_t length,
+                                         ArchSpec &arch_spec) {
+  Log *log = GetLog(LLDBLog::Modules);
+
+  lldb::offset_t offset = 0;
+
+  uint8_t format_version = data.GetU8(&offset);
+  if (format_version != llvm::ELFAttrs::Format_Version)
+    return;
+
+  auto subsection_or_opt =
+      FindSubSectionOffsetByName(data, offset, length, "riscv");
+  if (!subsection_or_opt) {
+    LLDB_LOGF(log,
+              "ObjectFileELF::%s Ill-formed .riscv.attributes section: "
+              "mandatory 'riscv' sub-section was not preserved",
+              __FUNCTION__);
+    return;
+  }
+
+  auto subsubsection_or_opt = FindSubSubSectionOffsetByTag(
+      data, *subsection_or_opt, llvm::ELFAttrs::File);
+  if (!subsubsection_or_opt)
+    return;
+
+  auto value_or_opt = GetSubSubSubSectionValue(data, *subsubsection_or_opt,
+                                               llvm::RISCVAttrs::ARCH);
+  if (!value_or_opt)
+    return;
+
+  auto isa_info = llvm::RISCVISAInfo::parseArchString(
+      std::get<llvm::StringRef>(*value_or_opt),
+      /* EnableExperimentalExtension=*/true);
----------------
DavidSpickett wrote:

I was thinking about encoding overlaps but even if we assume that's possible, that means that the input program file uses extensions that overlap. So the problem if, it exists, is with the producer of the program file, not LLDB.

@lenary you know about these things, does that make sense to you?

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


More information about the lldb-commits mailing list