Skip to content

Commit 1e7311e

Browse files
[Coverage][WebAssembly] Add initial support for WebAssembly/WASI (llvm#111332)
Currently, WebAssembly/WASI target does not provide direct support for code coverage. This patch set fixes several issues to unlock the feature. The main changes are: 1. Port `compiler-rt/lib/profile` to WebAssembly/WASI. 2. Adjust profile metadata sections for Wasm object file format. - [CodeGen] Emit `__llvm_covmap` and `__llvm_covfun` as custom sections instead of data segments. - [lld] Align the interval space of custom sections at link time. - [llvm-cov] Copy misaligned custom section data if the start address is not aligned. - [llvm-cov] Read `__llvm_prf_names` from data segments 3. [clang] Link with profile runtime libraries if requested See each commit message for more details and rationale. This is part of the effort to add code coverage support in Wasm target of Swift toolchain.
1 parent 3a9722b commit 1e7311e

File tree

23 files changed

+253
-45
lines changed

23 files changed

+253
-45
lines changed

clang/lib/Driver/ToolChains/WebAssembly.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA,
155155
AddRunTimeLibs(ToolChain, ToolChain.getDriver(), CmdArgs, Args);
156156
}
157157

158+
ToolChain.addProfileRTLibs(Args, CmdArgs);
159+
158160
CmdArgs.push_back("-o");
159161
CmdArgs.push_back(Output.getFilename());
160162

compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ set(ALL_HWASAN_SUPPORTED_ARCH ${X86_64} ${ARM64} ${RISCV64})
7171
set(ALL_MEMPROF_SUPPORTED_ARCH ${X86_64})
7272
set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32} ${PPC64}
7373
${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}
74-
${RISCV32} ${RISCV64} ${LOONGARCH64})
74+
${RISCV32} ${RISCV64} ${LOONGARCH64} ${WASM32})
7575
set(ALL_CTX_PROFILE_SUPPORTED_ARCH ${X86_64})
7676
set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X}
7777
${LOONGARCH64} ${RISCV64})

compiler-rt/cmake/config-ix.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ else()
816816
endif()
817817

818818
if (PROFILE_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND
819-
OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX")
819+
OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX|WASI")
820820
set(COMPILER_RT_HAS_PROFILE TRUE)
821821
else()
822822
set(COMPILER_RT_HAS_PROFILE FALSE)

compiler-rt/lib/profile/CMakeLists.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ int main() {
3838
3939
" COMPILER_RT_TARGET_HAS_FCNTL_LCK)
4040

41+
CHECK_CXX_SOURCE_COMPILES("
42+
#include <sys/file.h>
43+
44+
int fd;
45+
int main() {
46+
flock(fd, LOCK_EX);
47+
return 0;
48+
}
49+
50+
" COMPILER_RT_TARGET_HAS_FLOCK)
51+
4152
CHECK_CXX_SOURCE_COMPILES("
4253
#include <sys/utsname.h>
4354
int main() {
@@ -93,6 +104,13 @@ if(FUCHSIA OR UNIX)
93104
-Wno-pedantic)
94105
endif()
95106

107+
if(CMAKE_SYSTEM_NAME STREQUAL "WASI")
108+
set(EXTRA_FLAGS
109+
${EXTRA_FLAGS}
110+
-D_WASI_EMULATED_MMAN
111+
-D_WASI_EMULATED_GETPID)
112+
endif()
113+
96114
if(COMPILER_RT_TARGET_HAS_ATOMICS)
97115
set(EXTRA_FLAGS
98116
${EXTRA_FLAGS}
@@ -105,6 +123,12 @@ if(COMPILER_RT_TARGET_HAS_FCNTL_LCK)
105123
-DCOMPILER_RT_HAS_FCNTL_LCK=1)
106124
endif()
107125

126+
if(COMPILER_RT_TARGET_HAS_FLOCK)
127+
set(EXTRA_FLAGS
128+
${EXTRA_FLAGS}
129+
-DCOMPILER_RT_HAS_FLOCK=1)
130+
endif()
131+
108132
if(COMPILER_RT_TARGET_HAS_UNAME)
109133
set(EXTRA_FLAGS
110134
${EXTRA_FLAGS}

compiler-rt/lib/profile/GCDAProfiling.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ void llvm_reset_counters(void) {
584584
}
585585
}
586586

587-
#if !defined(_WIN32)
587+
#if !defined(_WIN32) && !defined(__wasm__)
588588
COMPILER_RT_VISIBILITY
589589
pid_t __gcov_fork() {
590590
pid_t parent_pid = getpid();

compiler-rt/lib/profile/InstrProfilingPlatformLinux.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
|*
77
\*===----------------------------------------------------------------------===*/
88

9-
#if defined(__linux__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
10-
(defined(__sun__) && defined(__svr4__)) || defined(__NetBSD__) || \
11-
defined(_AIX)
9+
#if defined(__linux__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
10+
(defined(__sun__) && defined(__svr4__)) || defined(__NetBSD__) || \
11+
defined(_AIX) || defined(__wasm__)
1212

13-
#if !defined(_AIX)
13+
#if !defined(_AIX) && !defined(__wasm__)
1414
#include <elf.h>
1515
#include <link.h>
1616
#endif

compiler-rt/lib/profile/InstrProfilingPlatformOther.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88

99
#if !defined(__APPLE__) && !defined(__linux__) && !defined(__FreeBSD__) && \
1010
!defined(__Fuchsia__) && !(defined(__sun__) && defined(__svr4__)) && \
11-
!defined(__NetBSD__) && !defined(_WIN32) && !defined(_AIX)
11+
!defined(__NetBSD__) && !defined(_WIN32) && !defined(_AIX) && \
12+
!defined(__wasm__)
1213

1314
#include <stdlib.h>
1415
#include <stdio.h>

compiler-rt/lib/profile/InstrProfilingPort.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
#endif
5555

5656
#define COMPILER_RT_MAX_HOSTLEN 128
57-
#ifdef __ORBIS__
57+
#if defined(__ORBIS__) || defined(__wasi__)
5858
#define COMPILER_RT_GETHOSTNAME(Name, Len) ((void)(Name), (void)(Len), (-1))
5959
#else
6060
#define COMPILER_RT_GETHOSTNAME(Name, Len) lprofGetHostName(Name, Len)

compiler-rt/lib/profile/InstrProfilingUtil.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,11 @@ COMPILER_RT_VISIBILITY int lprofLockFd(int fd) {
153153
}
154154
}
155155
return 0;
156-
#else
156+
#elif defined(COMPILER_RT_HAS_FLOCK)
157157
flock(fd, LOCK_EX);
158158
return 0;
159+
#else
160+
return 0;
159161
#endif
160162
}
161163

@@ -178,9 +180,11 @@ COMPILER_RT_VISIBILITY int lprofUnlockFd(int fd) {
178180
}
179181
}
180182
return 0;
181-
#else
183+
#elif defined(COMPILER_RT_HAS_FLOCK)
182184
flock(fd, LOCK_UN);
183185
return 0;
186+
#else
187+
return 0;
184188
#endif
185189
}
186190

@@ -372,8 +376,8 @@ COMPILER_RT_VISIBILITY void lprofRestoreSigKill(void) {
372376

373377
COMPILER_RT_VISIBILITY int lprofReleaseMemoryPagesToOS(uintptr_t Begin,
374378
uintptr_t End) {
375-
#if defined(__ve__)
376-
// VE doesn't support madvise.
379+
#if defined(__ve__) || defined(__wasi__)
380+
// VE and WASI doesn't support madvise.
377381
return 0;
378382
#else
379383
size_t PageSize = getpagesize();

lld/test/wasm/custom-section-align.s

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
2+
# RUN: wasm-ld --no-entry %t.o -o %t.wasm
3+
# RUN: obj2yaml %t.wasm | FileCheck %s
4+
5+
# Check that "__llvm_covfun" custom section is aligned to 8 bytes.
6+
7+
.section .custom_section.__llvm_covfun,"GR",@,__covrec_A
8+
.int32 1
9+
.int8 2
10+
# pad .int8 0
11+
# .int8 0
12+
# .int8 0
13+
14+
.section .custom_section.__llvm_covfun,"GR",@,__covrec_B
15+
.int32 3
16+
17+
# CHECK: - Type: CUSTOM
18+
# CHECK-NEXT: Name: __llvm_covfun
19+
# CHECK-NEXT: Payload: '010000000200000003000000'
20+
21+
# Check that regular custom sections are not aligned.
22+
.section .custom_section.foo,"GR",@,foo_A
23+
.int32 1
24+
.int8 2
25+
26+
.section .custom_section.foo,"GR",@,foo_B
27+
.int32 3
28+
29+
# CHECK: - Type: CUSTOM
30+
# CHECK-NEXT: Name: foo
31+
# CHECK-NEXT: Payload: '010000000203000000'

0 commit comments

Comments
 (0)