Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0006693OCamlruntime system and C interfacepublic2014-12-06 12:382017-02-16 15:15
ReporterRichard Jones 
Assigned Togasche 
Platformamd64OSLinuxOS Version
Product Version 
Target Version4.02.2+dev / +rc1Fixed in Version4.02.2+dev / +rc1 
Summary0006693: RFE: build libasmrun_shared too
DescriptionI want to routinely build Linux .so files containing OCaml code. This can be done, see Gerd's instructions here: [^]

*but* it requires that you recompile OCaml with -fPIC, otherwise you get this error:

/usr/bin/ld: /usr/lib64/ocaml/libasmrun.a(startup.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC

So it would be nice if this just worked out of the box. I think by analogy to, there should be, and ocamlopt should select '-lasmrun_shared' when asked to build a .so file.

This has been requested multiple times on the mailing list: [^] [^] [^]
Attached Filespatch file icon camlrun_pic.patch [^] (4,884 bytes) 2015-02-05 15:32 [Show Content]
patch file icon grel.patch [^] (1,497 bytes) 2015-05-02 19:33 [Show Content]

- Relationships
related to 0006733closedgasche Teach ocamlbuild to create shared libraries using -output-obj 
related to 0006845closeddoligez New mode where ocamlc doesn't check list of primitives 

-  Notes
yallop (developer)
2014-12-06 17:13

I agree that this would be useful. Ctypes provides facilities for building shared objects from OCaml libraries, and it'd be better if the instructions for doing so didn't have to begin with "First, recompile OCaml with -fPIC" ...

Example here: [^]
Richard Jones (reporter)
2014-12-06 20:45

My specific need stems from writing nbdkit plugins in OCaml: [^]
shinwell (developer)
2014-12-08 09:57

We must sort this out. I will see what I can do.
whitequark (developer)
2014-12-29 03:21

I've attached a patch that builds like It also builds libasmrun_pic.a and libcamlrun_pic.a, since in many cases it is inconvenient to refer to a shared library that is not in default library search path.
gasche (administrator)
2015-01-03 20:29

Would the "people that know this stuff" give an opinion on the proposed patch? It's a dependency to get the ocamlbuild-related patch in PR#6733 (which I'm ready to merge) to work properly.
shinwell (developer)
2015-01-05 10:02

I will have a look at it, when I can find a moment...
whitequark (developer)
2015-01-28 21:23

Ping? This is needed for [^]
shinwell (developer)
2015-02-05 12:09

I had a look for two minutes, and I spotted two things.

1. It appears that PICFLAGS does not include -O. Is this intentional?

2. Why does e.g. the implicit rule for %.pic.o include ASPPPROFFLAGS? Those are for profiling. (Should we build shared library versions of the profiling-enabled libraries too? I tend to think that there's no point for Linux since perf is almost certainly more useful than gprof---but for other platforms, this argument may not hold.)
whitequark (developer)
2015-02-05 15:32

1. -O added.

I think we can add profiling-enabled shared libraries when someone needs them.
whitequark (developer)
2015-02-25 08:09

shinwell (developer)
2015-02-25 08:25

Pong. (I will look at this when I have a moment.)
whitequark (developer)
2015-03-06 01:38

avsm (developer)
2015-03-15 18:08

A minor nit on this patch; `SHARED` is quite a general variable name to go in the top-level Makefile. Would something like `SHARED_LIBS` or `SHARED_LIBS_MODE` to reflect the purpose of the variable be clearer?
gasche (administrator)
2015-05-02 17:07

The patch is slightly wrong as there are dangling `; fi` in the byterun/Makefile:install-shared target, but that is easy to fix.
gasche (administrator)
2015-05-02 17:28

There was another minor problem with the patch:
  libcamlrun_pic.a: $(OBJS)
should be
  libcamlrun_pic.a: $(PICOBJS)
gasche (administrator)
2015-05-02 17:31

Merged in 4.02 and trunk, thanks!
whitequark (developer)
2015-05-02 17:33

Thank you for the review!
gasche (administrator)
2015-05-02 17:39

There seems to be an issue on MacOSX, with the failure message shown below from out continuous integration test. If you have ideas of how to fix it, I can apply them right now, otherwise I may have to revert the patch and let someone with access to a test machine handle it.


gcc -c -I../byterun -DCAML_NAME_SPACE -DNATIVE_CODE -DTARGET_amd64 -DSYS_macosx -O -D_FILE_OFFSET_BITS=64 -D_REENTRANT -o debugger.pic.o debugger.c
gcc -c -I../byterun -DCAML_NAME_SPACE -DNATIVE_CODE -DTARGET_amd64 -DSYS_macosx -O -D_FILE_OFFSET_BITS=64 -D_REENTRANT -o meta.pic.o meta.c
gcc -c -I../byterun -DCAML_NAME_SPACE -DNATIVE_CODE -DTARGET_amd64 -DSYS_macosx -O -D_FILE_OFFSET_BITS=64 -D_REENTRANT -o dynlink.pic.o dynlink.c
clang -arch x86_64 -c -DSYS_macosx -DMODEL_default -o amd64.pic.o amd64.S
rm -f libasmrun_pic.a
ar rc libasmrun_pic.a startup.pic.o main.pic.o fail.pic.o roots.pic.o globroots.pic.o signals.pic.o signals_asm.pic.o misc.pic.o freelist.pic.o major_gc.pic.o minor_gc.pic.o memory.pic.o alloc.pic.o compare.pic.o ints.pic.o floats.pic.o str.pic.o array.pic.o io.pic.o extern.pic.o intern.pic.o hash.pic.o sys.pic.o parsing.pic.o gc_ctrl.pic.o terminfo.pic.o md5.pic.o obj.pic.o lexing.pic.o printexc.pic.o callback.pic.o weak.pic.o compact.pic.o finalise.pic.o custom.pic.o unix.pic.o backtrace.pic.o natdynlink.pic.o debugger.pic.o meta.pic.o dynlink.pic.o amd64.pic.o
ranlib libasmrun_pic.a
gcc -bundle -flat_namespace -undefined suppress -Wl,-no_compact_unwind -o startup.pic.o main.pic.o fail.pic.o roots.pic.o globroots.pic.o signals.pic.o signals_asm.pic.o misc.pic.o freelist.pic.o major_gc.pic.o minor_gc.pic.o memory.pic.o alloc.pic.o compare.pic.o ints.pic.o floats.pic.o str.pic.o array.pic.o io.pic.o extern.pic.o intern.pic.o hash.pic.o sys.pic.o parsing.pic.o gc_ctrl.pic.o terminfo.pic.o md5.pic.o obj.pic.o lexing.pic.o printexc.pic.o callback.pic.o weak.pic.o compact.pic.o finalise.pic.o custom.pic.o unix.pic.o backtrace.pic.o natdynlink.pic.o debugger.pic.o meta.pic.o dynlink.pic.o amd64.pic.o
ld: illegal text reloc in '_caml_start_program' to '_caml_program' for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[4]: *** [] Error 1
make[3]: *** [makeruntimeopt] Error 2
make[2]: *** [opt-core] Error 2
make[1]: *** [opt.opt] Error 2
make: *** [world.opt] Error 2
whitequark (developer)
2015-05-02 18:05

The crux of the issue is that GCALL(_caml_start_program)(%rip) (unlike, say, GCALL(caml_apply1)(%rip), which works), is an actual unresolved reference when compiled into a shared object, and thus it would have to be updated by dyld on startup. dyld normally refuses to update references in __TEXT; on i386, this can be ameliorated by passing -read_only_relocs suppress to ld, but on x86_64, this is a hard error.

Let me see how it can be fixed.
whitequark (developer)
2015-05-02 18:20

Correction: the references to caml_apply were also invalid. I'm attaching a patch that fixes this. As far as I can see this code was never 'correct', you shouldn't use a relocation mode intended for calls with lea.
whitequark (developer)
2015-05-02 18:41

A new version of the patch attached that doesn't break Windows.
gasche (administrator)
2015-05-02 19:10

With the proposed patch, ./ocamlc.opt segfaults on my machine (and the testsuite breaks).

I reverted the change from 4.02. We might be able to fix things in trunk, but I'm not qualified to decide whether it can go in the stable branch.
whitequark (developer)
2015-05-02 19:26

Ok, I completely forgot that the @GOTPCREL entry just contains the address of the global (i.e. function in this case) but @PLT entry contains executable code that jumps onto the function entry point. Thus we need to remove a level of indirection. I will attach a patch in a moment.
whitequark (developer)
2015-05-02 19:33

Patch updated.
gasche (administrator)
2015-05-02 22:39

The new patch fixes the build failure, thanks.
whitequark (developer)
2015-05-02 22:47

It only uses a technique (LEA_VAR) that is already applied elsewhere, so in my opinion it should be safe to apply to both trunk and stable. The choice is yours, of course.
jacques-henri.jourdan (manager)
2015-05-05 17:46

The second patch seems OK to me.

Notice it has a slightly different behaviour, because LEA_VAR loads the actual address of the function being called, while leaq GCALL(..%PLT) loads the entry in the PLT.

It would be really nice to document properly this feature.

Concerning portability, the only architecture where the runtime contains PIC code is arm64, but the compiler backend does not generate PIC code for arm64, which make this kind of useless. Analogously, the arm backend can produce PIC code, but its runtime doesn't seem to be PIC compatible... Clarification needed.
doligez (administrator)
2015-05-05 19:49

Let me ask for Xavier's opinion before we apply this patch to 4.02.
xleroy (administrator)
2015-05-06 09:28

The grel.patch and its use of LEA_VAR look correct to me. gcc -fPIC also generates a movq from a GOTPCREL relocation in this case (taking a pointer to an external function).
shinwell (developer)
2015-05-06 17:14

I also think the grel.patch bugfix is correct. I'm a bit rusty on these topics, but if I understand correctly, the visible semantics shouldn't have changed: originally (with @PLT) we would have taken the address of a PLT trampoline that branched immediately through a particular GOT entry (which in turn would call the lazy resolution stub, or branch to the function itself if it had already been resolved); now, we obtain the address from the same GOT entry directly by using a %rip-relative load---the offset being calculated by the (static) linker when dealing with the GOTPCREL relocation.

We should probably test on more architectures to ensure the libasmrun_shared support works correctly, or is documented not to work. I may be able to help for SPARC and POWER, since I need to find suitable machines to test another patch.

I've applied the patch for the relocations to the 4.02 branch.

I spoke to Damien and he agreed that we can un-revert the main patch. Gabriel, are you able to do this? I looked at "svn diff -r 16071:16072" and it looks like some other changes might have got caught up in your reversion (maybe only in "Changes")?
gasche (administrator)
2015-05-06 17:16

I will unrevert, but unless this is very urgent I will wait for the next week-end to do it.
gasche (administrator)
2015-05-10 07:48

Merged in 4.02 again.
Richard Jones (reporter)
2015-06-20 12:52

Just a note: I have enabled OCaml-based plugins in nbdkit using this work. Everything appears to work fine.
yallop (developer)
2015-06-20 14:57

It works for me, too: [^]

- Issue History
Date Modified Username Field Change
2014-12-06 12:38 Richard Jones New Issue
2014-12-06 17:13 yallop Note Added: 0012688
2014-12-06 20:45 Richard Jones Note Added: 0012690
2014-12-08 09:57 shinwell Note Added: 0012710
2014-12-08 09:57 shinwell Assigned To => shinwell
2014-12-08 09:57 shinwell Status new => acknowledged
2014-12-08 09:57 shinwell Status acknowledged => assigned
2014-12-29 01:08 whitequark Relationship added related to 0006733
2014-12-29 03:20 whitequark File Added: camlrun_pic.patch
2014-12-29 03:21 whitequark Note Added: 0012998
2015-01-03 20:29 gasche Note Added: 0013005
2015-01-05 10:02 shinwell Note Added: 0013007
2015-01-13 22:41 doligez Tag Attached: patch
2015-01-13 22:41 doligez Target Version => 4.02.2+dev / +rc1
2015-01-28 21:23 whitequark Note Added: 0013187
2015-02-05 12:09 shinwell Note Added: 0013233
2015-02-05 15:31 whitequark File Deleted: camlrun_pic.patch
2015-02-05 15:32 whitequark File Added: camlrun_pic.patch
2015-02-05 15:32 whitequark Note Added: 0013237
2015-02-25 08:09 whitequark Note Added: 0013342
2015-02-25 08:25 shinwell Note Added: 0013343
2015-03-06 01:38 whitequark Note Added: 0013394
2015-03-15 18:08 avsm Note Added: 0013490
2015-05-02 17:07 gasche Note Added: 0013784
2015-05-02 17:28 gasche Note Added: 0013785
2015-05-02 17:31 gasche Note Added: 0013786
2015-05-02 17:31 gasche Status assigned => resolved
2015-05-02 17:31 gasche Fixed in Version => 4.02.2+dev / +rc1
2015-05-02 17:31 gasche Resolution open => fixed
2015-05-02 17:33 whitequark Note Added: 0013788
2015-05-02 17:39 gasche Note Added: 0013789
2015-05-02 18:05 whitequark Note Added: 0013791
2015-05-02 18:20 whitequark Note Added: 0013794
2015-05-02 18:20 whitequark Status resolved => feedback
2015-05-02 18:20 whitequark Resolution fixed => reopened
2015-05-02 18:21 whitequark File Added: grel.patch
2015-05-02 18:41 whitequark File Deleted: grel.patch
2015-05-02 18:41 whitequark File Added: grel.patch
2015-05-02 18:41 whitequark Note Added: 0013795
2015-05-02 19:10 gasche Note Added: 0013796
2015-05-02 19:26 whitequark Note Added: 0013797
2015-05-02 19:33 whitequark File Deleted: grel.patch
2015-05-02 19:33 whitequark File Added: grel.patch
2015-05-02 19:33 whitequark Note Added: 0013798
2015-05-02 22:39 gasche Note Added: 0013799
2015-05-02 22:47 whitequark Note Added: 0013800
2015-05-05 17:46 jacques-henri.jourdan Note Added: 0013809
2015-05-05 19:49 doligez Note Added: 0013816
2015-05-06 09:28 xleroy Note Added: 0013826
2015-05-06 17:14 shinwell Note Added: 0013834
2015-05-06 17:15 shinwell Assigned To shinwell => gasche
2015-05-06 17:15 shinwell Status feedback => assigned
2015-05-06 17:16 gasche Note Added: 0013835
2015-05-10 07:48 gasche Note Added: 0013885
2015-05-10 07:48 gasche Status assigned => resolved
2015-05-10 07:48 gasche Resolution reopened => fixed
2015-05-12 16:55 doligez Relationship added related to 0006845
2015-06-20 12:52 Richard Jones Note Added: 0014108
2015-06-20 14:57 yallop Note Added: 0014113
2017-02-16 15:15 xleroy Status resolved => closed
2017-02-23 16:43 doligez Category OCaml runtime system => runtime system
2017-03-03 17:45 doligez Category runtime system => runtime system and C interface

Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker