diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1712,6 +1712,12 @@ StringRef Name = GO->getSection(); + // Clang precompiled header data isn't needed at runtime; use custom section + // TODO: This special case may be generalized as wasm binary format + // https://github.com/WebAssembly/tool-conventions/issues/138 + if (Name == "__clangast") + Kind = SectionKind::getMetadata(); + StringRef Group = ""; if (const Comdat *C = getWasmComdat(GO)) { Group = C->getName(); diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -373,7 +373,16 @@ Section.PayloadOffset = W.OS.tell(); // Custom sections in wasm also have a string identifier. - writeString(Name); + if (Name != "__clangast") { + writeString(Name); + } else { + // pad section start to nearest 4 bytes for Clang PCH + uint64_t MinLength = + Section.PayloadOffset + 5ULL /* min ULEB128 length */ + Name.size(); + uint64_t RoundedUpLength = (MinLength + 3ULL) & ~3ULL; + encodeULEB128(Name.size(), W.OS, 5 + (RoundedUpLength - MinLength)); + W.OS << Name; + } // The position where the custom section starts. Section.ContentsOffset = W.OS.tell(); @@ -1099,6 +1108,10 @@ if (Sym.isSection()) return false; + // Clang's precompiled headers are in a separate custom section + if (Sym.getName() == "__clang_ast") + return false; + return true; } diff --git a/llvm/test/MC/WebAssembly/clangast.ll b/llvm/test/MC/WebAssembly/clangast.ll new file mode 100644 --- /dev/null +++ b/llvm/test/MC/WebAssembly/clangast.ll @@ -0,0 +1,38 @@ +; RUN: llc -filetype=obj %s -o - | llvm-readobj -S | FileCheck %s + +target triple = "wasm32-unknown-unknown" + +@dummy = hidden global [6 x i8] c"hello\00", align 1 +@__clang_ast = internal constant [4 x i8] c"CPCH", section "__clangast", align 4 +!0 = !{ !"anchor", !"\00" } +!wasm.custom_sections = !{ !0 } + +; The size of __clang_ast should be 27. +; ┌───────────────────────────────┬───────────────────────────────┬─────────┐ +; │ content type │ contet bytes (hex) │ size │ +; ├───────────────────────────────┼───────────────────────────────┼─────────┤ +; │ section id │ 00 │ 1 byte │ +; │ size of content (LEB128) │ 95 80 80 80 00 │ 5 byte │ +; │ size of section name (LEB128) │ 8a │ 1 byte │ +; │ padding to align │ 80 80 80 80 80 00 │ 6 byte │ +; │ section name │ 5f 5f 63 6c 61 6e 67 61 73 74 │ 10 byte │ +; │ content of __clang_ast │ 43 50 43 48 │ 4 byte │ +; ├───────────────────────────────┼───────────────────────────────┼─────────┤ +; │ sum │ - │ 27 byte │ +; └─────────────────────────────────────────────────────────────────────────┘ + +; The content of __clang_ast should be aligned by 4, +; so the size of section name is padded to round up. + +; CHECK: Section { +; CHECK: Type: CUSTOM (0x0) +; CHECK: Size: 4 +; CHECK: Offset: [[#OFFSET:]] +; CHECK: Name: __clangast +; CHECK: } +; CHECK: Section { +; CHECK: Type: CUSTOM (0x0) +; CHECK: Size: 1 +; CHECK: Offset: [[#OFFSET + 27]] +; CHECK: Name: anchor +; CHECK: }