package linksem
A formalisation of the core ELF and DWARF file formats written in Lem
Install
Dune Dependency
Authors
Maintainers
Sources
0.8.tar.gz
md5=2075c56715539b3b8f54ae65cc808b8c
sha512=f7c16e4036a1440a6a8d13707a43f0f9f9db0c68489215f948cc300b6a164dba5bf852e58f89503e9d9f38180ee658d9478156ca1a1ef64d6861eec5f9cf43d2
doc/src/linksem_zarith/command_line.ml.html
Source file command_line.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671
(*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 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" ) ))
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>