implementation module Linker; import StdFile,StdArray,StdClass,StdEnum,StdInt,StdBool,StdChar; from StdMisc import abort; from StdList import ++; from StdString import String,%; import SymbolTable; from ReadObject import ExtFileSystem, read_xcoff_files,read_library_files; // only for PC,read_static_lib_files; from piObjectToDisk import write_object_to_disk; import SymbolTable; //import ObjectToDisk; import ExtString, ExtFile; import PlatformLinkOptions; import LinkerMessages; import UtilStrictLists; import LibraryDynamics; link_xcoff_files :: !Bool ![String] ![String] ![String] !String !PlatformLinkOptions !Files -> (!*State,!Files); link_xcoff_files normal_static_link file_names library_file_names static_libraries application_file_name platform_link_options files // platform independent options #! one_pass_link = True; /* WARNING: The MAC only supports one pass linking. Thus the one_pass_link *must* be set to True. The PC simply ignores the flag. */ #! allow_unused_undefined_symbols = False; // read object files #! (any_extra_sections,read_xcoff_files_errors,sections,n_xcoff_files,xcoff_list,names_table,files) = read_xcoff_files False file_names create_names_table one_pass_link files 0; | not (isEmpty read_xcoff_files_errors) # linker_messages_state = setLinkerMessages [LinkerError e \\ e <- read_xcoff_files_errors] DefaultLinkerMessages; = ({ EmptyState & linker_messages_state = linker_messages_state },files); //; //(read_xcoff_files_errors,files); # platform_link_options = plo_set_sections sections platform_link_options; # platform_link_options = plo_any_extra_sections any_extra_sections platform_link_options; // // | any_extra_sections // = abort "any_extra_sections"; /* only forPC // read static libraries #! (errors,xcoff_list, _, names_table, n_xcoff_files, files) = read_static_lib_files static_libraries [] names_table n_xcoff_files xcoff_list files; | not (isEmpty errors) # linker_messages_state = setLinkerMessages [LinkerError e \\ e <- errors] DefaultLinkerMessages; = ({ EmptyState & linker_messages_state = linker_messages_state },files); */ // read dynamic libraries #! n_libraries = length library_file_names; (read_library_errors,library_list,n_library_symbols,files,names_table) = read_library_files library_file_names (~n_libraries) 0 files names_table; | not (isEmpty read_library_errors) # linker_messages_state = setLinkerMessages [LinkerError e \\ e <- read_library_errors] DefaultLinkerMessages; = ({ EmptyState & linker_messages_state = linker_messages_state },files); // resolve symbolic references by name #! (undefined_symbols,xcoff_list,names_table) = import_symbols_in_xcoff_files xcoff_list 0 [] names_table; | not (isEmpty undefined_symbols) && not allow_unused_undefined_symbols # linker_messages_state = setLinkerMessages [LinkerError ("Undefined symbol: " +++ symbol_name) \\ (symbol_name,_,_)<-undefined_symbols] DefaultLinkerMessages; = ({ EmptyState & linker_messages_state = linker_messages_state },files); // check for the existence of main entry and any exported symbols # (main_entry_found,main_file_n,main_symbol_n, // main entry all_exported_symbols_found,entry_datas, // exported symbols (found,symbol_name,file_n,symbol_n) names_table, // names table platform_link_options) = find_root_symbols names_table platform_link_options; | not main_entry_found || not all_exported_symbols_found # undefined_main_entry = case main_entry_found of { True -> []; False -> ["Symbol \"main\" is not defined"]; }; # undefined_exported_entries = case all_exported_symbols_found of { True -> []; False -> [ ("Exported symbol \"" +++ name +++ "\" is not defined.") \\ (found,name,file_n,symbol_n) <- entry_datas | not found ]; }; # linker_messages_state = setLinkerMessages [LinkerError e \\ e <- (undefined_main_entry ++ undefined_exported_entries)] DefaultLinkerMessages; = ({ EmptyState & linker_messages_state = linker_messages_state },files); # platform_link_options = plo_set_main_file_n_and_symbol_n main_file_n main_symbol_n platform_link_options // mark only used symbols # root_entries = [(True,"",main_file_n,main_symbol_n) : entry_datas]; #! (unused_undefined_symbols,n_xcoff_symbols,marked_bool_a,marked_offset_a,xcoff_a,names_table) = mark_modules_list [] xcoff_list n_xcoff_files n_libraries n_library_symbols library_list root_entries names_table; | not (isEmpty undefined_symbols) # linker_messages_state = setLinkerMessages [LinkerError ("unused undefined symbol " +++ e) \\ e <- unused_undefined_symbols] DefaultLinkerMessages; = ({ EmptyState & linker_messages_state = linker_messages_state },files); /* // PC; should be built-in // remove garbage from symbol table (only for static linker) #! (marked_bool_a,xcoff_a) = case normal_static_link of { True -> remove_garbage_from_symbol_table 0 n_xcoff_files 0 marked_bool_a xcoff_a; False -> (marked_bool_a,xcoff_a); }; */ /* // MAC; Xcoff-executable should be built-in # (sections,platform_link_options) = plo_get_sections platform_link_options; # (ok,pef_application_size,files) = case /*generate_xcoff*/ False of { False -> write_pef_file application_file_name n_xcoff_files n_libraries n_library_symbols library_list main_symbol_n main_file_n one_pass_link sections n_xcoff_symbols marked_bool_a marked_offset_a xcoff_a files; /* uniek maken True -> write_xcoff_file application_file_name n_xcoff_files n_libraries n_library_symbols library_list main_symbol_n main_file_n one_pass_link sections n_xcoff_symbols marked_bool_a marked_offset_a xcoff_a files; //abort "link_xcoff_files: a xcoff executable not supported"; */ }; */ // create state #! state = { EmptyState & // misc one_pass_link = one_pass_link , normal_static_link = normal_static_link // linker tables , application_name = application_file_name , n_libraries = n_libraries , n_xcoff_files = n_xcoff_files , n_xcoff_symbols = n_xcoff_symbols , n_library_symbols = n_library_symbols , marked_bool_a = marked_bool_a , marked_offset_a = marked_offset_a // , module_offset_a :: !*{#Int} , xcoff_a = xcoff_a , namestable = names_table // dynamic libraries , library_list = library_list , library_file_names = if normal_static_link [] (strip_paths_from_file_names library_file_names) // , pd_state :: !*PDState }; #! (state,platform_link_options,files) = case (normal_static_link || (not normal_static_link && not dynamics)) of { True #! (state,platform_link_options,files) = write_object_to_disk platform_link_options state files; /* #! (/*ok,*/state,platform_link_options,files) = write_object_to_disk normal_static_link application_file_name n_xcoff_files n_libraries n_library_symbols library_list n_xcoff_symbols marked_bool_a marked_offset_a xcoff_a files names_table platform_link_options; */ // check for link errors during generation #! (ok,state) = IsErrorOccured state; #! (_,_,state,platform_link_options,files) = case ok of { True -> post_process state platform_link_options files; False -> (False,[],state,platform_link_options,files); }; -> (state,platform_link_options,files); False /* #! warning = LinkerWarning "Using library approach to dynamics" #! state = AddMessage warning state; */ // plo_set_console_window -> build_type_and_code_library file_names library_file_names static_libraries application_file_name state platform_link_options files; }; = (state,files);