Something went wrong. Try again.
My own corner of monopam
Something went wrong. Try again.
3.1 kB · 94 lines
Shell
at main
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495#!/usr/bin/env bash# The symbol names a Darwin developer link keeps in its symbol table.## -no_exported_symbols makes every global symbol of the link local, and# -non_global_symbols_no_strip_list keeps the local names the list matches and# drops the others. OCaml names each static block, closure and constant of a# unit as well as each function: three in four of space's 594,102 names are# data, which no debugger, sampler or backtrace reads (a backtrace reads the# frame table). The list keeps the name of every piece of code and of every# symbol that is not an OCaml unit's:## caml<Unit>$<function>_<stamp> a function; also a value whose name is an# operator, the one data shape it keeps# caml<Unit>$code_begin, $code_end, $entry# caml_<name> the runtime and the C stubs# any name not caml<Upper>... C, Objective-C and assembler labels## and drops caml<Unit>__<value>_<stamp>, caml<Unit>$<function>_<stamp>_closure,# caml<Unit>$frametable, $gc_roots, $data_begin and $data_end.## The shapes are the compiler's, so the list is read against the compiler that# links: a probe executable over the standard library is linked with OCAMLOPT,# and every code symbol of it must be kept and no data symbol of an OCaml unit# may be, or this refuses, naming the symbols.## link-keep.sh OCAMLOPTset -euo pipefailexport LC_ALL=C
ocamlopt=${1:?usage: link-keep.sh OCAMLOPT}
keep=( '_caml*$[_a-zA-Z]*[0-9]' '_caml*$$$*[0-9]' '_caml*$code_begin' '_caml*$code_end' '_caml*$entry' '_caml[_$.a-z0-9]*' '_cam[_$.A-Za-km-z0-9]*' '_ca[_$.A-Za-ln-z0-9]*' '_c[_$.A-Zb-z0-9]*' '_[_$.A-Zabd-z0-9]*' '[.$A-Za-z0-9]*' '-*' '+*' '_' '_c' '_ca' '_cam' '_caml')
work=$(mktemp -d "${TMPDIR:-/tmp}/link-keep.XXXXXX")trap 'rm -rf "$work"' EXITprintf '%s\n' \ 'let rec count n = if n = 0 then 0 else 1 + count (n - 1)' \ 'let ( +++ ) a b = a + b' \ 'let table = Hashtbl.create 7' \ 'let () = Hashtbl.replace table "k" (List.map (fun x -> x +++ 1) [ 1; 2 ])' \ 'let () = Printf.printf "%d %F\n" (count (Array.length Sys.argv)) 1.5' \ > "$work/link_keep_probe.ml"(cd "$work" && "$ocamlopt" -o probe.exe link_keep_probe.ml) >&2
kept() { local glob for glob in "${keep[@]}"; do # shellcheck disable=SC2053 [[ $1 == $glob ]] && return 0 done return 1}
dropped_code=()kept_data=()while read -r kind name; do case $kind in T | t) kept "$name" || dropped_code+=("$name") ;; D | d | S | s | B | b) case $name in _caml[A-Z]*) if kept "$name"; then kept_data+=("$name"); fi ;; esac ;; esacdone < <(nm "$work/probe.exe" | awk 'NF == 3 { print $2, $3 }')
if [ ${#dropped_code[@]} != 0 ] || [ ${#kept_data[@]} != 0 ]; then echo "link-keep.sh: the list does not fit $ocamlopt's symbols" >&2 for name in ${dropped_code[@]+"${dropped_code[@]}"}; do echo " code dropped: $name" >&2; done for name in ${kept_data[@]+"${kept_data[@]}"}; do echo " data kept: $name" >&2; done exit 1fiprintf '%s\n' "${keep[@]}"