diff options
| author | Alasdair Armstrong | 2018-01-18 18:16:45 +0000 |
|---|---|---|
| committer | Alasdair Armstrong | 2018-01-18 18:31:26 +0000 |
| commit | 0fa42d315e20f819af93c2a822ab1bc032dc4535 (patch) | |
| tree | 7ef4ea3444ba5938457e7c852f9ad9957055fe41 /lib/ocaml_rts/linksem/command_line.ml | |
| parent | 24dc13511053ab79ccb66ae24e3b8ffb9cad0690 (diff) | |
Modified ocaml backend to use ocamlfind for linksem and lem
Fixed test cases for ocaml backend and interpreter
Diffstat (limited to 'lib/ocaml_rts/linksem/command_line.ml')
| -rw-r--r-- | lib/ocaml_rts/linksem/command_line.ml | 671 |
1 files changed, 0 insertions, 671 deletions
diff --git a/lib/ocaml_rts/linksem/command_line.ml b/lib/ocaml_rts/linksem/command_line.ml deleted file mode 100644 index 62d4b87e..00000000 --- a/lib/ocaml_rts/linksem/command_line.ml +++ /dev/null @@ -1,671 +0,0 @@ -(*Generated by Lem from command_line.lem.*) -open Lem_basic_classes -open Lem_function -open Lem_string -open Lem_string_extra -open Lem_tuple -open Lem_bool -open Lem_list -open Lem_list_extra -(*import Set*) -(*import Set_extra*) -open Lem_sorting -open Lem_num -open Lem_maybe -open Lem_assert_extra - -open Byte_sequence -open Default_printing -open Error -open Missing_pervasives -open Show - -(* Here we try to model the command line of GNU ld.bfd. - * - * Some options are global modifiers affecting the link output. - * Others have effect only for some subset of input files. - * Typically some mutually-exclusive possibilities exist - * whereby each argument selects one such possibility for all subsequent input files, - * until a different argument selects another possibility for ensuring inputs. - *) - -type input_file_spec = Filename of string (* /path/to/file.{o,a,so,...} -- might be script! *) - | Libname of string (* -llib *) - -(*val string_of_input_file_spec : input_file_spec -> string*) -let string_of_input_file_spec spec:string= - ((match spec with - Filename(s) -> "file `" ^ (s ^ "'") - | Libname(s) -> "library `" ^ (s ^ "'") - )) - -let instance_Show_Show_Command_line_input_file_spec_dict:(input_file_spec)show_class= ({ - - show_method = string_of_input_file_spec}) - -type input_file_options = { input_fmt : string - ; input_libpath : string list - ; input_link_sharedlibs : bool (* -Bstatic *) - ; input_check_sections : bool - ; input_copy_dt_needed : bool - ; input_whole_archive : bool - ; input_as_needed : bool - } - -(*val null_input_file_options : input_file_options*) -let null_input_file_options:input_file_options= - ({ input_fmt = "" - ; input_libpath = ([]) - ; input_link_sharedlibs = false - ; input_check_sections = false - ; input_copy_dt_needed = false - ; input_whole_archive = false - ; input_as_needed = false - }) - -type output_kind = Executable - | SharedLibrary - -type link_option = OutputFilename of string - | OutputKind of output_kind - | ForceCommonDefined of bool (* -d, -dc, -dp *) - | Soname of string (* -soname *) - | EntryAddress of Nat_big_num.num - | TextSegmentStart of Nat_big_num.num - | RodataSegmentStart of Nat_big_num.num - | LdataSegmentStart of Nat_big_num.num - | BindFunctionsEarly (* -Bsymbolic-functions *) - | BindNonFunctionsEarly (* the remainder of -Bsymbolic *) - (* more here! *) - -(*val tagEqual : link_option -> link_option -> bool*) -let tagEqual opt1 opt2:bool= ((match (opt1, opt2) with - (* FIXME: Lem BUG here! says "duplicate binding" *) - (OutputFilename(_), OutputFilename(_)) -> true - | (OutputKind(_), OutputKind(_)) -> true - (* | (ForceCommonDefined, ForceCommonDefined) -> true *) - | (Soname(_), Soname(_)) -> true - (* | (EntryAddress, EntryAddress) -> true *) - | (TextSegmentStart(_), TextSegmentStart(_)) -> true - | (RodataSegmentStart(_), RodataSegmentStart(_)) -> true - | (LdataSegmentStart(_), LdataSegmentStart(_)) -> true - (* | (BindFunctionsEarly, BindFunctionsEarly) -> true *) - (* | (BindNonFunctionsEarly, BindNonFunctionsEarly) -> true *) - | _ -> false -)) - -(* To allow filtering out a previous setting for a given option, we define - * an equality relation that is true if options are of the same constructor. - * Seems like a bit of a HACK. *) -let instance_Basic_classes_Eq_Command_line_link_option_dict:(link_option)eq_class= ({ - - isEqual_method = (fun opt1 -> - (fun opt2 -> - (match (opt1, opt2) with - | (OutputFilename(_), OutputFilename(_)) -> true - | (ForceCommonDefined(_), ForceCommonDefined(_)) -> true - | (Soname(_), Soname(_)) -> true - | (EntryAddress(_), EntryAddress(_)) -> true - | _ -> false - ) - )); - - isInequal_method = (fun opt1 -> (fun opt2 -> not ( ((fun opt1 -> - (fun opt2 -> - (match (opt1, opt2) with - | (OutputFilename(_), OutputFilename(_)) -> true - | (ForceCommonDefined(_), ForceCommonDefined(_)) -> true - | (Soname(_), Soname(_)) -> true - | (EntryAddress(_), EntryAddress(_)) -> true - | _ -> false - ) - ))opt1 opt2))))}) - -type input_file_and_options = input_file_spec * input_file_options -type input_unit = File of input_file_and_options - | Group of (input_file_and_options) list (* NOT recursive *) - | BuiltinControlScript (* for uniformity when processing script defs *) - -(*val string_of_input_unit : input_unit -> string*) -let string_of_input_unit u:string= - ((match u with - File(spec, opts) -> - "single " ^ (string_of_input_file_spec spec) - | Group(spec_opt_list) -> - "group: [" ^ ((string_of_list - instance_Show_Show_Command_line_input_file_spec_dict (Lem_list.map (fun (spec, opts) -> spec) spec_opt_list)) ^ "]") - | BuiltinControlScript -> "(built-in control script)" - )) - -let instance_Show_Show_Command_line_input_unit_dict:(input_unit)show_class= ({ - - show_method = string_of_input_unit}) - -(* Reading the command-line: - * we encode the meaning of a linker command token - * using a reader function interpreting a list of argument definitions. - * Lookahead is necessary: sometimes the interpretation of an option - * depends on the next argument (e.g. whether it's a file, directory or another option). - * The list of argument definitions is from lists of strings to constructor function invocations. - * We use lists of strings since many options have synonyms. - * The strings are interpreted as regular expressions and any matched groups are collected together - * as a second argument list; this is because some arguments are of the form --blah=NUM or similar. *) - -(* As we read the command line, we keep a current state which is the collection - * of seen input files, seen whole-link options, and input file options that will - * apply to any input files we add subsequently. *) -type command_state = { input_units : input_unit list - ; link_options : link_option Pset.set - ; current_input_options : input_file_options - ; current_group : ( input_file_and_options list)option - } - -(* This is the "default state" when we start reading input options *) -(*val initial_state : list command_state*) (* the stack *) -let initial_state0:(command_state)list= ([{ input_units = ([]) - ; link_options =(Pset.from_list compare [OutputFilename("a.out"); OutputKind(Executable)]) - ; current_input_options = ({ input_fmt = "elf64-x86-64" (* FIXME *) - ; input_libpath = (["/usr/lib"]) (* FIXME: this probably isn't the right place to supply the default search path *) - ; input_link_sharedlibs = true - ; input_check_sections = true - ; input_copy_dt_needed = false - ; input_whole_archive = false - ; input_as_needed = true (* FIXME *) - }) - ; current_group = None - }]) - -type interpreted_command_line = input_unit list * link_option Pset.set - -(*val add_input_file : list command_state -> string -> list command_state*) -let add_input_file (state1 :: more) s:(command_state)list= - (let chars = (Xstring.explode s) - in - let spec = ((match chars with - '-' :: 'l' :: more -> Libname(Xstring.implode more) - | '-' :: more -> failwith ("not a valid option or input file: " ^ s) - | _ -> Filename(s) - )) - in - if (Lem.option_equal (listEqualBy (Lem.pair_equal (=) (=))) state1.current_group None) - then - { input_units = (List.rev_append (List.rev state1.input_units) [File(spec, state1.current_input_options)]) - ; link_options = (state1.link_options) - ; current_input_options = (state1.current_input_options) - ; current_group = (state1.current_group) - } :: more - else - { input_units = (state1.input_units) - ; link_options = (state1.link_options) - ; current_input_options = (state1.current_input_options) - ; current_group = (let toAppend = ([(spec, state1.current_input_options)]) in - (match state1.current_group with Some l -> Some( List.rev_append (List.rev l) toAppend) | None -> Some(toAppend) - )) - } :: more) - -(*val start_group : list command_state -> list command_state*) -let start_group (state1 :: more):(command_state)list= ({ - input_units = (state1.input_units) - ; link_options = (state1.link_options) - ; current_input_options = (state1.current_input_options) - ; current_group = ((match state1.current_group with - None -> Some [] - | _ -> failwith "cannot nest groups" - )) - } :: more) - -(*val end_group : list command_state -> list command_state*) -let end_group (state1 :: more):(command_state)list= ({ - input_units = (List.rev_append (List.rev state1.input_units) ((match state1.current_group with - Some l -> [Group(l)] - | None -> failwith "end group without start group" - ))) - ; link_options = (state1.link_options) - ; current_input_options = (state1.current_input_options) - ; current_group = None - } :: more) - -type option_token = string -type option_argspecs = string list * string list -type option_argvals = string list * string list - -(*val set_or_replace_option : link_option -> list command_state -> list command_state*) -let set_or_replace_option opt state_list:(command_state)list= - ((match state_list with - [] -> failwith "error: no state" - | state1 :: more -> - { input_units = (state1.input_units) - ; link_options = (Pset.add opt (Pset.filter (fun existing -> ((fun opt1 -> (fun opt2 -> not ( ((fun opt1 -> - (fun opt2 -> - (match (opt1, opt2) with - | (OutputFilename(_), OutputFilename(_)) -> true - | (ForceCommonDefined(_), ForceCommonDefined(_)) -> true - | (Soname(_), Soname(_)) -> true - | (EntryAddress(_), EntryAddress(_)) -> true - | _ -> false - ) - ))opt1 opt2)))) existing opt)) state1.link_options)) - ; current_input_options = (state1.current_input_options) - ; current_group = (state1.current_group) - } :: more - )) - -(*val find_option_matching_tag : link_option -> set link_option -> maybe link_option*) -let rec find_option_matching_tag tag options:(link_option)option= - (Lem_list.list_find_opt (tagEqual tag) (Pset.elements options)) - -(*val extract_hex_addend : char -> maybe natural*) -let extract_hex_addend x:(Nat_big_num.num)option= - (if x = '0' then - Some(Nat_big_num.of_int 0) - else if x = '1' then - Some(Nat_big_num.of_int 1) - else if x = '2' then - Some(Nat_big_num.of_int 2) - else if x = '3' then - Some(Nat_big_num.of_int 3) - else if x = '4' then - Some(Nat_big_num.of_int 4) - else if x = '5' then - Some(Nat_big_num.of_int 5) - else if x = '6' then - Some(Nat_big_num.of_int 6) - else if x = '7' then - Some(Nat_big_num.of_int 7) - else if x = '8' then - Some(Nat_big_num.of_int 8) - else if x = '9' then - Some(Nat_big_num.of_int 9) - else if x = 'a' then - Some(Nat_big_num.of_int 10) - else if x = 'b' then - Some(Nat_big_num.of_int 11) - else if x = 'c' then - Some(Nat_big_num.of_int 12) - else if x = 'd' then - Some(Nat_big_num.of_int 13) - else if x = 'e' then - Some(Nat_big_num.of_int 14) - else if x = 'f' then - Some(Nat_big_num.of_int 15) - else - None) - -(*val accumulate_hex_chars : natural -> list char -> natural*) -let rec accumulate_hex_chars acc chars:Nat_big_num.num= - ((match chars with - | [] -> acc - | x::xs -> - (match extract_hex_addend x with - | None -> acc - | Some addend -> - accumulate_hex_chars ( Nat_big_num.add (Nat_big_num.mul acc(Nat_big_num.of_int 16)) addend) xs - ) - )) - -(*val extract_dec_addend : char -> maybe natural*) -let extract_dec_addend x:(Nat_big_num.num)option= - (if x = '0' then - Some(Nat_big_num.of_int 0) - else if x = '1' then - Some(Nat_big_num.of_int 1) - else if x = '2' then - Some(Nat_big_num.of_int 2) - else if x = '3' then - Some(Nat_big_num.of_int 3) - else if x = '4' then - Some(Nat_big_num.of_int 4) - else if x = '5' then - Some(Nat_big_num.of_int 5) - else if x = '6' then - Some(Nat_big_num.of_int 6) - else if x = '7' then - Some(Nat_big_num.of_int 7) - else if x = '8' then - Some(Nat_big_num.of_int 8) - else if x = '9' then - Some(Nat_big_num.of_int 9) - else - None) - -(*val accumulate_dec_chars : natural -> list char -> natural*) -let rec accumulate_dec_chars acc chars:Nat_big_num.num= - ((match chars with - | [] -> acc - | x::xs -> - (match extract_dec_addend x with - | None -> acc - | Some addend -> - accumulate_hex_chars ( Nat_big_num.add (Nat_big_num.mul acc(Nat_big_num.of_int 16)) addend) xs - ) - )) - -(*val parse_address : string -> natural*) -let parse_address s:Nat_big_num.num= ((match Xstring.explode s with - '0' :: 'x' :: more -> accumulate_hex_chars(Nat_big_num.of_int 0) more - | chars -> accumulate_dec_chars(Nat_big_num.of_int 0) chars -)) - -type option_def = ( option_token list) * option_argspecs * (option_argvals -> command_state list -> command_state list) * string - -(* the table is a list of: ... options and their arg names ... and the option's meaning as a function... and a help string *) -(*val command_line_table : list option_def*) -let command_line_table:((string)list*((string)list*(string)list)*((string)list*(string)list ->(command_state)list ->(command_state)list)*string)list= ([ - (* per-input options *) - (["-b"; "--format"], (["TARGET"], []), (fun args -> (fun state1 -> state1)), "Specify target for following input files"); - (["-L"; "--library-path"], (["DIRECTORY"], []), (fun args -> (fun state1 -> state1)), "Add DIRECTORY to library search path"); - (["--as-needed"], ([], []), (fun _ -> (fun state1 -> state1)), "Only set DT_NEEDED for following dynamic libs if used"); - (["--no-as-needed"], ([], []), (fun _ -> (fun state1 -> state1)), "Always set DT_NEEDED for dynamic libraries mentioned on the command line"); - (["-Bdynamic"; "-dy"; "-call_shared"], ([], []), (fun _ -> (fun state1 -> state1)), "Link against shared libraries"); - (["-Bstatic"; "-dn"; "-non_shared"; "-static"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not link against shared libraries"); - (["--check-sections"], ([], []), (fun _ -> (fun state1 -> state1)), "Check section addresses for overlaps (default) **srk** not sure it's per-input!"); - (["--no-check-sections"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not check section addresses for overlaps **srk** not sure it's per-input!"); - (["--copy-dt-needed-entries"], ([], []), (fun _ -> (fun state1 -> state1)), "Copy DT_NEEDED links mentioned inside DSOs that follow"); - (["--no-copy-dt-needed-entries"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not copy DT_NEEDED links mentioned inside DSOs that follow"); - (["--no-whole-archive"], ([], []), (fun _ -> (fun state1 -> state1)), "Turn off --whole-archive"); - (["-rpath-link"], (["PATH"], []), (fun _ -> (fun state1 -> state1)), "Set link time shared library search path **srk** not sure it's per-input!"); - (["--whole-archive"], ([], []), (fun _ -> (fun state1 -> state1)), "Include all objects from following archives"); - (* linker plugin control *) - (["-plugin"], (["PLUGIN"], []), (fun _ -> (fun state1 -> state1)), "Load named plugin"); - (["-plugin-opt"], (["ARG"], []), (fun _ -> (fun state1 -> state1)), "Send arg to last-loaded plugin"); - (* output / whole-job options (some may be repeated with different args, but most not): *) - (["-A"; "--architecture"], (["ARCH"], []), (fun _ -> (fun state1 -> state1)), "Set architecture"); - (["-EB"], ([], []), (fun _ -> (fun state1 -> state1)), "Link big-endian objects"); - (["-EL"], ([], []), (fun _ -> (fun state1 -> state1)), "Link little-endian objects"); - (["-R"; "--just-symbols"], (["DIR"], []), (fun _ -> (fun state1 -> state1)), "**srk** (if directory, same as --rpath)"); - (["-d"; "-dc"; "-dp"], ([], []), (fun _ -> (fun state1 -> state1)), "Force common symbols to be defined"); - (["-e"; "--entry"], (["ADDRESS"], []), (fun _ -> (fun state1 -> state1)), "Set start address"); - (["-E"; "--export-dynamic"], ([], []), (fun _ -> (fun state1 -> state1)), "Export all dynamic symbols"); - (["--no-export-dynamic"], ([], []), (fun _ -> (fun state1 -> state1)), "Undo the effect of --export-dynamic"); - (["-f"; "--auxiliary"], (["SHLIB"], []), (fun _ -> (fun state1 -> state1)), "Auxiliary filter for shared object symbol table"); - (["-F"; "--filter"], (["SHLIB"], []), (fun _ -> (fun state1 -> state1)), "Filter for shared object symbol table"); - (["-G"; "--gpsize"], (["SIZE"], []), (fun _ -> (fun state1 -> state1)), "Small data size (if no size, same as --shared) **srk NOTE this quirk!**"); - (["-h"; "-soname"], (["FILENAME"], []), (fun _ -> (fun state1 -> state1)), "Set internal name of shared library"); - (["-I"; "--dynamic-linker"], (["PROGRAM"], []), (fun _ -> (fun state1 -> state1)), "Set PROGRAM as the dynamic linker to use"); - (["--sysroot="], ([], ["DIRECTORY"]), (fun _ -> (fun state1 -> state1)), "Override the default sysroot location"); - (["-m"], (["EMULATION"], []), (fun _ -> (fun state1 -> state1)), "Set emulation"); - (["-n"; "--nmagic"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not page align data"); - (["-N"; "--omagic"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not page align data, do not make text readonly"); - (["--no-omagic"], ([], []), (fun _ -> (fun state1 -> state1)), "Page align data, make text readonly"); - (["-o"; "--output"], (["FILE"], []), (fun argvals -> set_or_replace_option (OutputFilename(List.hd (fst argvals)))), "Set output file name"); - (["-O"], ([], []), (fun _ -> (fun state1 -> state1)), "Optimise output file"); - (["-q"; "--emit-relocs"], ([], []), (fun _ -> (fun state1 -> state1)), "Generate relocations in final output"); - (["-r"; "-i"; "--relocatable"], ([], []), (fun _ -> (fun state1 -> state1)), "Generate relocatable output"); - (["-s"; "--strip-all"], ([], []), (fun _ -> (fun state1 -> state1)), "Strip all symbols"); - (["-S"; "--strip-debug"], ([], []), (fun _ -> (fun state1 -> state1)), "Strip debugging symbols"); - (["--strip-discarded"], ([], []), (fun _ -> (fun state1 -> state1)), "Strip symbols in discarded sections"); - (["--no-strip-discarded"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not strip symbols in discarded sections"); - (["--default-script"; "-dT"], (["FILE"], []), (fun _ -> (fun state1 -> state1)), "Read default linker script"); - (["--unique="], ([], ["SECTION"]), (fun _ -> (fun state1 -> state1)), "Don't merge input [SECTION | orphan] sections"); - (["-Ur"], ([], []), (fun _ -> (fun state1 -> state1)), "Build global constructor/destructor tables ( **srk**: like -r, but... )"); - (["-x"; "--discard-all"], ([], []), (fun _ -> (fun state1 -> state1)), "Discard all local symbols"); - (["-X"; "--discard-locals"], ([], []), (fun _ -> (fun state1 -> state1)), "Discard temporary local symbols (default)"); - (["--discard-none"], ([], []), (fun _ -> (fun state1 -> state1)), "Don't discard any local symbols"); - (["-Bsymbolic"], ([], []), (fun argvals -> (fun state1 -> set_or_replace_option BindFunctionsEarly (set_or_replace_option BindNonFunctionsEarly state1))), "Bind global references locally"); - (["-Bsymbolic-functions"], ([], []), (fun argvals -> set_or_replace_option (BindFunctionsEarly)), "Bind global function references locally"); - (["--force-exe-suffix"], ([], []), (fun _ -> (fun state1 -> state1)), "Force generation of file with .exe suffix"); - (["--gc-sections"], ([], []), (fun _ -> (fun state1 -> state1)), "**srk: uncertain: can repeat?** Remove unused sections (on some targets)"); - (["--no-gc-sections"], ([], []), (fun _ -> (fun state1 -> state1)), "**srk: uncertain: can repeat?** Don't remove unused sections (default)"); - (["--hash-size="], ([], ["NUMBER"]), (fun _ -> (fun state1 -> state1)), "Set default hash table size close to <NUMBER>"); - (["--no-define-common"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not define Common storage"); - (["--no-undefined"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not allow unresolved references in object files"); - (["--allow-shlib-undefined"], ([], []), (fun _ -> (fun state1 -> state1)), "Allow unresolved references in shared libraries"); - (["--no-allow-shlib-undefined"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not allow unresolved references in shared libs"); - (["--default-symver"], ([], []), (fun _ -> (fun state1 -> state1)), "Create default symbol version"); - (["--default-imported-symver"], ([], []), (fun _ -> (fun state1 -> state1)), "Create default symbol version for imported symbols"); - (["-nostdlib"], ([], []), (fun _ -> (fun state1 -> state1)), "Only use library directories specified on the command line"); - (["--oformat"], (["TARGET"], []), (fun _ -> (fun state1 -> state1)), "Specify target of output file"); - (["--relax"], ([], []), (fun _ -> (fun state1 -> state1)), "Reduce code size by using target specific optimisations"); - (["--no-relax"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not use relaxation techniques to reduce code size"); - (["--retain-symbols-file"], (["FILE"], []), (fun _ -> (fun state1 -> state1)), "Keep only symbols listed in FILE"); - (["-rpath"], (["PATH"], []), (fun _ -> (fun state1 -> state1)), "Set runtime shared library search path"); - (["-shared"; "-Bshareable"], ([], []), (fun argvals -> set_or_replace_option (OutputKind(SharedLibrary))), "Create a shared library"); - (["-pie"; "--pic-executable"], ([], []), (fun _ -> (fun state1 -> state1)), "Create a position independent executable"); - (["--sort-common="],(* (ascending|descending) *)([], ["order"]), (fun _ -> (fun state1 -> state1)), "Sort common symbols by alignment [in specified order]"); - (["--sort-section="],(* (name|alignment) *) ([], ["key"]), (fun _ -> (fun state1 -> state1)), "Sort sections by name or maximum alignment"); - (["--spare-dynamic-tags"], (["COUNT"], []), (fun _ -> (fun state1 -> state1)), "How many tags to reserve in .dynamic section"); - (["--split-by-file="], ([], ["SIZE"]), (fun _ -> (fun state1 -> state1)), "Split output sections every SIZE octets"); - (["--split-by-reloc="], ([], ["COUNT"]), (fun _ -> (fun state1 -> state1)), "Split output sections every COUNT relocs"); - (["--traditional-format"], ([], []), (fun _ -> (fun state1 -> state1)), "Use same format as native linker"); - (["--unresolved-symbols="], ([], ["method"]), (fun _ -> (fun state1 -> state1)), "How to handle unresolved symbols. <method> is: ignore-all, report-all, ignore-in-object-files, ignore-in-shared-libs"); - (["--dynamic-list-data"], ([], []), (fun _ -> (fun state1 -> state1)), "Add data symbols to dynamic list"); - (["--dynamic-list-cpp-new"], ([], []), (fun _ -> (fun state1 -> state1)), "Use C++ operator new/delete dynamic list"); - (["--dynamic-list-cpp-typeinfo "], ([], []), (fun _ -> (fun state1 -> state1)), "Use C++ typeinfo dynamic list"); - (["--dynamic-list"], (["FILE"], []), (fun _ -> (fun state1 -> state1)), "Read dynamic list"); - (["--wrap"], (["SYMBOL"], []), (fun _ -> (fun state1 -> state1)), "Use wrapper functions for SYMBOL"); - (* the following are specific to ELF emulations *) - (["--audit=(.*)"], ([], ["AUDITLIB"]), (fun _ -> (fun state1 -> state1)), "Specify a library to use for auditing"); - (["-Bgroup"], ([], []), (fun _ -> (fun state1 -> state1)), "Selects group name lookup rules for DSO"); - (["--build-id="], ([], ["STYLE"]), (fun _ -> (fun state1 -> state1)), "Generate build ID note"); - (["-P"], (["AUDITLIB"], []), (fun _ -> (fun state1 -> state1)), "Specify a library to use for auditing dependencies"); - (["--depaudit="], ([], ["AUDITLIB"]), (fun _ -> (fun state1 -> state1)), "Specify a library to use for auditing dependencies"); - (["--disable-new-dtags"], ([], []), (fun _ -> (fun state1 -> state1)), "Disable new dynamic tags"); - (["--enable-new-dtags"], ([], []), (fun _ -> (fun state1 -> state1)), "Enable new dynamic tags"); - (["--eh-frame-hdr"], ([], []), (fun _ -> (fun state1 -> state1)), "Create .eh_frame_hdr section"); - (["--exclude-libs="], ([], ["LIBS"]), (fun _ -> (fun state1 -> state1)), "Make all symbols in LIBS hidden"); - (["--hash-style="], ([], ["STYLE"]), (fun _ -> (fun state1 -> state1)), "Set hash style to sysv, gnu or both"); - (* NOTE: for these to work, we hack our word-splitter to merge -z options into a single word with a single space in *) - (["-z combreloc"], ([], []), (fun _ -> (fun state1 -> state1)), "Merge dynamic relocs into one section and sort"); - (["-z common-page-size="], ([], ["SIZE"]), (fun _ -> (fun state1 -> state1)), "Set common page size to SIZE"); - (["-z defs"], ([], []), (fun _ -> (fun state1 -> state1)), "Report unresolved symbols in object files."); - (["-z execstack"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark executable as requiring executable stack"); - (["-z global"], ([], []), (fun _ -> (fun state1 -> state1)), "Make symbols in DSO available for subsequently loaded objects"); - (["-z initfirst"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark DSO to be initialized first at runtime"); - (["-z interpose"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark object to interpose all DSOs but executable"); - (["-z lazy"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark object lazy runtime binding (default)"); - (["-z loadfltr"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark object requiring immediate process"); - (["-z max-page-size="], ([], ["SIZE"]), (fun _ -> (fun state1 -> state1)), "Set maximum page size to SIZE"); - (["-z nocombreloc"], ([], []), (fun _ -> (fun state1 -> state1)), "Don't merge dynamic relocs into one section"); - (["-z nocopyreloc"], ([], []), (fun _ -> (fun state1 -> state1)), "Don't create copy relocs"); - (["-z nodefaultlib"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark object not to use default search paths"); - (["-z nodelete"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark DSO non-deletable at runtime"); - (["-z nodlopen"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark DSO not available to dlopen"); - (["-z nodump"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark DSO not available to dldump"); - (["-z noexecstack"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark executable as not requiring executable stack"); - (["-z norelro"], ([], []), (fun _ -> (fun state1 -> state1)), "Don't create RELRO program header"); - (["-z now"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark object non-lazy runtime binding"); - (["-z origin"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark object requiring immediate $ORIGIN processing at runtime"); - (["-z relro"], ([], []), (fun _ -> (fun state1 -> state1)), "Create RELRO program header"); - (["-z stacksize="], ([], ["SIZE"]), (fun _ -> (fun state1 -> state1)), "Set size of stack segment"); - (["-z bndplt"], ([], []), (fun _ -> (fun state1 -> state1)), "Always generate BND prefix in PLT entries"); - (["--ld-generated-unwind-info"], ([], []), (fun _ -> (fun state1 -> state1)), "Generate exception handling info for PLT."); - (["--no-ld-generated-unwind-info"], ([], []), (fun _ -> (fun state1 -> state1)), "Don't do so."); - (* quasi-input options (can be repeated): *) - (["-c"; "--mri-script"], (["FILE"], []), (fun _ -> (fun state1 -> state1)), "Read MRI format linker script"); - (["-l"; "--library"], (["LIBNAME"], []), (fun _ -> (fun state1 -> state1)), "Search for library LIBNAME"); - (* (["-R" ,"--just-symbols"], (["FILE"], []), fun _ -> (fun state -> state), "Just link symbols"), *) (* Handled above! *) - (["-T"; "--script"], (["FILE"], []), (fun _ -> (fun state1 -> state1)), "Read linker script"); - (["-u"; "--undefined"], (["SYMBOL"], []), (fun _ -> (fun state1 -> state1)), "Start with undefined reference to SYMBOL"); - (["-("; "--start-group"], ([], []), (fun _ -> (fun state1 -> start_group state1)), "Start a group"); - (["-)"; "--end-group"], ([], []), (fun _ -> (fun state1 -> end_group state1)), "End a group"); - (["--defsym"], (["SYMBOL=EXPRESSION"], []), (fun _ -> (fun state1 -> state1)), "Define a symbol"); - (["-fini"], (["SYMBOL"], []), (fun _ -> (fun state1 -> state1)), "Call SYMBOL at unload-time"); - (["-init"], (["SYMBOL"], []), (fun _ -> (fun state1 -> state1)), "Call SYMBOL at load-time"); - (["--section-start"], (["SECTION=ADDRESS"], []), (fun _ -> (fun state1 -> state1)), "Set address of named section"); - (["-Tbss"], (["ADDRESS"], []), (fun _ -> (fun state1 -> state1)), "Set address of .bss section"); - (["-Tdata"], (["ADDRESS"], []), (fun _ -> (fun state1 -> state1)), "Set address of .data section"); - (["-Ttext"], (["ADDRESS"], []), (fun _ -> (fun state1 -> state1)), "Set address of .text section"); - (["-Ttext-segment"], (["ADDRESS"], []), (fun argvals -> set_or_replace_option (TextSegmentStart(parse_address (List.hd (fst argvals))))), "Set address of text segment"); - (["-Trodata-segment"], (["ADDRESS"], []), (fun argvals -> set_or_replace_option (RodataSegmentStart(parse_address (List.hd (fst argvals))))), "Set address of rodata segment"); - (["-Tldata-segment"], (["ADDRESS"], []), (fun argvals -> set_or_replace_option (LdataSegmentStart(parse_address (List.hd (fst argvals))))), "Set address of ldata segment"); - (["--version-script"], (["FILE"], []), (fun _ -> (fun state1 -> state1)), "Read version information script"); - (["--version-exports-section"], (["SYMBOL"], []), (fun _ -> (fun state1 -> state1)), "Take export symbols list from .exports, using SYMBOL as the version."); - (* linker internal debugging/diagnostics and performance tuning *) - (["-M"; "--print-map"], ([], []), (fun _ -> (fun state1 -> state1)), "Print map file on standard output"); - (["-t"; "--trace"], ([], []), (fun _ -> (fun state1 -> state1)), "Trace file opens"); - (["-v"; "--version"], ([], []), (fun _ -> (fun state1 -> state1)), "Print version information"); - (["-V"], ([], []), (fun _ -> (fun state1 -> state1)), "Print version and emulation information"); - (["-y"; "--trace-symbol"], (["SYMBOL"], []), (fun _ -> (fun state1 -> state1)), "Trace mentions of SYMBOL"); - (["--cref"], ([], []), (fun _ -> (fun state1 -> state1)), "Output cross reference table"); - (["--demangle="], ([], ["STYLE"]), (fun _ -> (fun state1 -> state1)), "Demangle symbol names [using STYLE]"); - (["--print-gc-sections"], ([], []), (fun _ -> (fun state1 -> state1)), "List removed unused sections on stderr"); - (["--no-print-gc-sections"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not list removed unused sections"); - (["-Map"], (["FILE"], []), (fun _ -> (fun state1 -> state1)), "Write a map file"); - (["-Map="], ([], ["FILE"]), (fun _ -> (fun state1 -> state1)), "Write a map file"); - (["--help"], ([], []), (fun _ -> (fun state1 -> state1)), "Print option help"); - (["--no-keep-memory"], ([], []), (fun _ -> (fun state1 -> state1)), "Use less memory and more disk I/O"); - (["--no-demangle"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not demangle symbol names"); - (["--print-output-format"], ([], []), (fun _ -> (fun state1 -> state1)), "Print default output format"); - (["--print-sysroot"], ([], []), (fun _ -> (fun state1 -> state1)), "Print current sysroot"); - (["--reduce-memory-overheads"], ([], []), (fun _ -> (fun state1 -> state1)), "Reduce memory overheads, possibly taking much longer"); - (["--stats"], ([], []), (fun _ -> (fun state1 -> state1)), "Print memory usage statistics"); - (["--target-help"], ([], []), (fun _ -> (fun state1 -> state1)), "Display target specific options"); - (["--verbose="], ([], ["NUMBER"]), (fun _ -> (fun state1 -> state1)), "Output lots of information during link"); - (* unknown *) - (["--embedded-relocs"], ([], []), (fun _ -> (fun state1 -> state1)), "Generate embedded relocs"); - (["--task-link"], (["SYMBOL"], []), (fun _ -> (fun state1 -> state1)), "Do task level linking"); - (* compatibility *) - (["-a"], (["KEYWORD"], []), (fun _ -> (fun state1 -> state1)), "Shared library control for HP/UX compatibility"); - (["-Y"], (["PATH"], []), (fun _ -> (fun state1 -> state1)), "Default search path for Solaris compatibility"); - (* permissiveness controls (tightening/loosening) *) - (["--accept-unknown-input-arch"], ([], []), (fun _ -> (fun state1 -> state1)), "Accept input files whose architecture cannot be determined"); - (["--no-accept-unknown-input-arch"], ([], []), (fun _ -> (fun state1 -> state1)), "Reject input files whose architecture is unknown"); - (["--fatal-warnings"], ([], []), (fun _ -> (fun state1 -> state1)), "Treat warnings as errors"); - (["--no-fatal-warnings"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not treat warnings as errors (default)"); - (["--allow-multiple-definition"], ([], []), (fun _ -> (fun state1 -> state1)), "Allow multiple definitions"); - (["--no-undefined-version"], ([], []), (fun _ -> (fun state1 -> state1)), "Disallow undefined version"); - (["--noinhibit-exec"], ([], []), (fun _ -> (fun state1 -> state1)), "Create an output file even if errors occur"); - (["--error-unresolved-symbols"], ([], []), (fun _ -> (fun state1 -> state1)), "Report unresolved symbols as errors"); - (["--ignore-unresolved-symbol"], (["SYMBOL"], []), (fun _ -> (fun state1 -> state1)), "Unresolved SYMBOL will not cause an error or warning"); - (* permissiveness, specific to ELF emulation *) - (["-z muldefs"], ([], []), (fun _ -> (fun state1 -> state1)), "Allow multiple definitions"); - (* warnings (enabling/disabling) *) - (["--no-warn-mismatch"], ([], []), (fun _ -> (fun state1 -> state1)), "Don't warn about mismatched input files"); - (["--no-warn-search-mismatch"], ([], []), (fun _ -> (fun state1 -> state1)), "Don't warn on finding an incompatible library"); - (["--warn-common"], ([], []), (fun _ -> (fun state1 -> state1)), "Warn about duplicate common symbols"); - (["--warn-constructors"], ([], []), (fun _ -> (fun state1 -> state1)), "Warn if global constructors/destructors are seen"); - (["--warn-multiple-gp"], ([], []), (fun _ -> (fun state1 -> state1)), "Warn if the multiple GP values are used"); - (["--warn-once"], ([], []), (fun _ -> (fun state1 -> state1)), "Warn only once per undefined symbol"); - (["--warn-section-align"], ([], []), (fun _ -> (fun state1 -> state1)), "Warn if start of section changes due to alignment"); - (["--warn-shared-textrel"], ([], []), (fun _ -> (fun state1 -> state1)), "Warn if shared object has DT_TEXTREL"); - (["--warn-alternate-em"], ([], []), (fun _ -> (fun state1 -> state1)), "Warn if an object has alternate ELF machine code"); - (["--warn-unresolved-symbols"], ([], []), (fun _ -> (fun state1 -> state1)), "Report unresolved symbols as warnings"); - (* meta-options *) - (["--push-state"], ([], []), (fun _ -> (fun state1 -> state1)), "Push state of flags governing input file handling"); - (["--pop-state"], ([], []), (fun _ -> (fun state1 -> state1)), "Pop state of flags governing input file handling") -(*(["@FILE"], [], fun _ -> (fun state -> state), "Read options from FILE") *) (* processed during word-splitting phase *); -]) - -(*val delete_trailing_equals: string -> maybe string*) -let delete_trailing_equals str:(string)option= - (let cs = (Xstring.explode str) - in - if (listEqualBy (=) ['='] (drop0 ( Nat_big_num.sub_nat(length cs)(Nat_big_num.of_int 1)) cs)) - then Some (Xstring.implode ((take0 ( Nat_big_num.sub_nat(length cs)(Nat_big_num.of_int 1)) cs))) - else (* let _ = Missing_pervasives.errln ("No trailing equals: " ^ str) - in *) - None) - -(*val string_following_equals_at : nat -> string -> maybe string*) -let string_following_equals_at pos str:(string)option= - (let (first, second) = (Lem_list.split_at pos (Xstring.explode str)) - in (match second with - '=' :: rest -> Some (Xstring.implode rest) - | _ -> (* let _ = Missing_pervasives.errln ("No trailing equals at " ^ (show pos) ^ ": " ^ str) - in *) - None - )) - -(*val equal_modulo_trailing_equals : string -> string -> bool*) -let equal_modulo_trailing_equals argstr argdef:bool= -( - (* we allow argdef to have a trailing equals; if it does, - * we allow the argstring to have the equals (or not) and trailing stuff, - * which will become an arg *)let result = ((match (delete_trailing_equals argdef) with - Some matched -> - let following_equals = (string_following_equals_at (String.length matched) argstr) - in - (match following_equals with - Some following -> (* okay; does the pre-equals part match? *) - matched = Xstring.implode (Lem_list.take ( Nat_num.nat_monus(String.length argdef)( 1)) (Xstring.explode argstr)) - | _ -> (* the argstr is allowed not to have a trailing equals *) argstr = matched - ) - | None -> (* no trailing equals *) argdef = argstr - )) - in - (* let _ = Missing_pervasives.errln ("Do '" ^ argstr ^ "' and '" ^ argdef ^ "' match modulo trailing equals? " ^ (show result)) - in *) result) - - -(*val matching_arg_and_alias : string -> list option_def -> maybe (string * option_def)*) -let rec matching_arg_and_alias arg options:(string*((string)list*((string)list*(string)list)*(option_argvals ->(command_state)list ->(command_state)list)*string))option= ((match options with - [] -> None - | (aliases, argspec, meaning, doc) :: more_opts -> - (match list_find_opt (fun alias -> equal_modulo_trailing_equals arg alias) aliases with - Some found_alias -> Some (found_alias, (aliases, argspec, meaning, doc)) - | None -> matching_arg_and_alias arg more_opts - ) - )) - -(* We don't try to convert from strings to other things here; - * everything we record is either a bool, meaning option -A was "present", for some A, - * or a string somearg, meaning option -A somearg was present, for some A. *) - -(* The above suffices to understand each concrete argument. - * Now we define an "interpreted command line" that includes - * some useful structure. *) - -(*val read_one_arg : list command_state -> list string -> (list command_state * list string)*) -let read_one_arg state_stack args:(command_state)list*(string)list= -( - (* Get the first string and look it up in our table. *)(match args with - [] -> (state_stack, []) - | some_arg :: more -> (match (matching_arg_and_alias some_arg command_line_table) with - (* We need to handle argdefs that have trailing equals. This means - * an extra arg might follow the equals. We need some helper functions. *) - Some (alias, (aliases, (argspec_extras, argspec_regex), meaning, doc)) -> - (* Return a new state, by applying the argument's meaning. - * We have to supply the option's argument strings to the meaning function. *) - let argstrings = (Lem_list.take (List.length argspec_extras) more) - in - let regex_matches = ((match delete_trailing_equals some_arg with - Some prefix -> - (match (string_following_equals_at ( Nat_num.nat_monus(String.length alias)( 1)) some_arg) with - Some following_equals -> [following_equals] - | None -> failwith "impossible: '=' not where it was a moment ago" - ) - | None -> [] - )) - in - let new_state_stack = (meaning (argstrings, regex_matches) state_stack) - in - (new_state_stack, drop0 (length argspec_extras) more) - | None -> - (* If we didn't match any args, we ought to be an input file. *) - (add_input_file state_stack some_arg, more) - ) - )) - -(* To fold over the command-line arguments we need a fold that passes - * suffixes of the list, not individual elements, and gives us back - * the continuation that we need to fold over: a pair of folded-value, new-list. *) -(*val foldl_suffix : forall 'a 'b. ('a -> list 'b -> ('a * list 'b)) -> 'a -> list 'b -> 'a*) (* originally foldl *) -let rec foldl_suffix f a l:'a= ((match l with - | [] -> a - | x :: xs -> - let (new_a, new_list) = (f a l) - in foldl_suffix f new_a new_list -)) - -(* the word-splitting in argv needs a little fixing up. *) -(*val cook_argv : list string -> list string -> list string*) -let rec cook_argv acc args:(string)list= - ((match args with - [] -> acc - | "-z" :: more -> (match more with - [] -> failwith "-z must be followed by another argument" - | something :: yetmore -> cook_argv ( List.rev_append (List.rev acc) [("-z " ^ something)]) yetmore - ) - | something :: more -> cook_argv ( List.rev_append (List.rev acc) [something]) more - )) - -(*val command_line : unit -> interpreted_command_line*) -let command_line:unit ->(input_unit)list*(link_option)Pset.set= (fun _ -> ( - let cooked_argv = (cook_argv [] (List.tl Ml_bindings.argv_list)) - in - (* Now we use our fold-alike. *) - (match foldl_suffix read_one_arg initial_state0 cooked_argv with - state1 :: rest_of_stack -> (state1.input_units, state1.link_options) - | _ -> failwith "no command state left" - ) -)) |
