Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions libc/config/linux/aarch64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1116,6 +1116,12 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.search.lfind
libc.src.search.lsearch
libc.src.search.remque
libc.src.search.tdelete
libc.src.search.tdestroy
libc.src.search.tfind
libc.src.search.tsearch
libc.src.search.twalk
libc.src.search.twalk_r

# threads.h entrypoints
libc.src.threads.call_once
Expand Down
6 changes: 6 additions & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1298,6 +1298,12 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.search.lfind
libc.src.search.lsearch
libc.src.search.remque
libc.src.search.tdelete
libc.src.search.tdestroy
libc.src.search.tfind
libc.src.search.tsearch
libc.src.search.twalk
libc.src.search.twalk_r

# threads.h entrypoints
libc.src.threads.call_once
Expand Down
8 changes: 8 additions & 0 deletions libc/fuzzing/__support/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ add_libc_fuzzer(
-D__LIBC_EXPLICIT_SIMD_OPT
)

add_libc_fuzzer(
weak_avl_fuzz
SRCS
weak_avl_fuzz.cpp
DEPENDS
libc.src.__support.weak_avl
)

# TODO: FreeListHeap uses the _end symbol which conflicts with the _end symbol
# defined by GPU start.cpp files so for now we exclude this fuzzer on GPU.
if(LLVM_LIBC_FULL_BUILD AND NOT LIBC_TARGET_OS_IS_GPU)
Expand Down
94 changes: 94 additions & 0 deletions libc/fuzzing/__support/weak_avl_fuzz.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
//===-- weak_avl_fuzz.cpp -------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// Fuzzing test for llvm-libc weak AVL implementations.
///
//===----------------------------------------------------------------------===//
#include "hdr/types/ENTRY.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/macros/config.h"
#include "src/__support/weak_avl.h"

namespace LIBC_NAMESPACE_DECL {

// A sequence of actions:
// - Erase: a single byte valued (5, 6 mod 7) followed by an int
// - Find: a single byte valued (4 mod 7) followed by an int
// - FindOrInsert: a single byte valued (0,1,2,3 mod 7) followed by an int
extern "C" size_t LLVMFuzzerMutate(uint8_t *data, size_t size, size_t max_size);
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *data, size_t size,
size_t max_size, unsigned int seed) {
size = LLVMFuzzerMutate(data, size, max_size);
return size / (1 + sizeof(int)) * (1 + sizeof(int));
}

class AVLTree {
using Node = WeakAVLNode<int>;
Node *root = nullptr;
bool reversed = false;
static int compare(int a, int b) { return (a > b) - (a < b); }
static int reverse_compare(int a, int b) { return (b > a) - (b < a); }

public:
AVLTree(bool reversed = false) : reversed(reversed) {}
bool find(int key) {
return Node::find(root, key, reversed ? reverse_compare : compare);
}
bool find_or_insert(int key) {
return Node::find_or_insert(root, key,
reversed ? reverse_compare : compare);
}
bool erase(int key) {
Node *node = Node::find(root, key, reversed ? reverse_compare : compare);
if (node)
Node::erase(root, node);
return node;
}
~AVLTree() { Node::destroy(root); }
};

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
AVLTree tree1;
AVLTree tree2(true);
for (size_t i = 0; i + (1 + sizeof(int)) <= size; i += 1 + sizeof(int)) {
uint8_t action = data[i];
int key;
__builtin_memcpy(&key, data + i + 1, sizeof(int));
if (action % 7 == 4) {
// Find
bool res1 = tree1.find(key);
bool res2 = tree2.find(key);
if (res1 != res2)
__builtin_trap();

} else if (action % 7 == 5 || action % 7 == 6) {
// Erase
bool res1 = tree1.erase(key);
bool res2 = tree2.erase(key);
if (res1 != res2)
__builtin_trap();
if (tree1.find(key))
__builtin_trap();
if (tree2.find(key))
__builtin_trap();
} else {
// FindOrInsert
bool res1 = tree1.find_or_insert(key);
bool res2 = tree2.find_or_insert(key);
if (res1 != res2)
__builtin_trap();
if (!tree1.find(key))
__builtin_trap();
if (!tree2.find(key))
__builtin_trap();
}
}
return 0;
}

} // namespace LIBC_NAMESPACE_DECL
18 changes: 18 additions & 0 deletions libc/hdr/types/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -487,3 +487,21 @@ add_proxy_header_library(
FULL_BUILD_DEPENDS
libc.include.llvm-libc-types.gid_t
)

add_proxy_header_library(
posix_tnode
HDRS
posix_tnode.h
FULL_BUILD_DEPENDS
libc.include.llvm-libc-types.posix_tnode
libc.include.search
)

add_proxy_header_library(
VISIT
HDRS
VISIT.h
FULL_BUILD_DEPENDS
libc.include.llvm-libc-types.VISIT
libc.include.search
)
22 changes: 22 additions & 0 deletions libc/hdr/types/VISIT.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//===-- Definition of macros from VISIT -----------------------------------===//
//
// 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_HDR_TYPES_VISIT_H
#define LLVM_LIBC_HDR_TYPES_VISIT_H

#ifdef LIBC_FULL_BUILD

#include "include/llvm-libc-types/VISIT.h"

#else // Overlay mode

#include <search.h>

#endif // LLVM_LIBC_FULL_BUILD

#endif // LLVM_LIBC_HDR_TYPES_VISIT_H
28 changes: 28 additions & 0 deletions libc/hdr/types/posix_tnode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//===-- Definition of macros from posix_tnode -----------------------------===//
//
// 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_HDR_TYPES_POSIX_TNODE_H
#define LLVM_LIBC_HDR_TYPES_POSIX_TNODE_H

// posix_tnode is introduced in POSIX.1-2024.
// this may result in problems when overlaying on older systems.
// internal code should use __llvm_libc_tnode.

#ifdef LIBC_FULL_BUILD

#include "include/llvm-libc-types/posix_tnode.h"
#define __llvm_libc_tnode posix_tnode

#else // Overlay mode

#include <search.h>
typedef void __llvm_libc_tnode;

#endif // LLVM_LIBC_FULL_BUILD

#endif // LLVM_LIBC_HDR_TYPES_POSIX_TNODE_H
4 changes: 4 additions & 0 deletions libc/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,13 @@ add_header_macro(
.llvm-libc-types.ACTION
.llvm-libc-types.ENTRY
.llvm-libc-types.VISIT
.llvm-libc-types.posix_tnode
.llvm-libc-types.__search_compare_t
.llvm-libc-types.size_t
.llvm-libc-types.struct_hsearch_data
.llvm-libc-types.__action_closure_fn_t
.llvm-libc-types.__action_fn_t
.llvm-libc-types.__free_fn_t
.llvm_libc_common_h
)

Expand Down
16 changes: 16 additions & 0 deletions libc/include/llvm-libc-types/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ add_header(off_t HDR off_t.h)
add_header(once_flag HDR once_flag.h DEPENDS .__futex_word)
add_header(posix_spawn_file_actions_t HDR posix_spawn_file_actions_t.h)
add_header(posix_spawnattr_t HDR posix_spawnattr_t.h)
add_header(posix_tnode HDR posix_tnode.h)
add_header(pthread_attr_t HDR pthread_attr_t.h DEPENDS .size_t)
add_header(pthread_condattr_t HDR pthread_condattr_t.h DEPENDS .clockid_t)
add_header(pthread_key_t HDR pthread_key_t.h)
Expand Down Expand Up @@ -310,3 +311,18 @@ add_header(EFI_SYSTEM_TABLE
.EFI_TABLE_HEADER
.char16_t
)
add_header(__action_closure_fn_t
HDR
__action_closure_fn_t.h
DEPENDS
.posix_tnode
.VISIT
)
add_header(__action_fn_t
HDR
__action_fn_t.h
DEPENDS
.posix_tnode
.VISIT
)
add_header(__free_fn_t HDR __free_fn_t.h)
17 changes: 17 additions & 0 deletions libc/include/llvm-libc-types/__action_closure_fn_t.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//===-- Definition of type __action_closure_fn_t --------------------------===//
//
// 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_TYPES___ACTION_CLOSURE_FN_T_H
#define LLVM_LIBC_TYPES___ACTION_CLOSURE_FN_T_H

#include "VISIT.h"
#include "posix_tnode.h"

typedef void (*__action_closure_fn_t)(const posix_tnode *, VISIT, void *);

#endif // LLVM_LIBC_TYPES___ACTION_CLOSURE_FN_T_H
17 changes: 17 additions & 0 deletions libc/include/llvm-libc-types/__action_fn_t.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//===-- Definition of type __action_fn_t ----------------------------------===//
//
// 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_TYPES___ACTION_FN_T_H
#define LLVM_LIBC_TYPES___ACTION_FN_T_H

#include "VISIT.h"
#include "posix_tnode.h"

typedef void (*__action_fn_t)(const posix_tnode *, VISIT, int);

#endif // LLVM_LIBC_TYPES___ACTION_FN_T_H
14 changes: 14 additions & 0 deletions libc/include/llvm-libc-types/__free_fn_t.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//===-- Definition of type __free_fn_t ------------------------------------===//
//
// 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_TYPES___FREE_FN_T_H
#define LLVM_LIBC_TYPES___FREE_FN_T_H

typedef void (*__free_fn_t)(void *);

#endif // LLVM_LIBC_TYPES___FREE_FN_T_H
17 changes: 17 additions & 0 deletions libc/include/llvm-libc-types/posix_tnode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//===-- Definition of type posix_tnode--------------- ---------------------===//
//
// 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_TYPES_POSIX_TNODE_H
#define LLVM_LIBC_TYPES_POSIX_TNODE_H

// Following POSIX.1-2024 and Austin Group Defect Report 1011:
// https://austingroupbugs.net/view.php?id=1011
// Define posix_tnode as void to provide both type safety and compatibility.
typedef void posix_tnode;

#endif // LLVM_LIBC_TYPES_POSIX_TNODE_H
48 changes: 48 additions & 0 deletions libc/include/search.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ types:
- type_name: VISIT
- type_name: __search_compare_t
- type_name: struct_hsearch_data
- type_name: posix_tnode
- type_name: __action_closure_fn_t
- type_name: __action_fn_t
- type_name: __free_fn_t
enums: []
objects: []
functions:
Expand Down Expand Up @@ -80,3 +84,47 @@ functions:
- type: size_t *
- type: size_t
- type: __search_compare_t
- name: tdelete
standards:
- posix
return_type: void *
arguments:
- type: const void *__restrict
- type: posix_tnode **__restrict
- type: __search_compare_t
- name: tfind
standards:
- posix
return_type: posix_tnode *
arguments:
- type: const void *
- type: posix_tnode * const *
- type: __search_compare_t
- name: tsearch
standards:
- posix
return_type: posix_tnode *
arguments:
- type: const void *
- type: posix_tnode **
- type: __search_compare_t
- name: twalk
standards:
- posix
return_type: void
arguments:
- type: const posix_tnode *
- type: __action_fn_t
- name: twalk_r
standards: gnu
return_type: void
arguments:
- type: const posix_tnode *
- type: __action_closure_fn_t
- type: void *
- name: tdestroy
standards: gnu
return_type: void
arguments:
- type: posix_tnode *
- type: __free_fn_t
14 changes: 14 additions & 0 deletions libc/src/__support/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,20 @@ add_header_library(
libc.src.__support.macros.attributes
)

add_header_library(
weak_avl
HDRS
weak_avl.h
DEPENDS
libc.hdr.stdint_proxy
libc.src.__support.CPP.bit
libc.src.__support.CPP.new
libc.src.__support.CPP.utility
libc.src.__support.libc_assert
libc.src.__support.macros.attributes
libc.src.__support.macros.config
)

add_subdirectory(FPUtil)
add_subdirectory(OSUtil)
add_subdirectory(StringUtil)
Expand Down
Loading
Loading