Skip to content

Commit d4efc3e

Browse files
[Coverage][WebAssembly] Add initial support for WebAssembly/WASI (#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 2f077ec commit d4efc3e

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
@@ -163,6 +163,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA,
163163
AddRunTimeLibs(ToolChain, ToolChain.getDriver(), CmdArgs, Args);
164164
}
165165

166+
ToolChain.addProfileRTLibs(Args, CmdArgs);
167+
166168
CmdArgs.push_back("-o");
167169
CmdArgs.push_back(Output.getFilename());
168170

compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ set(ALL_HWASAN_SUPPORTED_ARCH ${X86_64} ${ARM64} ${RISCV64})
7777
set(ALL_MEMPROF_SUPPORTED_ARCH ${X86_64})
7878
set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32} ${PPC64}
7979
${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}
80-
${RISCV32} ${RISCV64} ${LOONGARCH64})
80+
${RISCV32} ${RISCV64} ${LOONGARCH64} ${WASM32})
8181
set(ALL_CTX_PROFILE_SUPPORTED_ARCH ${X86_64})
8282
if (OS_NAME MATCHES "FreeBSD")
8383
set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64})

compiler-rt/cmake/config-ix.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ else()
822822
endif()
823823

824824
if (PROFILE_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND
825-
OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX")
825+
OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX|WASI")
826826
set(COMPILER_RT_HAS_PROFILE TRUE)
827827
else()
828828
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
@@ -152,9 +152,11 @@ COMPILER_RT_VISIBILITY int lprofLockFd(int fd) {
152152
}
153153
}
154154
return 0;
155-
#else
155+
#elif defined(COMPILER_RT_HAS_FLOCK)
156156
flock(fd, LOCK_EX);
157157
return 0;
158+
#else
159+
return 0;
158160
#endif
159161
}
160162

@@ -177,9 +179,11 @@ COMPILER_RT_VISIBILITY int lprofUnlockFd(int fd) {
177179
}
178180
}
179181
return 0;
180-
#else
182+
#elif defined(COMPILER_RT_HAS_FLOCK)
181183
flock(fd, LOCK_UN);
182184
return 0;
185+
#else
186+
return 0;
183187
#endif
184188
}
185189

@@ -353,8 +357,8 @@ COMPILER_RT_VISIBILITY void lprofRestoreSigKill(void) {
353357

354358
COMPILER_RT_VISIBILITY int lprofReleaseMemoryPagesToOS(uintptr_t Begin,
355359
uintptr_t End) {
356-
#if defined(__ve__)
357-
// VE doesn't support madvise.
360+
#if defined(__ve__) || defined(__wasi__)
361+
// VE and WASI doesn't support madvise.
358362
return 0;
359363
#else
360364
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)