|
|
|
|
|
by retrac
1680 days ago
|
|
ABI is not quite the same as API. While an ABI is an API not all APIs are ABIs. Binary interface vs. programming interface. An ABI is a precise low-level machine definition, bit level, of the register values, etc. to invoking the library functions. call function at 0x32918333 with 0xabcdef12. C++ has gotten terribly crufty in that regard. In practice there's no guarantee that if you link together something from multiple compilers with different flags, that it'll work. ABI incompatibilities and flaws. Though if you recompile it all from scratch you're fine -- it's all the same API. Stuff like "break the ABI to save C++" means recognize the above truth, and sweep the current stuff away and reach a consensus on an actual stable ABI we can live with. |
|
So then we have 2 APIs. That is, we have the C standard library (as an API) and the POSIX API. The POSIX API defines the syscalls such as write, read, open, ... The C or C++ standard library provide the header files (function declarations etc.) and its .so file (the shared library) is in the memory. Take the Microsoft C++ Compiler as an example. I cannot see how the standard library is implemented, because only the headers are defined and the actual compiled code "lives" as a .so file in memory. This .so file as an object in memory is accessible to all C/C++ applications. The .so file is essentially C's runtime environment (RTE). (Also, C and C++ are standardized so no matter who implements the compiler and the standard library, it has to follow the language standard.)
The standard library among other things is not only providing a wrapper for syscalls such as malloc and printf (POSIX API), it is also providing some useful functions or algorithms such as qsort, std::transform... Furthermore, data structure or containers can also be part of a standard library: std::vector, std::unordered_map, ...
Now, if we compile a C or C++ program, the ABI is basically a set of definitions/rules, that the compiler has to abide to. Meaning things like how function parameters are stored (stacked or in registers), how a function should be called, how arguments are passed, how operations are mapped to machine code etc. But not only is an ABI a mapping or layout between C instructions and machine code, it is also a mapping between OS syscalls and C or C++ code.
Exception handling in C and POSIX is basically this:
#include <stdio.h>
#include <setjmp.h>
int main() {
}So if I do exception handling in C++, then the ABI of C++ should follow an exception handling routine. For example, virtual functions in C are basically this:
https://godbolt.org/z/x94cdb1Y5
So vtables are structs of function pointers. The C++ compiler has to follow some ABI convention (namely, some rule how to map or translate a vtable implementation such that it corresponds to the C++ code.)
- syscalls ~ POSIX API (operating systems API) ~ write, read, open, ...
- C/C++ standard library (.so files loaded in computer memory) ~ wrapper for syscalls (printf, malloc, ...), containers/data structures/algorithms (std::vector, std::unordered_map, qsort, ...)
-ABI ~ rules for the compiler that tell how vtables, function calls, exceptions should be implemented
Correct so far? Or am I still wrong?