implementation module pdReadState;

// winOS

import SymbolTable;
import ReadWriteState;
import ExtFile;

read_xcoff :: !String !Int !{#*Xcoff} !*File -> !(!{#*Xcoff},!*File);
read_xcoff state_file_name i xcoff_a input
	// read file_name
	#! (_,s_object_file_name,input)
		= freadi input;
	#! (object_file_name,input)
		= freads input s_object_file_name;

//  OLD:
//	#! file_name
//		= state_file_name;
	#! file_name
		= debug_complement state_file_name { c \\ c <-: object_file_name } ;
	
		
	// read symbol_table
	#! (symbol_table,input)
		= read_symbol_table input;
		
	// read n_symbols
	#! (_,n_symbols,input)
		= freadi input;
	
	// update xcoff_a
	#! xcoff
		= { Xcoff |
			module_name		= extract_module_name object_file_name 
		,	file_name		= file_name
		,	symbol_table	= symbol_table
		,	n_symbols		= n_symbols
		};
	= ({xcoff_a & [i] = xcoff},input);
where {
	read_symbol_table input
		// read {text,data,bss,imported} symbols
		#! (text_symbols,input)
			= read_symbol_index_list input;
		#! (data_symbols,input)
			= read_symbol_index_list input;
		#! (bss_symbols,input)
			= read_symbol_index_list input;
		#! (imported_symbols,input)
			= read_symbol_index_list input;
			
		// read section symbols
		#! (section_symbol_ns,input)
			= loopAfillOnInput read_int input
			
		// read symbols
		#! (symbols,input)
			= loopAfillOnInput read_symbol input
			
		// update symbol_table
		#! symbol_table 
			= { SSymbolTable |
				text_symbols		= text_symbols
			,	data_symbols		= data_symbols
			,	bss_symbols			= bss_symbols
			,	imported_symbols	= imported_symbols
			,	section_symbol_ns	= section_symbol_ns
			,	symbols				= symbols
			,	extra_sections		= []
			};
		= (symbol_table,input);
	where {
		read_symbol_index_list input
			#! (_,s_symbol_index_list,input)
				= freadi input;
			= read_symbol_index_list s_symbol_index_list input;
		where {
			read_symbol_index_list 0 input
				= (EmptySymbolIndex,input);
			read_symbol_index_list s_symbol_index_list input
				#! (_,symbol_n,input)
					= freadi input;
				#! (sils,input)
					= read_symbol_index_list (dec s_symbol_index_list) input;
				= (SymbolIndex symbol_n sils,input);
		} // read_symbol_index_list
	
	read_symbol :: !Int !*{!Symbol} !*File -> (!*{!Symbol},!*File);	
	read_symbol i symbols_a input
		#! (symbol,input)
			= read_symbol input;
		= ({symbols_a & [i] = symbol},input);
	where {	
	//	read_symbol :: !*File -> (!Symbol,!*File);
		read_symbol input
			#! (_,symbol_kind, input)
				= freadc input;
			= case (toInt symbol_kind) of {
				MODULE_SYMBOL
				/*
					#! (_,i0,input)
						= freadi input;
				*/
					#! (_,i1,input)
						= freadi input;		
					#! (_,i2,input)
						= freadi input;
					#! (_,i3,input)
						= freadi input;	
					#! (_,i4,input)
						= freadi input;
					#! (_,i5,input)
						= freadi input;	
					#! (_,s_size,input)
						= freadi input;
					#! (s,input)
						= freads input s_size;
					-> (Module /*i0*/ i1 i2 i3 i4 i5 s, input);
					
				LABEL_SYMBOL
					#! (_,i0,input)
						= freadi input;
					#! (_,i1,input)
						= freadi input;	
					#! (_,i2,input)
						= freadi input;
					-> (Label i0 i1 i2, input);
					
				SECTIONLABEL_SYMBOL
					#! (_,i0,input)
						= freadi input;
					#! (_,i1,input)
						= freadi input;	
					-> (SectionLabel i0 i1, input);
				
				IMPORTLABEL_SYMBOL
					#! (_,s_size,input)
						= freadi input;
					#! (s,input)
						= freads input s_size;
					-> (ImportLabel s, input);
					
				IMPORTEDLABEL_SYMBOL
					#! (_,i0,input)
						= freadi input;
					#! (_,i1,input)
						= freadi input;
					-> (ImportedLabel i0 i1, input);
				
				IMPORTEDLABELPLUSOFFSET_SYMBOL
					#! (_,i0,input)
						= freadi input;
					#! (_,i1,input)
						= freadi input;		
					#! (_,i2,input)
						= freadi input;
					-> (ImportedLabelPlusOffset i0 i1 i2, input);
					
				IMPORTEDFUNCTIONDESCRIPTOR_SYMBOL 
					#! (_,i0,input)
						= freadi input;
					#! (_,i1,input)
						= freadi input;
					-> (ImportedFunctionDescriptor i0 i1, input);
					
				EMPTYSYMBOL_SYMBOL
					-> (EmptySymbol, input);
			} // case 
			
		} // read_symbol

	} // read_symbol_table


}