[llvm] [llvm-readobj][COFF] Dump .modmeta section (PR #201695)

James Henderson via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 9 01:00:43 PDT 2026


================
@@ -0,0 +1,131 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Object/COFFCxxModuleMetadata.h"
+#include "llvm/Support/ErrorExtras.h"
+
+namespace llvm::object {
+
+COFFCxxModuleMetadataReader::COFFCxxModuleMetadataReader(
+    const COFFCxxModuleMetadata &Map)
+    : ModuleData(Map.ModuleData), NamesData(Map.NamesData),
+      ModuleIndexWidth(Map.ModuleIndexWidth),
+      SymbolIndexWidth(Map.SymbolIndexWidth) {}
+
+bool COFFCxxModuleMetadataReader::hasModuleData() const {
+  return !ModuleData.empty();
+}
+
+Expected<uint32_t> COFFCxxModuleMetadataReader::readModuleID() {
+  switch (ModuleIndexWidth) {
+  case 1: {
+    if (ModuleData.size() < 1)
+      return createStringError("Not enough data");
+    uint8_t ID = static_cast<uint8_t>(ModuleData[0]);
+    ModuleData = ModuleData.slice(1, StringRef::npos);
+    if (ID == std::numeric_limits<uint8_t>::max())
+      return std::numeric_limits<uint32_t>::max();
+    return ID;
+  }
+  case 2: {
+    if (ModuleData.size() < 2)
+      return createStringError("Not enough data");
+    uint16_t ID =
+        support::endian::read<uint16_t>(ModuleData.data(), endianness::little);
+    ModuleData = ModuleData.slice(2, StringRef::npos);
+    if (ID == std::numeric_limits<uint16_t>::max())
+      return std::numeric_limits<uint32_t>::max();
+    return ID;
+  }
+  case 4: {
+    if (ModuleData.size() < 4)
+      return createStringError("Not enough data");
+    uint32_t ID =
+        support::endian::read<uint32_t>(ModuleData.data(), endianness::little);
+    ModuleData = ModuleData.slice(4, StringRef::npos);
+    return ID;
+  }
+  default:
+    return createStringErrorV("Unsupported index width: {0}", ModuleIndexWidth);
+  }
+}
+
+Expected<StringRef> COFFCxxModuleMetadataReader::readModuleName() {
+  size_t End = NamesData.find('\0');
+  if (End == StringRef::npos)
+    return createStringError("Missing null terminator");
+  StringRef Str = NamesData.slice(0, End);
+  NamesData = NamesData.drop_front(End + 1);
+  return Str;
+}
+
+Expected<ArrayRef<uint8_t>>
+COFFCxxModuleMetadataReader::readListImpl(uint8_t Width) {
+  StringRef Sentinel;
+  switch (Width) {
+  case 1:
+    Sentinel = "\xff";
+    break;
+  case 2:
+    Sentinel = "\xff\xff";
+    break;
+  case 4:
+    Sentinel = "\xff\xff\xff\xff";
+    break;
+  default:
+    return createStringErrorV("Unsupported index width: {0}", Width);
+  }
+  size_t Last = ModuleData.find(Sentinel);
+  if (Last == StringRef::npos)
+    return createStringError("Missing end sentinel");
+
+  ArrayRef<uint8_t> Data(ModuleData.bytes_begin(),
+                         ModuleData.bytes_begin() + Last);
+  ModuleData = ModuleData.drop_front(Last + Width);
+  return Data;
+}
+
+Expected<COFFCxxModuleMetadata>
+parseCOFFCxxModuleMetadata(StringRef SectionData) {
+  if (SectionData.size() <= sizeof(COFFCxxModuleMetadataHeader))
+    return createStringError("Insufficient size");
+
+  const auto *Header =
+      reinterpret_cast<const COFFCxxModuleMetadataHeader *>(SectionData.data());
+  if (Header->Version != 1)
+    return createStringError("Unsupported version");
----------------
jh7370 wrote:

I'd recommend including the read-in version number in this message.

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


More information about the llvm-commits mailing list