implementation module LinkerOffsets; import StdEnv; import DebugUtilities; from Offsets import Remove_at_size; import SymbolTable; /* Remove_at_size :: !String -> !String; Remove_at_size s = remove_at_size_i (size s-1); { remove_at_size_i -1 = s; remove_at_size_i i | s.[i]<>'@' = remove_at_size_i (i-1); = s % (0,i-1) +++t; { t :: {#Char}; t = createArray (size s-i) '\0'; } } */ :: *ModuleOffsets :== *{#Int}; compute_module_offsets :: SymbolIndexListKind Int [*Xcoff] Int Int *{#Bool} ModuleOffsets -> (*{#Bool},!Int,!ModuleOffsets,![*Xcoff]); compute_module_offsets _ _ [] offset0 file_symbol_index marked_bool_a module_offsets0 = (marked_bool_a, offset0,module_offsets0, []); compute_module_offsets kind base [xcoff=:{n_symbols,symbol_table=symbol_table=:{text_symbols,data_symbols,bss_symbols,symbols}}:xcoff_list] offset0 file_symbol_index marked_bool_a module_offsets0 # (marked_bool_a,offset1,symbols, module_offsets1) = compute_section_module_offsets base file_symbol_index marked_bool_a (select_kind kind) symbols offset0 module_offsets0; (marked_bool_a,offset,module_offsets, xcoff_list) = compute_module_offsets kind base xcoff_list offset1 (file_symbol_index+n_symbols) marked_bool_a module_offsets1; = (marked_bool_a,offset,module_offsets,[{xcoff & symbol_table={symbol_table & symbols=symbols}}:xcoff_list]); { select_kind :: !SymbolIndexListKind -> !SymbolIndexList; select_kind Text = text_symbols; select_kind Data = data_symbols; select_kind Bss = bss_symbols; }; compute_module_offsets_for_user_defined_sections :: {#Char} Int !*[*Xcoff] Int Int *{#Bool} *{#Int} -> *(.{#Bool},Int,*{#Int},[.Xcoff]); compute_module_offsets_for_user_defined_sections _ _ [] offset0 file_symbol_index marked_bool_a module_offsets0 = (marked_bool_a, offset0,module_offsets0, []); compute_module_offsets_for_user_defined_sections kind base [xcoff=:{n_symbols,symbol_table=symbol_table=:{extra_sections,symbols}}:xcoff_list] offset0 file_symbol_index marked_bool_a module_offsets0 # (marked_bool_a,offset1,symbols, module_offsets1) = compute_section_module_offsets base file_symbol_index marked_bool_a (select_kind kind) symbols offset0 module_offsets0; (marked_bool_a,offset,module_offsets, xcoff_list) = compute_module_offsets_for_user_defined_sections kind base xcoff_list offset1 (file_symbol_index+n_symbols) marked_bool_a module_offsets1; = (marked_bool_a,offset,module_offsets,[{xcoff & symbol_table={symbol_table & symbols=symbols}}:xcoff_list]); { select_kind :: !String -> !SymbolIndexList; select_kind user_section_name #! extra_section = filter (\{es_name} -> user_section_name == es_name) extra_sections; | isEmpty extra_section = EmptySymbolIndex; = (hd extra_section).es_symbols; } compute_section_module_offsets :: Int Int *{#Bool} SymbolIndexList *SymbolArray Int ModuleOffsets -> (*{#Bool},!Int,!*SymbolArray,!ModuleOffsets); compute_section_module_offsets _ file_symbol_index marked_bool_a EmptySymbolIndex symbol_array offset0 module_offsets0 = (marked_bool_a,offset0,symbol_array,module_offsets0 ); compute_section_module_offsets base file_symbol_index marked_bool_a (SymbolIndex module_n symbol_list) symbol_array=:{[module_n]=module_symbol} offset0 module_offsets0 | not marked_bool_a.[file_symbol_index+module_n] = compute_section_module_offsets base file_symbol_index marked_bool_a symbol_list symbol_array offset0 module_offsets0; # (offset1,module_offsets1)=compute_module_offset base module_symbol module_n offset0 file_symbol_index module_offsets0; = compute_section_module_offsets base file_symbol_index marked_bool_a symbol_list symbol_array offset1 module_offsets1; compute_module_offset :: Int Symbol Int Int Int ModuleOffsets -> (!Int,!ModuleOffsets); compute_module_offset 0 (Module _ length _ _ _ _) module_n offset0 file_symbol_index module_offsets0 = (aligned_offset0+length,{module_offsets0 & [file_symbol_index+module_n] = aligned_offset0}); { aligned_offset0=(offset0+alignment_mask) bitand (bitnot alignment_mask); alignment_mask=dec (1< .b; // E a b = b; compute_imported_library_symbol_offsets :: !LibraryList !Int !Int !Int !Int !*{#Bool} !*{#Int} -> (!*{#Bool},!LibraryList,!Int,!Int,!*{#Int}); compute_imported_library_symbol_offsets EmptyLibraryList text_offset0 thunk_data_offset0 n_libraries symbol_n marked_bool_a module_offset_a0 = (marked_bool_a,EmptyLibraryList,text_offset0,thunk_data_offset0,module_offset_a0); compute_imported_library_symbol_offsets (Library library_name _ library_symbols n_symbols library_list0) text_offset0 thunk_data_offset0 n_libraries symbol_n marked_bool_a module_offset_a0 # (marked_bool_a,imported_symbols,text_offset1,thunk_data_offset1,module_offset_a1) = compute_library_symbol_offsets library_symbols symbol_n text_offset0 thunk_data_offset0 marked_bool_a module_offset_a0; # (marked_bool_a,library_list1,text_offset2,thunk_data_offset2,module_offset_a2) = compute_imported_library_symbol_offsets library_list0 text_offset1 thunk_data_offset1 (inc n_libraries) (symbol_n+n_symbols) marked_bool_a module_offset_a1; n_imported_symbols = (text_offset1-text_offset0) / 6; = (marked_bool_a,Library library_name 0 imported_symbols n_imported_symbols library_list1,text_offset2,thunk_data_offset2,module_offset_a2); { compute_library_symbol_offsets :: LibrarySymbolsList Int Int Int *{#Bool} *{#Int} -> (*{#Bool},!LibrarySymbolsList,!Int,!Int,!*{#Int}); compute_library_symbol_offsets EmptyLibrarySymbolsList symbol_n text_offset0 thunk_data_offset0 marked_bool_a module_offset_a0 = (marked_bool_a,EmptyLibrarySymbolsList,text_offset0,thunk_data_offset0+4,module_offset_a0); compute_library_symbol_offsets (LibrarySymbol symbol_name symbol_list) symbol_n text_offset0 thunk_data_offset0 marked_bool_a module_offset_a0 | marked_bool_a.[symbol_n] = (marked_bool_a1,LibrarySymbol symbol_name imported_symbols,text_offset1,thunk_data_offset1,module_offset_a1); { (marked_bool_a1,imported_symbols,text_offset1,thunk_data_offset1,module_offset_a1) = compute_library_symbol_offsets symbol_list (symbol_n+2) (text_offset0+6) (thunk_data_offset0+4) marked_bool_a {module_offset_a0 & [symbol_n]=text_offset0 ,[symbol_n+1]=thunk_data_offset0 }; } = compute_library_symbol_offsets symbol_list (symbol_n+2) text_offset0 thunk_data_offset0 marked_bool_a module_offset_a0; } /* from DynamicLink import SetCurrentLibrary, StoreLong, GetFuncAddress; Dcompute_imported_library_symbol_offsets :: LibraryList Int Int Int *{#Bool} *{#Int} -> (*{#Bool},!LibraryList,!Int,!*{#Int}); Dcompute_imported_library_symbol_offsets EmptyLibraryList thunk_data_offset0 n_libraries symbol_n marked_bool_a module_offset_a0 = (marked_bool_a,EmptyLibraryList,thunk_data_offset0,module_offset_a0); Dcompute_imported_library_symbol_offsets (Library library_name base_of_client_dll library_symbols n_symbols library_list0) thunk_data_offset0 n_libraries symbol_n marked_bool_a module_offset_a0 #! (ok,library) = SetCurrentLibrary library_name | not ok = abort "Dcompute_imported_library_symbol_offsets: library doesn't exist" # (library,marked_bool_a, /* imported_symbols */ _,thunk_data_offset1,module_offset_a1) = compute_library_symbol_offsets library library_symbols symbol_n thunk_data_offset0 marked_bool_a module_offset_a0; | not (CloseLibrary library) = abort "Dcompute_imported_library_symbol_offsets: error" # (marked_bool_a,library_list1,thunk_data_offset2, module_offset_a2) = Dcompute_imported_library_symbol_offsets library_list0 thunk_data_offset1 (inc n_libraries) (symbol_n+n_symbols) marked_bool_a module_offset_a1; # n_imported_symbols = (thunk_data_offset1-thunk_data_offset0) / 4; = (marked_bool_a, Library library_name base_of_client_dll library_symbols n_symbols/* imported_symbols n_imported_symbols*/ library_list1,thunk_data_offset2,module_offset_a2); {} { compute_library_symbol_offsets :: !*Int LibrarySymbolsList Int Int *{#Bool} *{#Int} -> (!*Int,*{#Bool},!LibrarySymbolsList, !Int,!*{#Int}); compute_library_symbol_offsets library EmptyLibrarySymbolsList symbol_n thunk_data_offset0 marked_bool_a module_offset_a0 = (library,marked_bool_a,EmptyLibrarySymbolsList, thunk_data_offset0 /*+4*/,module_offset_a0); compute_library_symbol_offsets library (LibrarySymbol symbol_name symbol_list) symbol_n thunk_data_offset0 marked_bool_a module_offset_a0 | marked_bool_a.[symbol_n] #! (func_address,library1) = GetFuncAddress (Remove_at_size symbol_name) base_of_client_dll library; # ok = StoreLong (symbol_name) thunk_data_offset0 func_address; | not ok = abort ("Dcompute_imported_library_symbol_offsets: can not store long"); = (library2,marked_bool_a1,LibrarySymbol symbol_name imported_symbols,thunk_data_offset1,module_offset_a1); { (library2,marked_bool_a1,imported_symbols,thunk_data_offset1,module_offset_a1) = compute_library_symbol_offsets library1 symbol_list (symbol_n+2) (thunk_data_offset0+4) marked_bool_a {module_offset_a0 & [symbol_n]= func_address, [symbol_n+1]= thunk_data_offset0 }; } // unmarked symbol = compute_library_symbol_offsets library symbol_list (symbol_n+2) thunk_data_offset0 marked_bool_a module_offset_a0; } E :: !a .b -> .b; E a b = b; CloseLibrary :: !*Int -> !Bool; CloseLibrary _ = code { ccall CloseLibrary "I-I" }; */