Skip to content

Commit

Permalink
[libc][docs] Update implementation docs (#73590)
Browse files Browse the repository at this point in the history
Some of the files in the docs/ directory are from 2019 and haven't been
updated since. This patch updates implementation_standard.rst,
source_tree_layout.rst, and has some minor fixes for strings.rst. It
also marks the most severely out of date files with a warning. These
files will be updated in a later patch.
  • Loading branch information
michaelrj-google committed Nov 28, 2023
1 parent 6c62f7c commit 43f783f
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 73 deletions.
5 changes: 5 additions & 0 deletions libc/docs/dev/api_test.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
========
API Test
========

.. warning::
This page is severely out of date. Much of the information it contains may be
incorrect. Please only remove this warning once the page has been updated.

The implementation of libc-project is unique because our public C header files
are generated using information from ground truth captured in TableGen files.
Unit tests only exercise the internal C++ implementations and don't ensure the
Expand Down
6 changes: 6 additions & 0 deletions libc/docs/dev/clang_tidy_checks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

LLVM libc clang-tidy checks
===========================


.. warning::
This page is severely out of date. Much of the information it contains may be
incorrect. Please only remove this warning once the page has been updated.

These are the clang-tidy checks designed to help enforce implementation
standards.
The configuration file is ``src/.clang-tidy``.
Expand Down
4 changes: 4 additions & 0 deletions libc/docs/dev/header_generation.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Generating Public and Internal headers
======================================

.. warning::
This page is severely out of date. Much of the information it contains may be
incorrect. Please only remove this warning once the page has been updated.

Other libc implementations make use of preprocessor macro tricks to make header
files platform agnostic. When macros aren't suitable, they rely on build
system tricks to pick the right set of files to compile and export. While these
Expand Down
84 changes: 36 additions & 48 deletions libc/docs/dev/implementation_standard.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,81 +5,69 @@ LLVM-libc entrypoints are defined in the entrypoints document. In this document,
we explain how the entrypoints are implemented. The source layout document
explains that, within the high level ``src`` directory, there exists one
directory for every public header file provided by LLVM-libc. The
implementations of related group of entrypoints will also live in a directory of
their own. This directory will have a name indicative of the related group of
entrypoints, and will be under the directory corresponding to the header file of
the entrypoints. For example, functions like ``fopen`` and ``fclose`` cannot be
tested independent of each other and hence will live in a directory named
``src/stdio/file_operations``. On the other hand, the implementation of the
``round`` function from ``math.h`` can be tested by itself, so it will live in
the directory of its own named ``src/math/round/``.
implementations of entrypoints live in the directory for the header they belong
to. Some entrypoints are platform specific, and so their implementations are in
a subdirectory with the name of the platform (e.g. ``stdio/linux/remove.cpp``).

Implementation of entrypoints can span multiple ``.cpp`` and ``.h`` files, but
there will be at least one header file with name of the form
``<entrypoint name>.h`` for every entrypoint. This header file is called as the
implementation header file. For the ``round`` function, the path to the
implementation header file will be ``src/math/round/round.h``. The rest of this
document explains the structure of implementation header files and ``.cpp``
files.
``<entrypoint name>.h`` for every entrypoint. This header file is called the
implementation header file. For the ``isalpha`` function, the path to the
implementation header file is ``src/ctype/isalpha.h``.

Implementation Header File Structure
------------------------------------

We will use the ``round`` function from the public ``math.h`` header file as an
example. The ``round`` function will be declared in an internal header file
``src/math/round/round.h`` as follows::
We will use the ``isalpha`` function from the public ``ctype.h`` header file as an
example. The ``isalpha`` function will be declared in an internal header file
``src/ctype/isalpha.h`` as follows::

// --- round.h --- //
#ifndef LLVM_LIBC_SRC_MATH_ROUND_ROUND_H
#define LLVM_LIBC_SRC_MATH_ROUND_ROUND_H
// --- isalpha.h --- //
#ifndef LLVM_LIBC_SRC_CTYPE_ISALPHA_H
#define LLVM_LIBC_SRC_CTYPE_ISALPHA_H

namespace LIBC_NAMESPACE {

double round(double);
int isalpha(int c);

} // namespace LIBC_NAMESPACE

#endif LLVM_LIBC_SRC_MATH_ROUND_ROUND_H
#endif LLVM_LIBC_SRC_CTYPE_ISALPHA_H

Notice that the ``round`` function declaration is nested inside the namespace
``LIBC_NAMESPACE``. All implementation constructs in LLVM-libc are declared within
the namespace ``LIBC_NAMESPACE``.
Notice that the ``isalpha`` function declaration is nested inside the namespace
``LIBC_NAMESPACE``. All implementation constructs in LLVM-libc are declared
within the namespace ``LIBC_NAMESPACE``.

``.cpp`` File Structure
-----------------------

The implementation can span multiple ``.cpp`` files. However, the signature of
the entrypoint function should make use of a special macro. For example, the
``round`` function from ``math.h`` should be defined as follows, say in the file
``src/math/math/round.cpp``::
The main ``.cpp`` file is named ``<entrypoint name>.cpp`` and is usually in the
same folder as the header. It contains the signature of the entrypoint function,
which must be defined with the ``LLVM_LIBC_FUNCTION`` macro. For example, the
``isalpha`` function from ``ctype.h`` is defined as follows, in the file
``src/ctype/isalpha.cpp``::

// --- round.cpp --- //
// --- isalpha.cpp --- //

namespace LIBC_NAMESPACE {

double LLVM_LIBC_ENTRYPOINT(round)(double d) {
LLVM_LIBC_FUNCTION(int, isalpha, (int c)) {
// ... implementation goes here.
}

} // namespace LIBC_NAMESPACE

Notice the use of the macro ``LLVM_LIBC_ENTRYPOINT``. This macro helps us define
an C alias symbol for the C++ implementation. The C alias need not be added by
the macro by itself. For example, for ELF targets, the macro is defined as
follows::
Notice the use of the macro ``LLVM_LIBC_FUNCTION``. This macro helps us define
a C alias symbol for the C++ implementation. For example, for a library build,
the macro is defined as follows::

#define ENTRYPOINT_SECTION_ATTRIBUTE(name) \
__attribute__((section(".llvm.libc.entrypoint."#name)))
#define LLVM_LIBC_ENTRYPOINT(name) ENTRYPOINT_SECTION_ATTRIBUTE(name) name
#define LLVM_LIBC_FUNCTION(type, name, arglist)
LLVM_LIBC_FUNCTION_IMPL(type, name, arglist)
#define LLVM_LIBC_FUNCTION_IMPL(type, name, arglist)
LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name)
__##name##_impl__ __asm__(#name);
decltype(LIBC_NAMESPACE::name) name [[gnu::alias(#name)]];
type __##name##_impl__ arglist

The macro places the C++ function in a unique section with name
``.llvm.libc.entrypoint.<function name>``. This allows us to add a C alias using
a post build step. For example, for the ``round`` function, one can use
``objcopy`` to add an alias symbol as follows::

objcopy --add-symbol round=.llvm.libc.entrypoint.round:0,function round.o

NOTE: We use a post build ``objcopy`` step to add an alias instead of using
the ``__attribute__((alias))``. For C++, this ``alias`` attribute requires
mangled names of the referees. Using the post build ``objcopy`` step helps
us avoid putting mangled names with ``alias`` attributes.
The LLVM_LIBC_FUNCTION_ATTR macro is normally defined to nothing, but can be
defined by vendors who want to set their own attributes.
68 changes: 49 additions & 19 deletions libc/docs/dev/source_tree_layout.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,39 @@ At the top-level, LLVM-libc source tree is organized in to the following
directories::

+ libc
- benchmarks
- cmake
- config
- docs
- examples
- fuzzing
- include
- lib
- startup
- spec
- src
- startup
- test
- utils

Each of these directories is explained in detail below.
Each of these directories is explained breifly below.

The ``benchmarks`` directory
----------------------------

The ``benchmarks`` directory contains LLVM-libc's benchmarking utilities. These
are mostly used for the memory functions. This also includes the automemcpy
subdirectory for automatic generation of optimized memory functions.

The ``config`` directory
------------------------

The ``config`` directory contains the default configurations for the targets
LLVM-libc supports. These are files in the ``config/<platform>/<architecture>/``
subdirectory called ``entrypoints.txt``, ``exclude.txt``, ``headers.txt``, and
``config.json``. These tell cmake which entrypoints are available, which
entrypoints to exclude, which headers to generate, and what options to set for
the current target respectively. There are also other platform specific files in
the ``config/<platform>/`` subdirectory.

The ``cmake`` directory
-----------------------
Expand All @@ -35,34 +57,36 @@ this document on source layout.
The ``fuzzing`` directory
-------------------------

This directory contains fuzzing tests for the various components of llvm-libc. The
directory structure within this directory mirrors the directory structure of the
top-level ``libc`` directory itself. For more details, see :doc:`fuzzing`.
This directory contains fuzzing tests for the various components of LLVM-libc.
The directory structure within this directory mirrors the directory structure
of the top-level ``libc`` directory itself. For more details, see
:doc:`fuzzing`.

The ``include`` directory
-------------------------

The ``include`` directory contains:

1. Self contained public header files - These are header files which are
already in the form that get installed when LLVM-libc is installed on a user's
computer.
2. ``*.h.def`` and ``*.h.in`` files - These files are used to construct the
generated public header files.
3. A ``CMakeLists.txt`` file - This file lists the targets for the self
contained and generated public header files.
1. ``*.h.def`` files - These files are used to construct the generated public
header files.
2. Self contained public header files - These are header files which are
already in the form that get installed when LLVM-libc is installed on a
user's computer. These are mostly in the ``llvm-libc-macros`` and
``llvm-libc-types`` subdirectories.

The ``lib`` directory
---------------------

This directory contains a ``CMakeLists.txt`` file listing the targets for the
public libraries ``libc.a``, ``libm.a`` etc.

The ``startup`` directory
-------------------------
The ``spec`` directory
----------------------

This directory contains the implementations of the application startup objects
like ``crt1.o`` etc.
This directory contains the specifications for the types, macros, and entrypoint
functions. These definitions come from the various standards and extensions
LLVM-libc supports, and they are used along with the ``*.h.def`` files and the
config files to generate the headers for fullbuild mode.

The ``src`` directory
---------------------
Expand All @@ -78,10 +102,16 @@ further organized as follows:
implementation standard document explains more about the *header*
directories.

The ``startup`` directory
-------------------------

This directory contains the implementations of the application startup objects
like ``crt1.o`` etc.

The ``test`` directory
----------------------

This directory contains tests for the various components of llvm-libc. The
This directory contains tests for the various components of LLVM-libc. The
directory structure within this directory mirrors the directory structure of the
toplevel ``libc`` directory itself. A test for, say the ``mmap`` function, lives
in the directory ``test/src/sys/mman/`` as implementation of ``mmap`` lives in
Expand All @@ -90,6 +120,6 @@ in the directory ``test/src/sys/mman/`` as implementation of ``mmap`` lives in
The ``utils`` directory
-----------------------

This directory contains utilities used by other parts of the llvm-libc system.
See the `README` files, in the sub-directories within this directory, to learn
This directory contains utilities used by other parts of the LLVM-libc system.
See the `README` files in the subdirectories within this directory to learn
about the various utilities.
11 changes: 5 additions & 6 deletions libc/docs/strings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -135,22 +135,21 @@ String Error Functions
============= =========
Function Name Available
============= =========
strerror
strerror_s
strerrorlen_s
strerror |check|
strerror_r |check|
============= =========

Localized String Functions
==========================

These functions require locale.h, and will be added when locale support is
These functions require locale.h, and will be finished when locale support is
implemented in LLVM-libc.

============= =========
Function Name Available
============= =========
strcoll
strxfrm
strcoll Partially
strxfrm Partially
============= =========

---------------------------
Expand Down

0 comments on commit 43f783f

Please sign in to comment.