/* strip symbol table marked internal references in principle after resolving it. */ strip_symbol_table :: !*State -> (!*{#Bool},!*State); strip_symbol_table state=:{n_xcoff_symbols,n_library_symbols} #! references = createArray (n_xcoff_symbols + n_library_symbols) False; // each unmarked symbol having at least one reference is set to True #! (references,state) = mark_referenced_symbols_in_xcoff 0 0 references state; // mark external definitions #! (names_table,state) = select_namestable state; #! (s_names_table,names_table) = usize names_table; #! (references,names_table,state) = mark_external_definitions 0 s_names_table names_table references state; #! state = update_namestable names_table state; #! (references,state) = remove_unreferenced_symbols 0 0 references state; = (references,state); //abort ("a!" +++ (p 0 (size references) references "" )); //state; // abort "strip_symbol_tab"; /* where { p i limit a s | i == limit = s #! (element,a) = a![i]; = p (inc i) limit a (s +++ (if element "t" "f" )); } */ remove_unreferenced_symbols :: !Int !Int !*{#Bool} !*State -> (!*{#Bool},!*State); remove_unreferenced_symbols file_n first_symbol_n references state=:{n_xcoff_files} | file_n == n_xcoff_files // + n_libraries = (references,state); #! (n_symbols,state) = select_n_symbols file_n state; #! (references,state) = remove_unreferenced_symbols_in_xcoff 0 n_symbols references state; = remove_unreferenced_symbols (inc file_n) (first_symbol_n + n_symbols) references state; where //{ remove_unreferenced_symbols_in_xcoff :: !Int !Int !*{#Bool} !*State -> (!*{#Bool},!*State); remove_unreferenced_symbols_in_xcoff symbol_n n_symbols references state | symbol_n == n_symbols = (references,state); #! (unreferenced_symbol,references) = references![first_symbol_n + symbol_n]; | not unreferenced_symbol = remove_unreferenced_symbols_in_xcoff (inc symbol_n) n_symbols references state; // remove unreferenced symbol //#! state // = update_symbol EmptySymbol file_n symbol_n state; = remove_unreferenced_symbols_in_xcoff (inc symbol_n) n_symbols references state; //= abort "remove_unreferenced_symbols_in_xcoff"; //} mark_external_definitions :: !Int !Int *NamesTable !*{#Bool} !*State -> (!*{#Bool},*NamesTable,!*State); mark_external_definitions i limit names_table references state | i == limit = (references,names_table,state); #! (names_table_elements,names_table) = names_table![i]; #! (references,state) = mark_names_table_elements names_table_elements references state; = mark_external_definitions (inc i) limit names_table references state; where //{ mark_names_table_elements EmptyNamesTableElement references state = (references,state); mark_names_table_elements (NamesTableElement _ symbol_n file_n ntes) references state #! (first_symbol_n,state) = case file_n < 0 of { True -> selacc_so_marked_offset_a file_n state; False -> selacc_marked_offset_a file_n state; } #! references = { references & [first_symbol_n + symbol_n] = True }; = mark_names_table_elements ntes references state; //} mark_referenced_symbols_in_xcoff :: !Int !Int !*{#Bool} !*State -> (!*{#Bool},!*State); mark_referenced_symbols_in_xcoff file_n first_symbol_n references state=:{n_xcoff_files,n_xcoff_symbols,xcoff_a} | /*F (toString file_n)*/ file_n == n_xcoff_files = (references,state); //abort "strip_symbol_table"; // for each symbol it must be known if there are references to it. Initially // there are no references to the symbols. A false in the reference-array // means that for the corresponding symbol, no references exist. /* Purpose: removal of symbols not being used by references */ #! (n_symbols,state) = select_n_symbols file_n state; // #! references // = createArray n_symbols False; // text symbols #! (text_symbols,state) = selacc_text_symbols file_n state; #! (references,state) = mark_referenced_symbols text_symbols references state; // data symbols #! (data_symbols,state) = selacc_data_symbols file_n state; #! (references,state) = mark_referenced_symbols data_symbols references state; // bss symbols #! (bss_symbols,state) = selacc_data_symbols file_n state; #! (references,state) = mark_referenced_symbols bss_symbols references state; #! s = (p 0 (size references) references ""); // | True // = abort (p 0 (size references) references ""); //(toString (size references)); = mark_referenced_symbols_in_xcoff (inc file_n) (first_symbol_n + n_symbols) references state; where //{ mark_referenced_symbols :: SymbolIndexList *{#Bool} !*State -> (*{#Bool},!*State); mark_referenced_symbols EmptySymbolIndex references state = (references,state); mark_referenced_symbols (SymbolIndex module_n sils) references state #! (marked_module_symbol,state) = selacc_marked_bool_a (first_symbol_n + module_n) state; | marked_module_symbol // references from marked symbols do not count anymore because // these have already been resolved; from the point of view of // the marked module these could already have been thrown out. // Thus the reference-array remains unchanged. = mark_referenced_symbols sils references state; // a unmarked module may contain references to other symbols. #! (Module _ _ _ _ _ n_relocations relocations,state) = sel_symbol file_n module_n state; #! (references,state) = mark_references 0 n_relocations references relocations state; = mark_referenced_symbols sils references state; where //{ mark_references relocation_n n_relocations references relocations state | relocation_n == n_relocations = (references,state); #! (marked_relocation_symbol,state) = selacc_marked_bool_a (first_symbol_n + relocation_symbol_n) state; | marked_relocation_symbol = mark_references (inc relocation_n) n_relocations references relocations state; #! (at_least_one_reference,references) = references![first_symbol_n + relocation_symbol_n]; | at_least_one_reference = mark_references (inc relocation_n) n_relocations references relocations state; #! references = { references & [first_symbol_n + relocation_symbol_n] = True }; = mark_references (inc relocation_n) n_relocations references relocations state; where //{ relocation_symbol_n=relocations ILONG (relocation_index+4); relocation_index=relocation_n * SIZE_OF_RELOCATION; //} // } //}