[libc] Add implementation of errno and define the other macros of errno.h.

Reviewers: stanshebs, alexbrachet

Subscribers: mgorny, MaskRay, tschuett, libc-commits

Tags: #libc-project

Differential Revision: https://reviews.llvm.org/D71094
This commit is contained in:
Siva Chandra Reddy 2019-12-05 12:09:24 -08:00
parent af52d5a04c
commit 453c85ff0f
14 changed files with 332 additions and 2 deletions

View File

@ -1,5 +1,7 @@
include "config/public_api.td"
include "spec/linux.td"
include "spec/posix.td"
include "spec/stdc.td"
def FloatT : TypeDecl<"float_t"> {
@ -28,6 +30,13 @@ def NullMacro : MacroDef<"NULL"> {
}];
}
def ErrnoMacro : MacroDef<"errno"> {
let Defn = [{
int *__errno_location();
#define errno (*__errno_location())
}];
}
def MathAPI : PublicAPI<"math.h"> {
let Functions = [
"acos",
@ -83,3 +92,22 @@ def StdIOAPI : PublicAPI<"stdio.h"> {
"snprintf",
];
}
def ErrnoAPI : PublicAPI<"errno.h"> {
let Macros = [
ErrnoMacro,
// We largely depend on linux/errno.h to give us the
// various error macro definitions. However, some libc
// implementations have chosen to provide definitions
// for some of the error macros to account for the ones
// missing in linux/errno.h. There is no harm in doing
// the same here if we define the macros only when they
// are not already defined.
MacroDefineIfNot<"ENOTSUP", "EOPNOTSUPP">,
MacroDefineIfNot<"ECANCELED", "125">,
MacroDefineIfNot<"EOWNERDEAD", "130">,
MacroDefineIfNot<"ENOTRECOVERABLE", "131">,
MacroDefineIfNot<"ERFKILL", "132">,
MacroDefineIfNot<"EHWPOISON", "133">,
];
}

View File

@ -0,0 +1,11 @@
//===---------------- Linux specific errno.h definitions ------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
%%begin()
#include <linux/errno.h>

View File

@ -10,6 +10,16 @@ class MacroDef<string name> {
string Defn = "";
}
class SimpleMacroDef<string name, string value> : MacroDef<name> {
let Defn = !strconcat("#define ", name, " ", value);
}
class MacroDefineIfNot<string name, string value> : MacroDef<name> {
let Defn = !strconcat("#ifndef ", name, "\n",
"#define " , name, " ", value, "\n",
"#endif // ", name);
}
class PublicAPI<string name> {
string HeaderName = name;
list<MacroDef> Macros = [];

View File

@ -28,3 +28,13 @@ add_gen_header(
DEPENDS
llvm_libc_common_h
)
add_gen_header(
errno_h
DEF_FILE errno.h.def
PARAMS
platform_errno=../config/${LIBC_TARGET_OS}/errno.h.in
GEN_HDR errno.h
DATA_FILES
../config/${LIBC_TARGET_OS}/errno.h.in
)

18
libc/include/errno.h.def Normal file
View File

@ -0,0 +1,18 @@
//===---------------- C standard library header errno.h ------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_ERRNO_H
#define LLVM_LIBC_ERRNO_H
#include <__llvm-libc-common.h>
%%include_file(${platform_errno})
%%public_api()
#endif // LLVM_LIBC_ERRNO_H

View File

@ -2,8 +2,10 @@
add_entrypoint_library(
llvmlibc
DEPENDS
# errno.h entrypoints
__errno_location
# string.h entrypoints
## C standard library entrypoints
strcpy
strcat
)

66
libc/spec/linux.td Normal file
View File

@ -0,0 +1,66 @@
def Linux : StandardSpec<"Linux"> {
HeaderSpec Errno = HeaderSpec<
"errno.h",
[
Macro<"ENOMEDIUM">,
Macro<"ENOTBLK">,
Macro<"EMEDIUMTYPE">,
Macro<"EBADSLT">,
Macro<"ECHRNG">,
Macro<"ERFKILL">,
Macro<"EUSERS">,
Macro<"EBADR">,
Macro<"EL3HLT">,
Macro<"ENOTUNIQ">,
Macro<"EXFULL">,
Macro<"EHOSTDOWN">,
Macro<"EL3RST">,
Macro<"ENOPKG">,
Macro<"ENOCSI">,
Macro<"EUNATCH">,
Macro<"EREMCHG">,
Macro<"ETOOMANYREFS">,
Macro<"EL2HLT">,
Macro<"EBADFD">,
Macro<"EREMOTEIO">,
Macro<"ENAVAIL">,
Macro<"ELIBEXEC">,
Macro<"ESHUTDOWN">,
Macro<"ENOKEY">,
Macro<"ESTRPIPE">,
Macro<"EKEYREJECTED">,
Macro<"ESRMNT">,
Macro<"EKEYREVOKED">,
Macro<"EBADE">,
Macro<"ELIBBAD">,
Macro<"EISNAM">,
Macro<"EBFONT">,
Macro<"EPFNOSUPPORT">,
Macro<"EREMOTE">,
Macro<"EDEADLOCK">,
Macro<"ENONET">,
Macro<"EDOTDOT">,
Macro<"EKEYEXPIRED">,
Macro<"ELIBSCN">,
Macro<"ERESTART">,
Macro<"EBADRQC">,
Macro<"EUCLEAN">,
Macro<"ENOANO">,
Macro<"ELIBACC">,
Macro<"EHWPOISON">,
Macro<"ELIBMAX">,
Macro<"ESOCKTNOSUPPORT">,
Macro<"ENOTNAM">,
Macro<"ELNRNG">,
Macro<"EL2NSYNC">,
Macro<"EADV">,
Macro<"ECOMM">,
],
[], // Types
[] // Functions
>;
let Headers = [
Errno,
];
}

91
libc/spec/posix.td Normal file
View File

@ -0,0 +1,91 @@
def POSIX : StandardSpec<"POSIX"> {
HeaderSpec Errno = HeaderSpec<
"errno.h",
[
Macro<"E2BIG">,
Macro<"EACCES">,
Macro<"EADDRINUSE">,
Macro<"EADDRNOTAVAIL">,
Macro<"EAFNOSUPPORT">,
Macro<"EAGAIN">,
Macro<"EALREADY">,
Macro<"EBADF">,
Macro<"EBADMSG">,
Macro<"EBUSY">,
Macro<"ECANCELED">,
Macro<"ECHILD">,
Macro<"ECONNABORTED">,
Macro<"ECONNREFUSED">,
Macro<"ECONNRESET">,
Macro<"EDEADLK">,
Macro<"EDESTADDRREQ">,
Macro<"EDQUOT">,
Macro<"EEXIST">,
Macro<"EFAULT">,
Macro<"EFBIG">,
Macro<"EHOSTUNREACH">,
Macro<"EIDRM">,
Macro<"EINPROGRESS">,
Macro<"EINTR">,
Macro<"EINVAL">,
Macro<"EIO">,
Macro<"EISCONN">,
Macro<"EISDIR">,
Macro<"ELOOP">,
Macro<"EMFILE">,
Macro<"EMLINK">,
Macro<"EMSGSIZE">,
Macro<"EMULTIHOP">,
Macro<"ENAMETOOLONG">,
Macro<"ENETDOWN">,
Macro<"ENETRESET">,
Macro<"ENETUNREACH">,
Macro<"ENFILE">,
Macro<"ENOBUFS">,
Macro<"ENODATA">,
Macro<"ENODEV">,
Macro<"ENOENT">,
Macro<"ENOEXEC">,
Macro<"ENOLCK">,
Macro<"ENOLINK">,
Macro<"ENOMEM">,
Macro<"ENOMSG">,
Macro<"ENOPROTOOPT">,
Macro<"ENOSPC">,
Macro<"ENOSR">,
Macro<"ENOSTR">,
Macro<"ENOSYS">,
Macro<"ENOTCONN">,
Macro<"ENOTDIR">,
Macro<"ENOTEMPTY">,
Macro<"ENOTRECOVERABLE">,
Macro<"ENOTSOCK">,
Macro<"ENOTSUP">,
Macro<"ENOTTY">,
Macro<"ENXIO">,
Macro<"EOPNOTSUPP">,
Macro<"EOVERFLOW">,
Macro<"EOWNERDEAD">,
Macro<"EPERM">,
Macro<"EPIPE">,
Macro<"EPROTO">,
Macro<"EPROTONOSUPPORT">,
Macro<"EPROTOTYPE">,
Macro<"EROFS">,
Macro<"ESPIPE">,
Macro<"ESRCH">,
Macro<"ESTALE">,
Macro<"ETIME">,
Macro<"ETIMEDOUT">,
Macro<"ETXTBSY">,
Macro<"EWOULDBLOCK">,
Macro<"EXDEV">,
],
[], // Types
[] // Functions
>;
let Headers = [
Errno,
];
}

View File

@ -170,7 +170,20 @@ def StdC : StandardSpec<"stdc"> {
]
>;
HeaderSpec Errno = HeaderSpec<
"errno.h",
[
Macro<"errno">,
Macro<"EDOM">,
Macro<"EILSEQ">,
Macro<"ERANGE">,
],
[], // Types
[] // Functions
>;
let Headers = [
Errno,
Math,
String,
StdIO,

View File

@ -1,4 +1,5 @@
add_subdirectory(string)
add_subdirectory(errno)
add_subdirectory(math)
add_subdirectory(string)
add_subdirectory(__support)

View File

@ -0,0 +1,19 @@
add_entrypoint_object(
__errno_location
SRCS
errno_location.cpp
HDRS
llvmlibc_errno.h
)
add_custom_target(libc_errno_unittests)
add_libc_unittest(
errno_test
SUITE
libc_errno_unittests
SRCS
errno_test.cpp
DEPENDS
__errno_location
)

View File

@ -0,0 +1,22 @@
//===----------------- Implementation of __errno_location -----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "src/errno/llvmlibc_errno.h"
#include "src/__support/common.h"
namespace __llvm_libc {
static thread_local int __errno = 0;
// __errno_location is not really an entry point but we still want it to behave
// like an entry point because the errno macro resolves to the C symbol
// "__errno_location".
int *LLVM_LIBC_ENTRYPOINT(__errno_location)() { return &__errno; }
} // namespace __llvm_libc

View File

@ -0,0 +1,17 @@
//===---------------------- Unittests for errno --------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "src/errno/llvmlibc_errno.h"
#include "gtest/gtest.h"
TEST(ErrnoTest, Basic) {
int test_val = 123;
llvmlibc_errno = test_val;
ASSERT_EQ(test_val, llvmlibc_errno);
}

View File

@ -0,0 +1,22 @@
//===------------------ Implementation header for errno -------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC_ERRNO_LLVMLIBC_ERRNO_H
#define LLVM_LIBC_SRC_ERRNO_LLVMLIBC_ERRNO_H
// Internal code should use this and not use the errno macro from the
// public header.
#define llvmlibc_errno (*__llvm_libc::__errno_location())
namespace __llvm_libc {
int *__errno_location();
} // namespace __llvm_libc
#endif // LLVM_LIBC_SRC_ERRNO_LLVMLIBC_ERRNO_H