Skip to content

Commit f2fa639

Browse files
committed
made internal function for read; removed errno guard class in getauxval
1 parent 09363d4 commit f2fa639

File tree

5 files changed

+89
-52
lines changed

5 files changed

+89
-52
lines changed

libc/src/__support/OSUtil/linux/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ add_object_library(
1212
mmap.cpp
1313
munmap.cpp
1414
prctl.cpp
15+
read.cpp
1516
HDRS
1617
io.h
1718
syscall.h
@@ -25,6 +26,10 @@ add_object_library(
2526
libc.hdr.types.struct_f_owner_ex
2627
libc.hdr.types.off_t
2728
libc.include.sys_syscall
29+
libc.src.__support.macros.sanitizer
30+
libc.hdr.types.size_t
31+
libc.hdr.types.ssize_t
32+
libc.include.unistd
2833
)
2934

3035
add_header_library(
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//===-- Linux implementation of read --------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/__support/OSUtil/read.h"
10+
11+
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
12+
#include "src/__support/common.h"
13+
#include "src/__support/macros/config.h"
14+
#include "src/__support/macros/sanitizer.h" // for MSAN_UNPOISON
15+
#include <sys/syscall.h> // For syscall numbers.
16+
17+
namespace LIBC_NAMESPACE_DECL {
18+
namespace internal {
19+
20+
ErrorOr<ssize_t> read(int fd, void *buf, size_t count) {
21+
ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_read, fd, buf, count);
22+
if (ret < 0)
23+
return Error(static_cast<int>(-ret));
24+
25+
// The cast is important since there is a check that dereferences the pointer
26+
// which fails on void*.
27+
MSAN_UNPOISON(reinterpret_cast<char *>(buf), count);
28+
return ret;
29+
}
30+
31+
} // namespace internal
32+
} // namespace LIBC_NAMESPACE_DECL

libc/src/__support/OSUtil/read.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===--------- Implementation header of the read function -------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_READ_H
10+
#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_READ_H
11+
12+
#include "hdr/types/size_t.h"
13+
#include "hdr/types/ssize_t.h"
14+
#include "hdr/unistd_macros.h"
15+
#include "src/__support/macros/config.h"
16+
#include "src/__support/error_or.h"
17+
18+
namespace LIBC_NAMESPACE_DECL {
19+
namespace internal {
20+
21+
ErrorOr<ssize_t> read(int fd, void *buf, size_t count);
22+
23+
} // namespace internal
24+
} // namespace LIBC_NAMESPACE_DECL
25+
26+
#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_READ_H

libc/src/sys/auxv/linux/getauxval.cpp

Lines changed: 19 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,22 @@
1111
#include "hdr/fcntl_macros.h"
1212
#include "src/__support/OSUtil/fcntl.h"
1313
#include "src/__support/common.h"
14-
#include "src/__support/libc_errno.h"
1514
#include "src/__support/error_or.h"
15+
#include "src/__support/libc_errno.h"
1616
#include "src/__support/macros/config.h"
1717
#include <linux/auxvec.h>
1818

1919
// for guarded initialization
2020
#include "src/__support/threads/callonce.h"
2121
#include "src/__support/threads/linux/futex_word.h"
2222

23-
// -----------------------------------------------------------------------------
24-
// TODO: This file should not include other public libc functions. Calling other
25-
// public libc functions is an antipattern within LLVM-libc. This needs to be
26-
// cleaned up. DO NOT COPY THIS.
27-
// -----------------------------------------------------------------------------
28-
2923
// for mallocing the global auxv
3024
#include "src/__support/OSUtil/mmap.h"
3125
#include "src/__support/OSUtil/munmap.h"
3226

3327
// for reading /proc/self/auxv
3428
#include "src/__support/OSUtil/prctl.h"
35-
#include "src/unistd/read.h"
29+
#include "src/__support/OSUtil/read.h"
3630

3731
// getauxval will work either with or without __cxa_atexit support.
3832
// In order to detect if __cxa_atexit is supported, we define a weak symbol.
@@ -47,18 +41,6 @@ namespace LIBC_NAMESPACE_DECL {
4741

4842
constexpr static size_t MAX_AUXV_ENTRIES = 64;
4943

50-
// Helper to recover or set errno
51-
class AuxvErrnoGuard {
52-
public:
53-
AuxvErrnoGuard() : saved(libc_errno), failure(false) {}
54-
~AuxvErrnoGuard() { libc_errno = failure ? ENOENT : saved; }
55-
void mark_failure() { failure = true; }
56-
57-
private:
58-
int saved;
59-
bool failure;
60-
};
61-
6244
// Helper to manage the memory
6345
static AuxEntry *auxv = nullptr;
6446

@@ -92,7 +74,7 @@ class AuxvMMapGuard {
9274
void *get() const { return ptr.value(); }
9375

9476
private:
95-
ErrorOr<void*> ptr;
77+
ErrorOr<void *> ptr;
9678
};
9779

9880
class AuxvFdGuard {
@@ -134,7 +116,7 @@ static void initialize_auxv_once(void) {
134116
// prctl.
135117
#ifdef PR_GET_AUXV
136118
auto ret = internal::prctl(PR_GET_AUXV, reinterpret_cast<unsigned long>(ptr),
137-
available_size, 0, 0);
119+
available_size, 0, 0);
138120
if (ret.has_value()) {
139121
mmap_guard.submit_to_global();
140122
return;
@@ -144,23 +126,22 @@ static void initialize_auxv_once(void) {
144126
if (!fd_guard.valid())
145127
return;
146128
auto *buf = reinterpret_cast<char *>(ptr);
147-
libc_errno = 0;
148129
bool error_detected = false;
149130
// Read until we use up all the available space or we finish reading the file.
150131
while (available_size != 0) {
151-
ssize_t bytes_read =
152-
LIBC_NAMESPACE::read(fd_guard.get(), buf, available_size);
153-
if (bytes_read <= 0) {
154-
if (libc_errno == EINTR)
132+
auto bytes_read = internal::read(fd_guard.get(), buf, available_size);
133+
if (!bytes_read.has_value() ||
134+
(bytes_read.has_value() && bytes_read.value() == 0)) {
135+
if (bytes_read.error() == EINTR)
155136
continue;
156137
// Now, we either have an non-recoverable error or we have reached the end
157138
// of the file. Mark `error_detected` accordingly.
158-
if (bytes_read == -1)
139+
if (!bytes_read.has_value())
159140
error_detected = true;
160141
break;
161142
}
162-
buf += bytes_read;
163-
available_size -= bytes_read;
143+
buf += bytes_read.value();
144+
available_size -= bytes_read.value();
164145
}
165146
// If we get out of the loop without an error, the auxv is ready.
166147
if (!error_detected)
@@ -172,17 +153,17 @@ static AuxEntry read_entry(int fd) {
172153
size_t size = sizeof(AuxEntry);
173154
char *ptr = reinterpret_cast<char *>(&buf);
174155
while (size > 0) {
175-
ssize_t ret = LIBC_NAMESPACE::read(fd, ptr, size);
176-
if (ret < 0) {
177-
if (libc_errno == EINTR)
156+
auto ret = internal::read(fd, ptr, size);
157+
if (!ret.has_value()) {
158+
if (ret.error() == EINTR)
178159
continue;
179160
// Error detected, return AT_NULL
180161
buf.id = AT_NULL;
181162
buf.value = AT_NULL;
182163
break;
183164
}
184-
ptr += ret;
185-
size -= ret;
165+
ptr += ret.value();
166+
size -= ret.value();
186167
}
187168
return buf;
188169
}
@@ -191,15 +172,13 @@ LLVM_LIBC_FUNCTION(unsigned long, getauxval, (unsigned long id)) {
191172
// Fast path when libc is loaded by its own initialization code. In this case,
192173
// app.auxv_ptr is already set to the auxv passed on the initial stack of the
193174
// process.
194-
AuxvErrnoGuard errno_guard;
195175

196-
auto search_auxv = [&errno_guard](AuxEntry *auxv,
197-
unsigned long id) -> AuxEntryType {
176+
auto search_auxv = [](AuxEntry *auxv, unsigned long id) -> AuxEntryType {
198177
for (auto *ptr = auxv; ptr->id != AT_NULL; ptr++)
199178
if (ptr->id == id)
200179
return ptr->value;
201180

202-
errno_guard.mark_failure();
181+
libc_errno = ENOENT;
203182
return AT_NULL;
204183
};
205184

@@ -227,7 +206,7 @@ LLVM_LIBC_FUNCTION(unsigned long, getauxval, (unsigned long id)) {
227206
}
228207

229208
// cannot find the entry after all methods, mark failure and return 0
230-
errno_guard.mark_failure();
209+
libc_errno = ENOENT;
231210
return AT_NULL;
232211
}
233212
} // namespace LIBC_NAMESPACE_DECL

libc/src/unistd/linux/read.cpp

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,20 @@
88

99
#include "src/unistd/read.h"
1010

11-
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
12-
#include "src/__support/common.h"
11+
#include "src/__support/OSUtil/read.h" // For internal syscall function.
1312
#include "src/__support/libc_errno.h"
14-
#include "src/__support/macros/config.h"
15-
#include "src/__support/macros/sanitizer.h" // for MSAN_UNPOISON
16-
#include <sys/syscall.h> // For syscall numbers.
13+
#include "src/__support/common.h"
1714

1815
namespace LIBC_NAMESPACE_DECL {
1916

2017
LLVM_LIBC_FUNCTION(ssize_t, read, (int fd, void *buf, size_t count)) {
21-
ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_read, fd, buf, count);
22-
if (ret < 0) {
23-
libc_errno = static_cast<int>(-ret);
18+
auto ret = internal::read(fd, buf, count);
19+
if (!ret.has_value()) {
20+
libc_errno = static_cast<int>(ret.error());
2421
return -1;
2522
}
26-
// The cast is important since there is a check that dereferences the pointer
27-
// which fails on void*.
28-
MSAN_UNPOISON(reinterpret_cast<char *>(buf), count);
29-
return ret;
23+
24+
return ret.value();
3025
}
3126

3227
} // namespace LIBC_NAMESPACE_DECL

0 commit comments

Comments
 (0)