@@ -28,6 +28,7 @@ to be used directly.
2828 * [ 2.2.2 Call Action Options] ( #s222 )
2929 * [ 2.2.3 Call Action Standard Library] ( #s223 )
3030 * [ 2.2.4 Call Action Initialization] ( #s224 )
31+ * [ 2.2.4 Call Action Dynamic Loading] ( #s225 )
3132 - [ 2.3 Plugin Actions] ( #s23 )
3233
3334---
@@ -942,7 +943,7 @@ stack manually inside the instrumentation code.
942943#### <a id =" s223 " >2.2.3 Call Action Standard Library</a >
943944
944945The main limitation of call actions is that the instrumentation
945- cannot use dynamically linked libraries, including ` glibc ` .
946+ cannot use dynamically linked libraries directly , including ` glibc ` .
946947This is because the instrumentation binary is directly injected
947948into the rewritten binary rather than dynamically/statically linked.
948949
@@ -957,21 +958,8 @@ However, only a subset of libc is implemented, so it is WYSIWYG.
957958Many common libc functions, including file I/O and memory
958959allocation, have been implemented.
959960
960- It is not advisable to call the "real" ` glibc ` functions from call
961- instrumentation, namely:
962-
963- * ` glibc ` functions use the System V ABI which is not compatible with
964- the clean call ABI.
965- Specifically, the clean ABI does not align the stack nor save/restore
966- floating point registers for performance reasons.
967- * Many ` glibc ` functions are not reentrant and access/modify global state
968- such as ` errno ` .
969- Thus, calling ` glibc ` functions directly can break transparency and/or cause
970- problems such as deadlocks.
971-
972- Unlike ` glibc ` ,
973- the parallel libc is designed to be compatible with the clean ABI and
974- handle problems such as deadlocks gracefully.
961+ Unlike ` glibc ` the parallel libc is designed to be compatible with the clean
962+ ABI and handle problems, such as deadlocks, more gracefully.
975963
976964---
977965#### <a id =" s224 " >2.2.4 Call Action Initialization</a >
@@ -1004,6 +992,61 @@ zero/`NULL` for patched shared objects.
1004992In the example above, the initialization function searches for an
1005993environment variable ` MAX ` , and sets the ` max ` counter accordingly.
1006994
995+ ---
996+ #### <a id =" s225 " >2.2.5 Call Action Dynamic Loading</a >
997+
998+ The parallel libc also provides an implementation of the standard dynamic linker
999+ functions ` dlopen() ` , ` dlsym() ` , and ` dlclose() ` .
1000+ These can be used to dynamically load shared objects at runtime, or access
1001+ existing shared libraries that are already dynamically linked into the original
1002+ program.
1003+ To enable, simply define the ` LIBDL ` macro before including ` stdlib.c ` .
1004+
1005+ #define LIBDL
1006+ #include "stdlib.c"
1007+
1008+ The ` dlinit(dynamic) ` function must also be called in the ` init() ` routine,
1009+ where ` dynamic ` is the fourth argument to the ` init() ` function:
1010+
1011+ void init(int argc, char **argv, char **envp, void *dynamic)
1012+ {
1013+ int result = dlinit(dynamic);
1014+ ...
1015+ }
1016+
1017+ Once initialized, the ` dlopen() ` , ` dlsym() ` , and ` dlclose() ` functions can be
1018+ used similarly to the standard ` libdl ` counterparts.
1019+
1020+ Note that function pointers returned by ` dlsym() ` ** should not be called
1021+ directly** unless you know what you are doing.
1022+ This is because most libraries are compiled with the System V ABI, which is
1023+ incompatible with the clean call ABI used by the instrumentation.
1024+ To avoid ABI incompatibility, the external library code should be called using
1025+ a special wrapper function ` dlcall() ` :
1026+
1027+ intptr_t dlcall(void *func, arg1, arg2, ...);
1028+
1029+ The ` dlcall() ` function will:
1030+
1031+ * Align/restore the stack pointer to 16bytes, as required by the System V ABI.
1032+ * Save/restore the extended register state, including ` %xmm0 ` , etc.
1033+ * Save/restore the glibc version of ` errno ` .
1034+
1035+ Be aware that the dynamic loading API has several caveats:
1036+
1037+ * The ` dlopen() ` , ` dlsym() ` , and ` dlclose() ` are wrappers for the glibc
1038+ versions of these functions (` __libc_dlopen ` , etc.).
1039+ The glibc versions do not officially exist, so this functionality may change
1040+ at any time.
1041+ Also the glibc versions lack some features, such as ` RTLD_NEXT ` , that are
1042+ available with the standard libdl versions.
1043+ * Since glibc is required, the original binary must be dynamically linked.
1044+ * Many external library functions are not designed to be reentrant, and this
1045+ may cause deadlocks if a signal occurs when the signal handler is also
1046+ instrumented.
1047+ * The ` dlcall() ` function supports a maximum of 16 arguments.
1048+ * The ` dlcall() ` function is relatively slow, so ought to be used sparingly.
1049+
10071050---
10081051### <a id =" s23 " >2.3 Plugin Actions</a >
10091052
0 commit comments