[libc-commits] [libc] fbe210d - [libc] Implement htonl and htons

Raman Tenneti via libc-commits libc-commits at lists.llvm.org
Thu Feb 16 10:12:24 PST 2023


Author: Raman Tenneti
Date: 2023-02-16T10:12:18-08:00
New Revision: fbe210dc7a6ad87a30e5ffe928a168e621f6fcc5

URL: https://github.com/llvm/llvm-project/commit/fbe210dc7a6ad87a30e5ffe928a168e621f6fcc5
DIFF: https://github.com/llvm/llvm-project/commit/fbe210dc7a6ad87a30e5ffe928a168e621f6fcc5.diff

LOG: [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 at google.com>

Reviewed By: sivachandra, jeffbailey, rtenneti

Differential Revision: https://reviews.llvm.org/D143795

Added: 
    libc/include/arpa/inet.h.def
    libc/src/network/CMakeLists.txt
    libc/src/network/htonl.cpp
    libc/src/network/htonl.h
    libc/src/network/htons.cpp
    libc/src/network/htons.h
    libc/test/src/network/CMakeLists.txt
    libc/test/src/network/htonl_test.cpp
    libc/test/src/network/htons_test.cpp

Modified: 
    libc/config/linux/aarch64/entrypoints.txt
    libc/config/linux/x86_64/entrypoints.txt
    libc/config/linux/x86_64/headers.txt
    libc/include/CMakeLists.txt
    libc/spec/posix.td
    libc/spec/spec.td
    libc/src/CMakeLists.txt
    libc/test/src/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index e2826effc29ab..82de499789577 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -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

diff  --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index e4fe2467b75bb..6d5aba734c709 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -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

diff  --git a/libc/config/linux/x86_64/headers.txt b/libc/config/linux/x86_64/headers.txt
index 3ec9d6a43a05f..e9437665675b8 100644
--- a/libc/config/linux/x86_64/headers.txt
+++ b/libc/config/linux/x86_64/headers.txt
@@ -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

diff  --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index df61a5599567e..aca05c64280fc 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -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

diff  --git a/libc/include/arpa/inet.h.def b/libc/include/arpa/inet.h.def
new file mode 100644
index 0000000000000..fdd5ae3e3f85a
--- /dev/null
+++ b/libc/include/arpa/inet.h.def
@@ -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

diff  --git a/libc/spec/posix.td b/libc/spec/posix.td
index 43cc031953b65..a7e50ca107f2f 100644
--- a/libc/spec/posix.td
+++ b/libc/spec/posix.td
@@ -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,

diff  --git a/libc/spec/spec.td b/libc/spec/spec.td
index 017056d7d7738..87bafb087d3fb 100644
--- a/libc/spec/spec.td
+++ b/libc/spec/spec.td
@@ -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">;

diff  --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt
index 32d557ad71576..59e7d06871787 100644
--- a/libc/src/CMakeLists.txt
+++ b/libc/src/CMakeLists.txt
@@ -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)

diff  --git a/libc/src/network/CMakeLists.txt b/libc/src/network/CMakeLists.txt
new file mode 100644
index 0000000000000..ea5101ecbaa9b
--- /dev/null
+++ b/libc/src/network/CMakeLists.txt
@@ -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
+)

diff  --git a/libc/src/network/htonl.cpp b/libc/src/network/htonl.cpp
new file mode 100644
index 0000000000000..983fcadd7dae3
--- /dev/null
+++ b/libc/src/network/htonl.cpp
@@ -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

diff  --git a/libc/src/network/htonl.h b/libc/src/network/htonl.h
new file mode 100644
index 0000000000000..eab56482150e4
--- /dev/null
+++ b/libc/src/network/htonl.h
@@ -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

diff  --git a/libc/src/network/htons.cpp b/libc/src/network/htons.cpp
new file mode 100644
index 0000000000000..1d2c6bf2f8836
--- /dev/null
+++ b/libc/src/network/htons.cpp
@@ -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

diff  --git a/libc/src/network/htons.h b/libc/src/network/htons.h
new file mode 100644
index 0000000000000..7b61006ffb113
--- /dev/null
+++ b/libc/src/network/htons.h
@@ -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

diff  --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt
index 1ae18860f396e..bf992ce2a8c25 100644
--- a/libc/test/src/CMakeLists.txt
+++ b/libc/test/src/CMakeLists.txt
@@ -50,6 +50,7 @@ endif()
 
 add_subdirectory(dirent)
 add_subdirectory(assert)
+add_subdirectory(network)
 add_subdirectory(setjmp)
 add_subdirectory(signal)
 add_subdirectory(spawn)

diff  --git a/libc/test/src/network/CMakeLists.txt b/libc/test/src/network/CMakeLists.txt
new file mode 100644
index 0000000000000..ed75dc4e77d72
--- /dev/null
+++ b/libc/test/src/network/CMakeLists.txt
@@ -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
+)

diff  --git a/libc/test/src/network/htonl_test.cpp b/libc/test/src/network/htonl_test.cpp
new file mode 100644
index 0000000000000..66ffc8b17232d
--- /dev/null
+++ b/libc/test/src/network/htonl_test.cpp
@@ -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
+}

diff  --git a/libc/test/src/network/htons_test.cpp b/libc/test/src/network/htons_test.cpp
new file mode 100644
index 0000000000000..786f488c98a29
--- /dev/null
+++ b/libc/test/src/network/htons_test.cpp
@@ -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
+}


        


More information about the libc-commits mailing list