From 39a45d82a89176b750123d573533717f88713611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vivek=20Das=C2=A0Mohapatra?= <vivek@collabora.co.uk> Date: Thu, 18 May 2017 20:51:31 +0100 Subject: [PATCH] Add documentation for quick-start, adding capsules & limitations --- doc/Building.txt | 95 +++++++++++++++++++++++++++++++++++++++++++++ doc/Limitations.txt | 51 ++++++++++++++++++++++++ doc/Quick-Start.txt | 45 +++++++++++++++++++++ 3 files changed, 191 insertions(+) create mode 100644 doc/Building.txt create mode 100644 doc/Limitations.txt create mode 100644 doc/Quick-Start.txt diff --git a/doc/Building.txt b/doc/Building.txt new file mode 100644 index 000000000..a640a74f8 --- /dev/null +++ b/doc/Building.txt @@ -0,0 +1,95 @@ +Here we will outline the pieces necessary to build a libcapsule based +library. + +At the moment libcapsule is still in its very early stages, so libraries +that use libcapsule are built as part of libcapsule's build process. + +This will be broken out properly to allow external builds (technically +it's possible right now but the details are not yet documented) + +Let us say we have a library libfoo.so.3.1 for which we wish to generate a +capsule. We would need to make the following changes: + +============================================================================ +Makefile.am: + +Add a line like this with the other lib_LTLIBRARIES lines: + +lib_LTLIBRARIES += libfoo.la + +Then in the 'shim libraries' section: + +libfoo_la_SOURCES = shim/libfoo.so.c +libfoo_la_LDFLAGS = -lcapsule -version-number 3:1:0 + +Or, if the library in question uses versioned symbols: + +libfoo_la_SOURCES = shim/libfoo.so.c +libfoo_la_LDFLAGS = -lcapsule -version-number 3:1:0 \ + -Wl,--version-script=shim/libfoo.so.map + +============================================================================ + +shim/libfoo.so.c.excluded + +This file should contain a list of libraries which should _NOT_ +be picked up from the /host tree and isolated in the capsule, +one per line. + +The following libraries are always considered to be excluded by +the code generator, so there's no need to add them explicitly: + +libc.so.6 +libpthread.so.0 +libpthread-2.19.so +libdl.so.2 + +============================================================================ + +shim/libfoo.so.c.shared + +This file should contain any extra libraries whose symbols should _also_ be +exported from the capsule, along with those from the main library libfoo.so. + +It will generally be empty, but in libGL.so's case it contains: + +libxcb.so.1 +libxcb-glx.so.0 +libxcb-dri2.so.0 +libxcb-dri3.so.0 +libxcb-present.so.0 +libxcb-sync.so.1 +libX11.so + +If your _application_ (ie the program itself, NOT libfoo) links against any +of these directly, it will likely also need the same shared libraries in the +.shared file. + +============================================================================ + +shim/libfoo.so.c.dlopen + +If your library needs any special handling of dlopen() calls you will need to +implement a function with the following signature and name: + +static void *_dlopen (const char *filename, int flags) +{ + ⋮ +} + +and put it in this file. If you do not, the default _dlopen wrapper generated +by libcapsule's code generator will be installed instead. + +Do not create an empty file with this name if you do not need libfoo-specific +dlopen handling. + +============================================================================ + +That's it - you should be ready to + + ./configure + make + +Your generated capsule libraries (and libcapsule) will be in .libs + +============================================================================ diff --git a/doc/Limitations.txt b/doc/Limitations.txt new file mode 100644 index 000000000..72dd07327 --- /dev/null +++ b/doc/Limitations.txt @@ -0,0 +1,51 @@ +libcapsule currently has the following limitations: + +============================================================================ + +If there are > 1 copies of a library which handles allocation (eg +libstdc++) the capsule cannot protect you from an object allocated +by the encapsulated copy being freed by the public copy. + +Some libraries may be OK with this pattern of behaviour, others +may not. + +============================================================================ + +There can only ever be one copy of libc, libpthread and libdl shared +between the capsule and the public namespace. This behaviour is baked +into the stub library generator script. Probably nothing particularly +sane will happen if you try to ignore this limitation. + +============================================================================ + +Currently only functions are exported from the capsule. Unlike the +previous items, this limitation is not intrinsic and could be lifted. + +============================================================================ + +libcapsule relies on the ld.so.cache from the capsule tree to find +libraries. If the cache is not there, it may still find some libraries +in the default-standard locations but many paths will end up being ignored. + +============================================================================ + +libcapsule replaces any instances of dlopen in the encapsulated libraries +with a wrapper around dlmopen: It does this so that a capsule opened on the +"/host" prefix (for example) continues to use DSOs (libraries and modules) +from "/host", and to prevent dlopen() calls from within the capsule from +breaking encapsulation. + +NB: Currently a dlopen() call from inside a dlmopen() namespace is unsupported +by glibc anyway, and would result in a segfault. + +============================================================================ + +Related to the above: The dlmopen wrapper cannot support RTLD_GLOBAL. + +If the library you are opening relies on calling dlopen() with RTLD_GLOBAL +to expose symbols from one DSO to another it will not work. + +This is a glibc limitation - it could be lifted but would require +the dlmopen libc call (and the linker) to be modified. + +============================================================================ diff --git a/doc/Quick-Start.txt b/doc/Quick-Start.txt new file mode 100644 index 000000000..f59ea7c50 --- /dev/null +++ b/doc/Quick-Start.txt @@ -0,0 +1,45 @@ + In the top level directory: + + ./configure + make + +libcapsule.so and capsules for libGL.so and libz.so will be in .libs/ + +Currently make install probably won't do what you want: There are details +yet to be thrashed out since libcapsule is atypical in that it deliberately +creates libraries with the same name as existing ones: But you can copy. + +The test environment is currently: + +A chroot containing a debian/jessie filesystem with libGL.so removed, +with the "real" OS filesystem bind mounted at /host. + +In the chroot: + +Copy the generated libGL.so into an appropriate directory. + +Ensure that ldd $(which glxgears) points to the libGL.so capsule + +Make sure a full filesystem from the host OS is mounted at /host + +Make sure your chroot is set up so that trivial XOrg programs can run +(xterm, xev, xeyes or whatever). + +Run glxgears. + +If it fails: + + export CAPSULE_DEBUG=path,search,capsule,mprotect,wrappers,ldcache + glxgears 2>&1 | tee glxgears.capsule.log + +capsule debug flags: + path # path manipulation and translation + search # searching for DSOs + ldcache # loading/processing the ld cache + capsule # setting up the proxy capsule + mprotect # handling mprotect (for RELRO) + wrappers # function wrappers installed in the capsule + reloc # patching capsule symbols into external DSOs + elf # detailed ELF introspection logging + +TODO: add instructions for bwrap instead of chroot here. -- GitLab