2019-10-16 04:25:36 +08:00
|
|
|
Redirectors
|
|
|
|
===========
|
|
|
|
|
|
|
|
When implementing a new C standard library (referred to as *libc* henceforth in
|
|
|
|
this document) starting from scratch, it is unrealistic to expect that we will
|
|
|
|
have the entire library available from day one. In such a scenario, a practical
|
|
|
|
approach is to redirect calls to the unimplemented functions to the same
|
|
|
|
functions from another fully functional libc implementation. Such a scheme can
|
|
|
|
also serve users who would like to mix and match implementations from LLVM libc
|
|
|
|
and another libc implementation. On most platforms, this other libc can be the
|
|
|
|
system libc itself. In this document, we present a strategy one can employ to
|
|
|
|
build redirectors to redirect from LLVM libc to the system libc. For now, the
|
|
|
|
scheme presented is limited to ELF platforms.
|
|
|
|
|
|
|
|
Highlevel Mechanism
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
The highlevel scheme is as below:
|
|
|
|
|
|
|
|
<img src="./redirectors_schematic.svg">
|
|
|
|
|
|
|
|
As shown in the diagram, the mechanism involves a redirector dynamic library
|
|
|
|
which goes in between the llvm-libc static library and the system libc dynamic
|
|
|
|
library. Essentially, LLVM libc provides implementations for all public
|
|
|
|
functions. However, some of the implementations do not actually implement the
|
|
|
|
expected functionality. Instead, they just call the corresponding function in
|
|
|
|
the redirector library, which in turn calls the same function from the system
|
|
|
|
libc.
|
|
|
|
|
|
|
|
Implementation of redirecting entrypoints
|
|
|
|
-----------------------------------------
|
|
|
|
|
|
|
|
Let us take the ``round`` function from ``math.h`` as an example to see what
|
|
|
|
it's implementation looks like when it just redirects to the ``round`` function
|
2022-01-29 08:27:34 +08:00
|
|
|
from the system libc::
|
2019-10-16 04:25:36 +08:00
|
|
|
|
|
|
|
namespace llvm_libc {
|
|
|
|
|
|
|
|
double __redirected_round(double);
|
|
|
|
|
|
|
|
double LLVM_LIBC_ENTRYPOINT(round)(double x) {
|
|
|
|
return __redirected_round(x);
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace llvm_libc
|
|
|
|
|
|
|
|
As can be seen, the ``round`` function from LLVM libc does not call the
|
|
|
|
``round`` function from the system libc directly. It calls a function
|
|
|
|
``__redirected_round`` from the redirector library. The rest of the
|
|
|
|
code follows the conventions described in the *implementation standard*
|
|
|
|
document.
|
|
|
|
|
|
|
|
Implementation of the redirector function
|
|
|
|
-----------------------------------------
|
|
|
|
|
|
|
|
The function ``__redirected_round`` calls the ``round`` function from the system
|
|
|
|
libc. Its implementation is as follows::
|
|
|
|
|
|
|
|
#include <math.h> // Header file from the system libc
|
|
|
|
|
|
|
|
namespace llvm_libc {
|
|
|
|
|
|
|
|
double __redirected_round(double x) {
|
|
|
|
return ::round(x); // Call to round from the system libc
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace llvm_libc
|
|
|
|
|