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