Closed Bug 532531 Opened 15 years ago Closed 14 years ago

Make binary components work with a static build (Mac)

Categories

(Firefox :: General, defect)

x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED INCOMPLETE

People

(Reporter: joelr, Assigned: joelr)

References

Details

Components are not able to link against dynamic libraries anymore but still need string handling and other functionality now living within Firefox.
On the Mac we can use the -bundle_loader flag. When building a plugin, -bundle_loader tells the linker what executable will load the plugin, so the plugin's dependencies may link to the main executable itself. 

We'll need to make sure the symbol visibility options for the main executable publish any symbols that the plugins might use.

Does this apply to other platforms?
So this appears to be a no-brainer on Mac OSX, no changes needed to XPCOM or component code as far as I understand. 

Does Linux have a similar approach to linking plugins against the executable, rather than a shared library?

Do we want to make static builds an OSX-only feature, at least initially?
When you use -bundle_loader, is the name of the main executable encoded in the component? I think we need XPCOM components to continue working no matter which application is loading them.

I really don't want to end up with totally different linkage on different platforms... if we do this, we should do it for all platforms.

I think that on Linux you can just leave unresolved symbols and they may be resolved by the executable as long as you link the executable with -E or use --dynamic-list, but that would require linking the component without -z defs. As far as I know there isn't an equivalent to -bundle_loader which would say "look in this executable to check for unresolved symbols".
Benjamin, it should be very easy to answer whether the executable name is encoded in the component with -bundle_loader. I'll run an experiment and report my findings. 

I understand that you had an idea with using pointers but I really don't understand how the linkage will work in your scenario. In fact, I think that we should leave resolution of unknown symbols to the dynamic linker, so long as this is possible on Linux.
Loading a "plugin" into another "host" does not seem to be an issue, e.g.

--- plugin.c ---

#include <stdio.h>

extern void somefun();

void entry_point()
{
  somefun();
}

--- plugin_host.c ---

#include <stdio.h>
#include <dlfcn.h>

typedef void* (*entry_point)(void);

void somefun() 
{
  printf("gotcha!\n");
}

int main(int argc, char* argv[])
{
  if (argc < 2)
  {
    printf("Usage: %s <plugin to load>\n", argv[0]);
    return -1;
  }
  
  entry_point ep;

  void* handle = dlopen(argv[1], RTLD_NOW|RTLD_GLOBAL);
  *(void**)(&ep) = dlsym(handle, "entry_point");
  
  (void)ep();
  
  return 0;
}

---

gcc -g plugin-host.c -o phost

./phost
Usage: ./phost <plugin to load>

gcc -g plugin.c -o plugin -bundle -flat_namespace -bundle_loader ./phost

file plugin
Mach-O 64-bit bundle x86_64

nm plugin
0000000000000f46 s  stub helpers
0000000000000000 t __mh_bundle_header
0000000000000f30 T _entry_point
                 U _somefun
                 U dyld_stub_binder

strings plugin
<nothing>

grep phost plugin
<nothing>

./phost plugin
gotcha!

# create another plugin host
gcc -g plugin-host.c -o phost1

./phost1 plugin
gotcha!
Summary: Static build of Firefox breaks binary components → Make binary components work with a static build (Mac)
Assignee: nobody → joelr
Status: NEW → RESOLVED
Closed: 14 years ago
Resolution: --- → INCOMPLETE
You need to log in before you can comment on or make changes to this bug.