-
Notifications
You must be signed in to change notification settings - Fork 275
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
provides versioned backends for program units symbol tables
TL;DR; follow mainstream OCaml and make dynamic loading sound and safe (not again, as it never was before). The Problem =========== The long story. Before OCaml 4.08 the dynlink module was unsound. Linking the same module resulted in GC roots table corruption and segmentation faults. To prevent this behavior, we were tracking loaded units. However, we weren't able to reliably track units that were linked into the program directly with the OCaml linker. We were using `findlib.dynload` and a corresponding functionality in dune that provide us the information about the units that were used to link the host program. Unfortunately, `findlib.dynload` was recording this information in terms of the findlib packages, not in compilation units. Therefore, in order to resolve a package name to corresponding compilation unit names we needed a working findlib system, i.e., the META files for all packages that are statically linked in the binary should be present in the hard-coded locations. In normal mode of operation, when packages that were used to build bap are present in the file system it didn't pose any problems. However, when bap together with its plugins was packed into a debian package and distributed to other machines no meta files were available. To enable binary distributions we developed an ocamlbuild plugin that was resolving package names to compilation unit names during the compilation time, so that bap (and other tools built from our main source repository) wasn't dependent on the runtime presence of META files. However, when a host program is compiled with dune, or any other build system that doesn't reflect package names to unit names and store them in the host file predicates (read it anywhere outside of bap), then when packaged and distributed to other hosts the program will fail in runtime. The Solution ============ Sine the bug is fixed in 4.08 there is no longer problem. The solution is trivial, just use Dynlink and the newly provided `all_units` function, that enumerate unit names as we always needed. The only problem with this solution is that it is probably to early for us to drop the support for OCaml 4.07. Therefore, we decided to provide two backends. The fallback solution still uses the old findlib approach, but we decided to make it a little bit more robust, to minimize the debugging time in case it will fail. We now check if we have the static information about the compilation units that comprise the host program, and if we don't then we ensure that we have working ocamlfind and META files. If not than we terminate the program with more or less comprehensible message. If we have a modern compiler, then we just use the Dynlink module (which is guarded with ppx_optcomp).
- Loading branch information
Showing
11 changed files
with
118 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1 @@ | ||
let plugindir = "$plugindir" | ||
|
||
module Units = Bap_plugins_units_$plugins_backend |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
open Core_kernel | ||
|
||
open Bap_plugins_units_intf | ||
|
||
[%%if ocaml_version < (4,08,0)] | ||
include Bap_plugins_units_fallback | ||
[%%else] | ||
let name = "dynlink" | ||
|
||
let units : reason String.Table.t = String.Table.create () | ||
|
||
let copy_units_from_dynlink () = | ||
Dynlink.all_units () |> | ||
List.iter ~f:(fun unit -> Hashtbl.add_exn units unit `In_core) | ||
|
||
let init () = copy_units_from_dynlink () | ||
let list () = Hashtbl.keys units | ||
let record name reason = Hashtbl.add_exn units name reason | ||
let lookup = Hashtbl.find units | ||
[%%endif] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1 @@ | ||
type reason = [ | ||
| `In_core | ||
| `Provided_by of string | ||
| `Requested_by of string | ||
] | ||
|
||
|
||
module type S = sig | ||
val init : unit Lazy.t | ||
|
||
val record : string -> reason -> unit | ||
val lookup : string -> reason option | ||
end | ||
include Bap_plugins_units_intf.S |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.