diff --git a/Changes b/Changes index 97f6394636b5..5e8ee01cb69b 100644 --- a/Changes +++ b/Changes @@ -163,7 +163,8 @@ ___________ - #13???: Introduce a RuntimeID for use in filename mangling to allow different configurations and different versions of ocamlrun and the shared runtime - libraries to coexist harmoniously on a single system. + libraries to coexist harmoniously on a single system. A portable version is + used in launcher header for bytecode executables. (David Allsopp, review by ???) ### Code generation and optimizations: diff --git a/Makefile b/Makefile index c22914612de5..931890e7fc61 100644 --- a/Makefile +++ b/Makefile @@ -2711,7 +2711,7 @@ install:: $(LN) "$(TARGET)-$(1)-$(BYTECODE_RUNTIME_ID)$(EXE)" "$(1)$(EXE)" cd "$(INSTALL_BINDIR)" && \ $(LN) "$(TARGET)-$(1)-$(BYTECODE_RUNTIME_ID)$(EXE)" \ - "$(1)-$(BYTECODE_RUNTIME_ID)$(EXE)" + "$(1)-$(ZINC_RUNTIME_ID)$(EXE)" endef define INSTALL_RUNTIME_LIB ifeq "$(2)" "BYTECODE" diff --git a/Makefile.build_config.in b/Makefile.build_config.in index f413fb9e3250..9d1895c6b407 100644 --- a/Makefile.build_config.in +++ b/Makefile.build_config.in @@ -186,3 +186,4 @@ TSAN_NATIVE_RUNTIME_C_SOURCES = @tsan_native_runtime_c_sources@ # OCaml release number, relative to 3.12 (used for RuntimeID) OCAML_RELEASE_NUMBER = @OCAML_RELEASE_NUMBER@ +ZINC_RUNTIME_ID = @zinc_runtime_id@ diff --git a/bytecomp/bytelink.ml b/bytecomp/bytelink.ml index 770665366c03..44054b366368 100644 --- a/bytecomp/bytelink.ml +++ b/bytecomp/bytelink.ml @@ -390,7 +390,7 @@ let write_header outchan = let ocamlrun = Printf.sprintf "ocamlrun%s-%s" !Clflags.runtime_variant - Config.bytecode_runtime_id + Config.zinc_runtime_id in (false, ocamlrun) in diff --git a/configure b/configure index e4351928b393..922d8d43c2c8 100755 --- a/configure +++ b/configure @@ -785,6 +785,7 @@ build_os build_vendor build_cpu build +zinc_runtime_id native_runtime_id bytecode_runtime_id ar_supports_response_files @@ -21036,6 +21037,7 @@ quintet3_native="$(echo "${alphabet}" | cut -c $(expr ${quintet3_native} + 1))" bytecode_runtime_id="${quintet3_byte}${quintet2}${quintet1}2" native_runtime_id="${quintet3_native}${quintet2}${quintet1}2" +zinc_runtime_id="00${quintet1}2" # Do not permanently cache the result of flexdll.h unset ac_cv_header_flexdll_h diff --git a/configure.ac b/configure.ac index 620405b45b6a..967c36443fb9 100644 --- a/configure.ac +++ b/configure.ac @@ -258,6 +258,7 @@ AC_SUBST([QS]) AC_SUBST([ar_supports_response_files]) AC_SUBST([bytecode_runtime_id]) AC_SUBST([native_runtime_id]) +AC_SUBST([zinc_runtime_id]) ## Generated files @@ -2711,6 +2712,7 @@ quintet3_native="$(echo "${alphabet}" | cut -c $(expr ${quintet3_native} + 1))" bytecode_runtime_id="${quintet3_byte}${quintet2}${quintet1}QUINTET0" native_runtime_id="${quintet3_native}${quintet2}${quintet1}QUINTET0" +zinc_runtime_id="00${quintet1}QUINTET0" # Do not permanently cache the result of flexdll.h unset ac_cv_header_flexdll_h diff --git a/runtime/Mangling.md b/runtime/Mangling.md index 046f7c6e6d36..01ae47e85288 100644 --- a/runtime/Mangling.md +++ b/runtime/Mangling.md @@ -49,7 +49,7 @@ OCaml 5.x series. ## Masks A particular configuration of the compiler has one RuntimeID, but this is used -in two different contexts where certain bits are masked out: +in three different contexts where certain bits are masked out: 1. Bytecode Mask (0xe7fff) is used by `libcamlrun` and masks out the frame pointers and spacetime bits since these affect neither the runtime nor code @@ -57,6 +57,8 @@ in two different contexts where certain bits are masked out: 2. Native Mask (0xfffff) is used by `libasmrun`. Note that in native code, the only place where name mangling is used is natdynlink, and bit 8 is therefore _never_ set. +3. Zinc Mask (0x001ff) is used by `ocamlc` for bytecode executables which do not + contain their own runtime. ## File Name Mangling @@ -73,10 +75,33 @@ Mangling is applied to the name of any file which will be loaded at runtime: - `ocamlrun` (and variants) are triplet-prefixed and Bytecode-suffixed. A symbolic is created both for `ocamlrun` and for `ocamlrun` Byte-suffixed but - not triplet-prefixed. + not triplet-prefixed. See below for additional symbolic links which are + created. - C stub libraries loaded by both the bytecode runtime and bytecode `Dynlink`. These are triplet-prefixed and Bytecode-suffixed. The effect is that any runtime attempts to load stub libraries compiled for exactly the same runtime. - Shared versions of the bytecode and native runtimes (`libcamlrun_shared.so` and `libasmrun_shared.so`). These are triplet-prefixed and Bytecode/Native-suffixed respectively. + +Bytecode executables compiled without their runtime pose an additional challenge +as these are portable. When a bytecode image is produced, the Zinc runtime ID is +used to mangle the name of the runtime with Bit 7 set if the bytecode image does +not require 63 bit `int` support (i.e. if the image compiles without error with +`ocamlc -compat-32` then Bit 7 will be set in the RuntimeID, even with a 64-bit +`ocamlc`) and Bit 8 unset. The runtime variant is then Zinc-suffixed to create +the runtime name for the executable's header. For example, if OCaml 5.1 is +configured with `--disable-flat-float-array --disable-shared` (Runtime suffix +`8093`) then an executable not requiring 63-bit `int`s will use `ocamlrun-0053` +as the runtime name. The "Zinc" RuntimeID here creates a portable and +reproducible runtime name. In order to facilitate this, the following additional +symbolic names are created, for each variant ``, with no +triplet-prefix: + +- Zinc-suffixed +- For runtimes supporting 63-bit `int` values, Zinc-suffixed but with Bit 7 set + (i.e. a 64-bit OCaml runtime also advertises that it works for 32-bit) + +Additionally, the header for the bytecode executable will initially search for a +runtime with Bit 8 un-set (i.e. with a preference for runtimes supporting shared +libraries) and fallback to searching for one with Bit 8 set otherwise. diff --git a/utils/config.fixed.ml b/utils/config.fixed.ml index 940b3c6de19b..c093820f9568 100644 --- a/utils/config.fixed.ml +++ b/utils/config.fixed.ml @@ -54,6 +54,7 @@ let flat_float_array = true let function_sections = false let afl_instrument = false let bytecode_runtime_id = "" +let zinc_runtime_id = "" let native_runtime_id = "" let native_compiler = false let tsan = false diff --git a/utils/config.generated.ml.in b/utils/config.generated.ml.in index c718b6540a63..5b82f36c9071 100644 --- a/utils/config.generated.ml.in +++ b/utils/config.generated.ml.in @@ -67,6 +67,7 @@ let function_sections = @function_sections@ let afl_instrument = @afl@ let bytecode_runtime_id = {@QS@|@bytecode_runtime_id@|@QS@} +let zinc_runtime_id = {@QS@|@zinc_runtime_id@|@QS@} let native_runtime_id = {@QS@|@native_runtime_id@|@QS@} let native_compiler = @native_compiler@ diff --git a/utils/config.mli b/utils/config.mli index 522e4e4a33d5..c236cbdb13c1 100644 --- a/utils/config.mli +++ b/utils/config.mli @@ -264,6 +264,12 @@ val bytecode_runtime_id : string @since 5.3 *) +val zinc_runtime_id : string +(** {!bytecode_runtime_id} with the Zinc Mask (used in headers to refer portably + to ocamlrun) + + @since 5.3 *) + val native_runtime_id : string (** The RuntimeID for libasmrun_shared