forked from OSchip/llvm-project
86 lines
3.6 KiB
ReStructuredText
86 lines
3.6 KiB
ReStructuredText
Convention for implementing entrypoints
|
|
=======================================
|
|
|
|
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/``.
|
|
|
|
Implementation of entrypoints can span multiple ``.cpp`` and ``.h`` files, but
|
|
there will be atleast 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.
|
|
|
|
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::
|
|
|
|
// --- round.h --- //
|
|
#ifndef LLVM_LIBC_SRC_MATH_ROUND_ROUND_H
|
|
#define LLVM_LIBC_SRC_MATH_ROUND_ROUND_H
|
|
|
|
namespace __llvm_libc {
|
|
|
|
double round(double);
|
|
|
|
} // namespace __llvm_libc
|
|
|
|
#endif LLVM_LIBC_SRC_MATH_ROUND_ROUND_H
|
|
|
|
Notice that the ``round`` function declaration is nested inside the namespace
|
|
``__llvm_libc``. All implementation constructs in LLVM-libc are declared within
|
|
the namespace ``__llvm_libc``.
|
|
|
|
``.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``::
|
|
|
|
// --- round.cpp --- //
|
|
|
|
namespace __llvm_libc {
|
|
|
|
double LLVM_LIBC_ENTRYPOINT(round)(double d) {
|
|
// ... implementation goes here.
|
|
}
|
|
|
|
} // namespace __llvm_libc
|
|
|
|
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::
|
|
|
|
#define ENTRYPOINT_SECTION_ATTRIBUTE(name) \
|
|
__attribute__((section(".llvm.libc.entrypoint."#name)))
|
|
#define LLVM_LIBC_ENTRYPOINT(name) ENTRYPOINT_SECTION_ATTRIBUTE(name) name
|
|
|
|
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.
|