Skip to content

Commit a6c9030

Browse files
committed
Update libc_errno to work correctly for both overlay and full build modes.
1 parent 2cbda75 commit a6c9030

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+320
-325
lines changed

libc/src/errno/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1+
set(full_build_flag "")
2+
if(LLVM_LIBC_FULL_BUILD)
3+
set(full_build_flag "-DLIBC_FULL_BUILD")
4+
endif()
5+
16
add_entrypoint_object(
27
errno
38
SRCS
49
libc_errno.cpp
510
HDRS
611
libc_errno.h # Include this
12+
COMPILE_OPTIONS
13+
${full_build_flag}
714
DEPENDS
815
libc.include.errno
916
libc.src.__support.common

libc/src/errno/libc_errno.cpp

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,44 @@
1111

1212
namespace LIBC_NAMESPACE {
1313

14-
#ifdef LIBC_TARGET_ARCH_IS_GPU
15-
struct ErrnoConsumer {
16-
void operator=(int) {}
14+
struct Errno {
15+
void operator=(int);
16+
operator int();
1717
};
18-
#endif
1918

20-
extern "C" {
21-
#ifdef LIBC_COPT_PUBLIC_PACKAGING
22-
// TODO: Declare __llvmlibc_errno only under LIBC_COPT_PUBLIC_PACKAGING and
23-
// __llvmlibc_internal_errno otherwise.
24-
// In overlay mode, this will be an unused thread local variable as libc_errno
25-
// will resolve to errno from the system libc's errno.h. In full build mode
26-
// however, libc_errno will resolve to this thread local variable via the errno
27-
// macro defined in LLVM libc's public errno.h header file.
28-
// TODO: Use a macro to distinguish full build and overlay build which can be
29-
// used to exclude __llvmlibc_errno under overlay build.
19+
} // namespace LIBC_NAMESPACE
20+
3021
#ifdef LIBC_TARGET_ARCH_IS_GPU
31-
ErrnoConsumer __llvmlibc_errno;
32-
#else
22+
// If we are targeting the GPU we currently don't support 'errno'. We simply
23+
// consume it.
24+
void LIBC_NAMESPACE::Errno::operator=(int) {}
25+
LIBC_NAMESPACE::Errno::operator int() { return 0; }
26+
27+
#elif !defined(LIBC_COPT_PUBLIC_PACKAGING)
28+
// This mode is for unit testing. We just use another internal errno.
29+
LIBC_THREAD_LOCAL int __llvmlibc_internal_errno;
30+
31+
void LIBC_NAMESPACE::Errno::operator=(int a) { __llvmlibc_internal_errno = a; }
32+
LIBC_NAMESPACE::Errno::operator int() { return __llvmlibc_internal_errno; }
33+
34+
#elif defined(LIBC_FULL_BUILD)
35+
// This mode is for public libc archive, hermetic, and integration tests.
36+
// In full build mode, we provide all the errno storage ourselves.
37+
extern "C" {
3338
LIBC_THREAD_LOCAL int __llvmlibc_errno;
34-
#endif // LIBC_TARGET_ARCH_IS_GPU
39+
}
40+
41+
void LIBC_NAMESPACE::Errno::operator=(int a) { __llvmlibc_errno = a; }
42+
LIBC_NAMESPACE::Errno::operator int() { return __llvmlibc_errno; }
43+
3544
#else
36-
LIBC_THREAD_LOCAL int __llvmlibc_internal_errno;
37-
#endif
38-
} // extern "C"
45+
// In overlay mode, we simply use the system errno.
46+
#include <errno.h>
3947

40-
} // namespace LIBC_NAMESPACE
48+
void LIBC_NAMESPACE::Errno::operator=(int a) { errno = a; }
49+
LIBC_NAMESPACE::Errno::operator int() { return errno; }
50+
51+
#endif // LIBC_FULL_BUILD
52+
53+
// Define the global `libc_errno` instance.
54+
LIBC_NAMESPACE::Errno libc_errno;

libc/src/errno/libc_errno.h

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,43 +14,17 @@
1414

1515
#include <errno.h>
1616

17-
// If we are targeting the GPU we currently don't support 'errno'. We simply
18-
// consume it.
19-
#ifdef LIBC_TARGET_ARCH_IS_GPU
17+
// This header is to be consumed by internal implementations, in which all of
18+
// them should refer to `libc_errno` instead of using `errno` directly from
19+
// <errno.h> header.
20+
2021
namespace LIBC_NAMESPACE {
21-
struct ErrnoConsumer {
22-
void operator=(int) {}
22+
struct Errno {
23+
void operator=(int);
24+
operator int();
2325
};
2426
} // namespace LIBC_NAMESPACE
25-
#endif
26-
27-
// All of the libc runtime and test code should use the "libc_errno" macro. They
28-
// should not refer to the "errno" macro directly.
29-
#ifdef LIBC_COPT_PUBLIC_PACKAGING
30-
#ifdef LIBC_TARGET_ARCH_IS_GPU
31-
extern "C" LIBC_NAMESPACE::ErrnoConsumer __llvmlibc_errno;
32-
#define libc_errno __llvmlibc_errno
33-
#else
34-
// This macro will resolve to errno from the errno.h file included above. Under
35-
// full build, this will be LLVM libc's errno. In overlay build, it will be
36-
// system libc's errno.
37-
#define libc_errno errno
38-
#endif
39-
#else
40-
namespace LIBC_NAMESPACE {
4127

42-
// TODO: On the GPU build this will be mapped to a single global value. We need
43-
// to ensure that tests are not run with multiple threads that depend on errno
44-
// until we have true 'thread_local' support on the GPU.
45-
extern "C" LIBC_THREAD_LOCAL int __llvmlibc_internal_errno;
46-
47-
// TODO: After all of libc/src and libc/test are switched over to use
48-
// libc_errno, this header file will be "shipped" via an add_entrypoint_object
49-
// target. At which point libc_errno, should point to __llvmlibc_internal_errno
50-
// if LIBC_COPT_PUBLIC_PACKAGING is not defined.
51-
#define libc_errno LIBC_NAMESPACE::__llvmlibc_internal_errno
52-
53-
} // namespace LIBC_NAMESPACE
54-
#endif
28+
extern LIBC_NAMESPACE::Errno libc_errno;
5529

5630
#endif // LLVM_LIBC_SRC_ERRNO_LIBC_ERRNO_H

libc/test/integration/src/pthread/pthread_create_test.cpp

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ static void *successThread(void *Arg) {
4747
pthread_t th = LIBC_NAMESPACE::pthread_self();
4848
auto *thread = reinterpret_cast<LIBC_NAMESPACE::Thread *>(&th);
4949

50-
ASSERT_EQ(libc_errno, 0);
50+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
5151
ASSERT_TRUE(thread);
5252
ASSERT_TRUE(thread->attrib);
5353

@@ -62,22 +62,22 @@ static void *successThread(void *Arg) {
6262
ASSERT_EQ(LIBC_NAMESPACE::pthread_attr_getstack(expec_attrs, &expec_stack,
6363
&expec_stacksize),
6464
0);
65-
ASSERT_EQ(libc_errno, 0);
65+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
6666

6767
ASSERT_EQ(
6868
LIBC_NAMESPACE::pthread_attr_getstacksize(expec_attrs, &expec_stacksize2),
6969
0);
70-
ASSERT_EQ(libc_errno, 0);
70+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
7171

7272
ASSERT_EQ(
7373
LIBC_NAMESPACE::pthread_attr_getguardsize(expec_attrs, &expec_guardsize),
7474
0);
75-
ASSERT_EQ(libc_errno, 0);
75+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
7676

7777
ASSERT_EQ(
7878
LIBC_NAMESPACE::pthread_attr_getdetachstate(expec_attrs, &expec_detached),
7979
0);
80-
ASSERT_EQ(libc_errno, 0);
80+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
8181

8282
ASSERT_EQ(expec_stacksize, expec_stacksize2);
8383

@@ -125,7 +125,7 @@ static void *successThread(void *Arg) {
125125
// permissions. Maybe we can read from /proc/{self}/map?
126126

127127
ASSERT_EQ(LIBC_NAMESPACE::pthread_attr_destroy(expec_attrs), 0);
128-
ASSERT_EQ(libc_errno, 0);
128+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
129129

130130
// Arg is malloced, so free.
131131
delete th_arg;
@@ -140,34 +140,34 @@ static void run_success_config(int detachstate, size_t guardsize,
140140
pthread_attr_t *attr = &(th_arg->attrs);
141141

142142
ASSERT_EQ(LIBC_NAMESPACE::pthread_attr_init(attr), 0);
143-
ASSERT_EQ(libc_errno, 0);
143+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
144144

145145
ASSERT_EQ(LIBC_NAMESPACE::pthread_attr_setdetachstate(attr, detachstate), 0);
146-
ASSERT_EQ(libc_errno, 0);
146+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
147147

148148
ASSERT_EQ(LIBC_NAMESPACE::pthread_attr_setguardsize(attr, guardsize), 0);
149-
ASSERT_EQ(libc_errno, 0);
149+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
150150

151151
void *Stack = nullptr;
152152
if (customstack) {
153153
Stack = LIBC_NAMESPACE::mmap(nullptr, stacksize, PROT_READ | PROT_WRITE,
154154
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
155155
ASSERT_NE(Stack, MAP_FAILED);
156156
ASSERT_NE(Stack, static_cast<void *>(nullptr));
157-
ASSERT_EQ(libc_errno, 0);
157+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
158158

159159
ASSERT_EQ(LIBC_NAMESPACE::pthread_attr_setstack(attr, Stack, stacksize), 0);
160-
ASSERT_EQ(libc_errno, 0);
160+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
161161
} else {
162162
ASSERT_EQ(LIBC_NAMESPACE::pthread_attr_setstacksize(attr, stacksize), 0);
163-
ASSERT_EQ(libc_errno, 0);
163+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
164164
}
165165

166166
void *expec_ret = nullptr;
167167
if (detachstate == PTHREAD_CREATE_JOINABLE) {
168168
ASSERT_EQ(LIBC_NAMESPACE::getrandom(&expec_ret, sizeof(expec_ret), 0),
169169
static_cast<ssize_t>(sizeof(expec_ret)));
170-
ASSERT_EQ(libc_errno, 0);
170+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
171171
}
172172

173173
th_arg->ret = expec_ret;
@@ -178,17 +178,17 @@ static void run_success_config(int detachstate, size_t guardsize,
178178
ASSERT_EQ(LIBC_NAMESPACE::pthread_create(&tid, attr, successThread,
179179
reinterpret_cast<void *>(th_arg)),
180180
0);
181-
ASSERT_EQ(libc_errno, 0);
181+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
182182

183183
if (detachstate == PTHREAD_CREATE_JOINABLE) {
184184
void *th_ret;
185185
ASSERT_EQ(LIBC_NAMESPACE::pthread_join(tid, &th_ret), 0);
186-
ASSERT_EQ(libc_errno, 0);
186+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
187187
ASSERT_EQ(th_ret, expec_ret);
188188

189189
if (customstack) {
190190
ASSERT_EQ(LIBC_NAMESPACE::munmap(Stack, stacksize), 0);
191-
ASSERT_EQ(libc_errno, 0);
191+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
192192
}
193193
} else {
194194
ASSERT_FALSE(customstack);
@@ -260,23 +260,23 @@ static void create_and_check_failure_thread(pthread_attr_t *attr) {
260260
// was just really larger we failed mmap.
261261
ASSERT_TRUE(result == EINVAL || result == EAGAIN);
262262
// pthread_create should NOT set errno on error
263-
ASSERT_EQ(libc_errno, 0);
263+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
264264

265265
ASSERT_EQ(LIBC_NAMESPACE::pthread_attr_destroy(attr), 0);
266-
ASSERT_EQ(libc_errno, 0);
266+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
267267
}
268268

269269
static void run_failure_config(size_t guardsize, size_t stacksize) {
270270
pthread_attr_t attr;
271271
guardsize &= -EXEC_PAGESIZE;
272272
ASSERT_EQ(LIBC_NAMESPACE::pthread_attr_init(&attr), 0);
273-
ASSERT_EQ(libc_errno, 0);
273+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
274274

275275
ASSERT_EQ(LIBC_NAMESPACE::pthread_attr_setguardsize(&attr, guardsize), 0);
276-
ASSERT_EQ(libc_errno, 0);
276+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
277277

278278
ASSERT_EQ(LIBC_NAMESPACE::pthread_attr_setstacksize(&attr, stacksize), 0);
279-
ASSERT_EQ(libc_errno, 0);
279+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
280280

281281
create_and_check_failure_thread(&attr);
282282
}
@@ -301,32 +301,32 @@ static void run_failure_tests() {
301301

302302
// Stacksize too small.
303303
ASSERT_EQ(LIBC_NAMESPACE::pthread_attr_init(&attr), 0);
304-
ASSERT_EQ(libc_errno, 0);
304+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
305305
attr.__stacksize = PTHREAD_STACK_MIN - 16;
306306
create_and_check_failure_thread(&attr);
307307

308308
// Stack misaligned.
309309
ASSERT_EQ(LIBC_NAMESPACE::pthread_attr_init(&attr), 0);
310-
ASSERT_EQ(libc_errno, 0);
310+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
311311
attr.__stack = reinterpret_cast<void *>(1);
312312
create_and_check_failure_thread(&attr);
313313

314314
// Stack + stacksize misaligned.
315315
ASSERT_EQ(LIBC_NAMESPACE::pthread_attr_init(&attr), 0);
316-
ASSERT_EQ(libc_errno, 0);
316+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
317317
attr.__stacksize = PTHREAD_STACK_MIN + 1;
318318
attr.__stack = reinterpret_cast<void *>(16);
319319
create_and_check_failure_thread(&attr);
320320

321321
// Guardsize misaligned.
322322
ASSERT_EQ(LIBC_NAMESPACE::pthread_attr_init(&attr), 0);
323-
ASSERT_EQ(libc_errno, 0);
323+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
324324
attr.__guardsize = EXEC_PAGESIZE / 2;
325325
create_and_check_failure_thread(&attr);
326326

327327
// Detachstate is unknown.
328328
ASSERT_EQ(LIBC_NAMESPACE::pthread_attr_init(&attr), 0);
329-
ASSERT_EQ(libc_errno, 0);
329+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
330330
attr.__detachstate = -1;
331331
create_and_check_failure_thread(&attr);
332332
}

libc/test/integration/src/pthread/pthread_join_test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ static void nullJoinTest() {
1919
pthread_t Tid;
2020
ASSERT_EQ(LIBC_NAMESPACE::pthread_create(&Tid, nullptr, simpleFunc, nullptr),
2121
0);
22-
ASSERT_EQ(libc_errno, 0);
22+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
2323
ASSERT_EQ(LIBC_NAMESPACE::pthread_join(Tid, nullptr), 0);
24-
ASSERT_EQ(libc_errno, 0);
24+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
2525
}
2626

2727
TEST_MAIN() {

libc/test/integration/src/unistd/getcwd_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ TEST_MAIN(int argc, char **argv, char **envp) {
3030
// Bad size
3131
cwd = LIBC_NAMESPACE::getcwd(buffer, 0);
3232
ASSERT_TRUE(cwd == nullptr);
33-
ASSERT_EQ(libc_errno, EINVAL);
33+
ASSERT_EQ(static_cast<int>(libc_errno), EINVAL);
3434
libc_errno = 0;
3535

3636
// Insufficient size

libc/test/src/dirent/dirent_test.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ TEST(LlvmLibcDirentTest, SimpleOpenAndRead) {
4444
}
4545

4646
// Verify that we don't break out of the above loop in error.
47-
ASSERT_EQ(libc_errno, 0);
47+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
4848

4949
ASSERT_TRUE(file1 != nullptr);
5050
ASSERT_TRUE(file2 != nullptr);
@@ -58,14 +58,14 @@ TEST(LlvmLibcDirentTest, OpenNonExistentDir) {
5858
libc_errno = 0;
5959
::DIR *dir = LIBC_NAMESPACE::opendir("___xyz123__.non_existent__");
6060
ASSERT_TRUE(dir == nullptr);
61-
ASSERT_EQ(libc_errno, ENOENT);
61+
ASSERT_EQ(static_cast<int>(libc_errno), ENOENT);
6262
libc_errno = 0;
6363
}
6464

6565
TEST(LlvmLibcDirentTest, OpenFile) {
6666
libc_errno = 0;
6767
::DIR *dir = LIBC_NAMESPACE::opendir("testdata/file1.txt");
6868
ASSERT_TRUE(dir == nullptr);
69-
ASSERT_EQ(libc_errno, ENOTDIR);
69+
ASSERT_EQ(static_cast<int>(libc_errno), ENOTDIR);
7070
libc_errno = 0;
7171
}

libc/test/src/errno/errno_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@
1212
TEST(LlvmLibcErrnoTest, Basic) {
1313
int test_val = 123;
1414
libc_errno = test_val;
15-
ASSERT_EQ(test_val, libc_errno);
15+
ASSERT_EQ(static_cast<int>(libc_errno), test_val);
1616
}

libc/test/src/fcntl/creat_test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ TEST(LlvmLibcCreatTest, CreatAndOpen) {
1919
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
2020
constexpr const char *TEST_FILE = "testdata/creat.test";
2121
int fd = LIBC_NAMESPACE::creat(TEST_FILE, S_IRWXU);
22-
ASSERT_EQ(libc_errno, 0);
22+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
2323
ASSERT_GT(fd, 0);
2424
ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
2525

2626
fd = LIBC_NAMESPACE::open(TEST_FILE, O_RDONLY);
27-
ASSERT_EQ(libc_errno, 0);
27+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
2828
ASSERT_GT(fd, 0);
2929
ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
3030

libc/test/src/fcntl/openat_test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ TEST(LlvmLibcUniStd, OpenAndReadTest) {
2121
constexpr const char *TEST_DIR = "testdata";
2222
constexpr const char *TEST_FILE = "openat.test";
2323
int dir_fd = LIBC_NAMESPACE::open(TEST_DIR, O_DIRECTORY);
24-
ASSERT_EQ(libc_errno, 0);
24+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
2525
ASSERT_GT(dir_fd, 0);
2626
constexpr const char TEST_MSG[] = "openat test";
2727
constexpr int TEST_MSG_SIZE = sizeof(TEST_MSG) - 1;
2828

2929
int read_fd = LIBC_NAMESPACE::openat(dir_fd, TEST_FILE, O_RDONLY);
30-
ASSERT_EQ(libc_errno, 0);
30+
ASSERT_EQ(static_cast<int>(libc_errno), 0);
3131
ASSERT_GT(read_fd, 0);
3232
char read_buf[TEST_MSG_SIZE];
3333
ASSERT_THAT(LIBC_NAMESPACE::read(read_fd, read_buf, TEST_MSG_SIZE),

0 commit comments

Comments
 (0)