[libc] Implement htonl and htons

Per spec:
* https://pubs.opengroup.org/onlinepubs/9699919799/functions/htonl.html
* https://pubs.opengroup.org/onlinepubs/9699919799/functions/htons.html

Also adds UInt16Type and UInt32Type to spec.td

Co-authored-by: Jeff Bailey <jbailey@google.com>

Reviewed By: sivachandra, jeffbailey, rtenneti

Differential Revision: https://reviews.llvm.org/D143795
This commit is contained in:
Raman Tenneti 2023-02-16 09:56:36 -08:00
parent 35742743d2
commit fbe210dc7a
17 changed files with 232 additions and 0 deletions

View File

@ -318,6 +318,10 @@ set(TARGET_LIBM_ENTRYPOINTS
if(LLVM_LIBC_FULL_BUILD)
list(APPEND TARGET_LIBC_ENTRYPOINTS
# network.h entrypoints
libc.src.network.htonl
libc.src.network.htons
# pthread.h entrypoints
libc.src.pthread.pthread_atfork
libc.src.pthread.pthread_attr_destroy

View File

@ -331,6 +331,10 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.dirent.opendir
libc.src.dirent.readdir
# network.h entrypoints
libc.src.network.htonl
libc.src.network.htons
# pthread.h entrypoints
libc.src.pthread.pthread_atfork
libc.src.pthread.pthread_attr_destroy

View File

@ -20,6 +20,8 @@ set(TARGET_PUBLIC_HEADERS
libc.include.time
libc.include.unistd
libc.include.arpa_inet
libc.include.sys_auxv
libc.include.sys_ioctl
libc.include.sys_mman

View File

@ -68,6 +68,17 @@ add_gen_header(
.llvm-libc-types.float_t
)
# TODO: This should be conditional on POSIX networking being included.
file(MAKE_DIRECTORY "arpa")
add_gen_header(
arpa_inet
DEF_FILE arpa/inet.h.def
GEN_HDR arpa/inet.h
DEPENDS
.llvm_libc_common_h
)
add_gen_header(
assert
DEF_FILE assert.h.def

View File

@ -0,0 +1,18 @@
//===-- C standard library header network.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_ARPA_INET_H
#define LLVM_LIBC_ARPA_INET_H
#include <__llvm-libc-common.h>
#include <inttypes.h>
%%public_api()
#endif // LLVM_LIBC_ARPA_INET_H

View File

@ -798,6 +798,25 @@ def POSIX : StandardSpec<"POSIX"> {
]
>;
HeaderSpec ArpaInet = HeaderSpec<
"arpa/inet.h",
[], // Macros
[], // Types
[], // Enumerations
[
FunctionSpec<
"htonl",
RetValSpec<UInt32Type>,
[ArgSpec<UInt32Type>]
>,
FunctionSpec<
"htons",
RetValSpec<UInt16Type>,
[ArgSpec<UInt16Type>]
>,
]
>;
HeaderSpec PThread = HeaderSpec<
"pthread.h",
[], // Macros
@ -1260,6 +1279,7 @@ def POSIX : StandardSpec<"POSIX"> {
>;
let Headers = [
ArpaInet,
CType,
Dirent,
Errno,

View File

@ -64,6 +64,9 @@ def LongDoublePtr : PtrType<LongDoubleType>;
def IntMaxTType : NamedType<"intmax_t">;
def UIntMaxTType : NamedType<"uintmax_t">;
def UInt16Type : NamedType<"uint16_t">;
def UInt32Type : NamedType<"uint32_t">;
def OffTType : NamedType<"off_t">;
def OffTPtr : PtrType<OffTType>;
def SSizeTType : NamedType<"ssize_t">;

View File

@ -24,6 +24,7 @@ if(NOT LLVM_LIBC_FULL_BUILD)
endif()
add_subdirectory(assert)
add_subdirectory(network)
add_subdirectory(setjmp)
add_subdirectory(signal)
add_subdirectory(spawn)

View File

@ -0,0 +1,21 @@
add_entrypoint_object(
htonl
SRCS
htonl.cpp
HDRS
htonl.h
DEPENDS
libc.include.arpa_inet
libc.src.__support.common
)
add_entrypoint_object(
htons
SRCS
htons.cpp
HDRS
htons.h
DEPENDS
libc.include.arpa_inet
libc.src.__support.common
)

View File

@ -0,0 +1,19 @@
//===-- Implementation of htonl function ----------------------------------===//
//
// 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/network/htonl.h"
#include "src/__support/common.h"
#include "src/__support/endian.h"
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(uint32_t, htonl, (uint32_t hostlong)) {
return Endian::to_big_endian(hostlong);
}
} // namespace __llvm_libc

20
libc/src/network/htonl.h Normal file
View File

@ -0,0 +1,20 @@
//===-- Implementation header of htonl --------------------------*- C++ -*-===//
//
// 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_NETWORK_HTONL_H
#define LLVM_LIBC_SRC_NETWORK_HTONL_H
#include <stdint.h>
namespace __llvm_libc {
uint32_t htonl(uint32_t hostlong);
} // namespace __llvm_libc
#endif // LLVM_LIBC_SRC_NETWORK_HTONL_H

View File

@ -0,0 +1,19 @@
//===-- Implementation of htons function ----------------------------------===//
//
// 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/network/htons.h"
#include "src/__support/common.h"
#include "src/__support/endian.h"
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(uint16_t, htons, (uint16_t hostshort)) {
return Endian::to_big_endian(hostshort);
}
} // namespace __llvm_libc

20
libc/src/network/htons.h Normal file
View File

@ -0,0 +1,20 @@
//===-- Implementation header of htons --------------------------*- C++ -*-===//
//
// 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_NETWORK_HTONS_H
#define LLVM_LIBC_SRC_NETWORK_HTONS_H
#include <stdint.h>
namespace __llvm_libc {
uint16_t htons(uint16_t hostlong);
} // namespace __llvm_libc
#endif // LLVM_LIBC_SRC_NETWORK_HTONS_H

View File

@ -50,6 +50,7 @@ endif()
add_subdirectory(dirent)
add_subdirectory(assert)
add_subdirectory(network)
add_subdirectory(setjmp)
add_subdirectory(signal)
add_subdirectory(spawn)

View File

@ -0,0 +1,25 @@
add_libc_testsuite(libc_network_unittests)
add_libc_unittest(
htonl
SUITE
libc_network_unittests
SRCS
htonl_test.cpp
CXX_STANDARD
20
DEPENDS
libc.src.network.htonl
)
add_libc_unittest(
htons
SUITE
libc_network_unittests
SRCS
htons_test.cpp
CXX_STANDARD
20
DEPENDS
libc.src.network.htons
)

View File

@ -0,0 +1,22 @@
//===-- Unittests for htonl -----------------------------------------------===//
//
// 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/__support/endian.h"
#include "src/network/htonl.h"
#include "test/UnitTest/Test.h"
TEST(LlvmLibcHtonl, SmokeTest) {
uint32_t original = 0x67452301;
uint32_t swapped = 0x01234567;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
EXPECT_EQ(__llvm_libc::htonl(original), swapped);
#endif
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
EXPECT_EQ(__llvm_libc::htonl(original), original);
#endif
}

View File

@ -0,0 +1,22 @@
//===-- Unittests for htons -----------------------------------------------===//
//
// 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/__support/endian.h"
#include "src/network/htons.h"
#include "test/UnitTest/Test.h"
TEST(LlvmLibcHtons, SmokeTest) {
uint16_t original = 0x2301;
uint16_t swapped = 0x0123;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
EXPECT_EQ(__llvm_libc::htons(original), swapped);
#endif
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
EXPECT_EQ(__llvm_libc::htons(original), original);
#endif
}