definition module linker2;

from StdString import String;
from StdFile import Files;

::	*SymbolArray :== SSymbolArray;
::	SSymbolArray :== {!Symbol};

::	Symbol
	= Module !Int !Int !Int !Int !Int !Int !String		// section_n offset length virtual_address file_offset n_relocations relocations
	| Label !Int !Int !Int								// section_n offset module_n
	| SectionLabel !Int !Int							// section_n offset
	| ImportLabel !String								// label_name
	| ImportedLabel !Int !Int 							// file_n symbol_n
	| ImportedLabelPlusOffset !Int !Int !Int			// file_n symbol_noffset
	| ImportedFunctionDescriptor !Int !Int 				// file_n symbol_n
	| EmptySymbol;

::	SymbolIndexList = SymbolIndex !Int !SymbolIndexList | EmptySymbolIndex;

::	*NamesTable :== SNamesTable;
::	SNamesTable :== {!NamesTableElement};

::	NamesTableElement
	= NamesTableElement !String !Int !Int !NamesTableElement	// symbol_name symbol_n file_n symbol_list
	| EmptyNamesTableElement;

::	LibraryList = Library !String !LibrarySymbolsList !Int !LibraryList | EmptyLibraryList;

::	LibrarySymbolsList = LibrarySymbol !String !LibrarySymbolsList | EmptyLibrarySymbolsList;

::	*Xcoff :== *SXcoff;
:: SXcoff ={
		file_name			:: !String,
		symbol_table		:: !.SSymbolTable,
		n_symbols			:: !Int
	};

::	*SymbolTable :== *SSymbolTable;
:: SSymbolTable ={
		text_symbols	:: !SymbolIndexList,
		data_symbols	:: !SymbolIndexList,
		bss_symbols		:: !SymbolIndexList,
		imported_symbols:: !SymbolIndexList,
		section_symbol_ns::!.{#Int},
		symbols			:: !.SSymbolArray
	};

:: XcoffArray :== {#SXcoff};

n_symbols_of_xcoff_list :: !Int ![Xcoff] -> (!Int,![Xcoff]);
imported_library_symbols :: !.LibrarySymbolsList !Int !{#.Bool} -> .[String];
create_coff_file :: !String !Int !Int !Int !Int !Int !Int !Bool !*Files -> (!Bool,!*File,!*Files);

SIZE_OF_HEADER:==20;
SIZE_OF_SECTION_HEADER:==40;
SIZE_OF_SYMBOL:==18;
SIZE_OF_RELOCATION:==10;

C_EXT:==2;
C_FILE:==103;

N_UNDEF:==0;
TEXT_SECTION:==1;
DATA_SECTION:==2;
BSS_SECTION:==3;

REL_DIR32:==6;
REL_REL32:==024;
REL_DUMMY:==0;

sort_modules :: !*SXcoff -> .SXcoff;

create_names_table :: NamesTable;
insert_symbol_in_symbol_table :: !String Int Int !NamesTable -> NamesTable;
find_symbol_in_symbol_table :: !String !NamesTable -> (!NamesTableElement,!NamesTable);

read_library_files :: ![String] Int Int !*Files NamesTable -> (![String],!LibraryList,!Int,!*Files,!NamesTable);
read_symbol_table :: !Int !Int !*File -> (!Bool,!String,!String,!*File);
read_xcoff_file :: !String NamesTable Bool !Files Int -> (![String],!*String,!*String,!Xcoff,!NamesTable,!Files);
empty_xcoff :: .SXcoff;
