diff --git a/capsule/capsule.h b/capsule/capsule.h index 0de488575fe1987048ffa35eadce25cb8cfbba08..d6d5410a32faeefaf5f36f1d78d4822c93234e64 100644 --- a/capsule/capsule.h +++ b/capsule/capsule.h @@ -47,8 +47,8 @@ typedef struct _capsule_item capsule_item; struct _capsule_item { const char *name; - capsule_addr shim; capsule_addr real; + capsule_addr shim; /*< private >*/ void *unused0; diff --git a/data/capsule-init-project b/data/capsule-init-project index 179066d6dad1c65b38b62cfa5cfb31cd5406acb5..f0478e1ca6a5b0cc36531e434817d2023c078bd7 100755 --- a/data/capsule-init-project +++ b/data/capsule-init-project @@ -70,6 +70,22 @@ static void *_dlopen (const char *filename, int flag) } EOF +cat - <<EOF > shim/$base.so.c.dlsym +// This allows symbols inside the capsule to be found by dlopen calls from +// outside the capsule iff they are in one of the exported DSOs. +// +// This is useful in libGL shims as libGL has an ‘interesting’ history +// of symbols appearing and disappearing so its users often do a +// bizarre dlopen()/dlsym() dance instead of referring to a symbol +// directly (and we may be missing those symbols from our static +// export list even if the target libGL has them) +static void *_dlsym (void *handle, const char *symbol) +{ + const char **valid_sources = { "libGL.so.1", NULL }; + return capsule_shim_dlsym( dso, handle, symbol, valid_sources ); +} +EOF + echo Initialising configure.ac; cat - <<EOF > configure.ac diff --git a/data/capsule-mkstublib b/data/capsule-mkstublib index b950b6c44ccd7a2b92b2f68f276c008b2d942dc1..5e3bae6bc62e6214c2480d9079cf5baef5a83234 100755 --- a/data/capsule-mkstublib +++ b/data/capsule-mkstublib @@ -47,6 +47,7 @@ proxied_dso=lib${dso_base}.so.${major_version}; symbol_file=${proxy_src%.c}.symbols; map_file=${proxy_src%.c}.map; dlopen_file=${proxy_src}.dlopen; +dlsym_file=${proxy_src}.dlsym; sharedir=$(pkg-config --variable=makeinc capsule) exec >$proxy_src.tmp; @@ -120,6 +121,15 @@ then echo "// -------------------------------------------------------------"; fi +if [ -f ${dlsym_file} ]; +then + echo "// -------------------------------------------------------------"; + echo "// start of ${proxy_src%.c} dlsym wrapper"; + cat $dlsym_file; + echo "// end of ${proxy_src%.c} dlsym wrapper"; + echo "// -------------------------------------------------------------"; +fi + cat - <<EOF static void __attribute__ ((constructor)) _capsule_init (void) @@ -134,8 +144,15 @@ EOF while read sym x; do echo " { \"$sym\" },"; done < $symbol_file; +if [ -f $dlsym_file ]; +then + cat - <<EOF + { "dlsym", (capsule_addr) _dlsym }, +EOF +fi; + cat - <<EOF - { NULL } + { NULL } }; // and this is an aray of functions we must override in the DSOs diff --git a/data/capsule-shim.mk.in b/data/capsule-shim.mk.in index d29dfac3e52dd916d888f25d400f883058771805..d46e12d0af80a3e3a7868fefc0e8cc00c655d5b0 100644 --- a/data/capsule-shim.mk.in +++ b/data/capsule-shim.mk.in @@ -29,7 +29,7 @@ GENSTUB_V0 = @echo " GENSTUB " $(subst $(word 1, $(basename $(filter shim/lib%, GENSTUB = $(GENSTUB_V$(V)) # regenerate if any dependencies get updated: -shim/lib%.so.c: shim/lib%.so.c.excluded shim/lib%.so.c.dlopen shim/lib%.so.symbols +shim/lib%.so.c: shim/lib%.so.c.excluded shim/lib%.so.c.dlopen shim/lib%.so.c.dlsym shim/lib%.so.symbols $(GENSTUB)V=$V $(mkstub) $$(basename $@ .c) $@.excluded $@.shared $@ $(ltver) $(CAPSULE_TREE) # regenerate the exportable symbols list