Path: utzoo!utgpu!cs.utexas.edu!uunet!mcsun!i2unix!inria!adesign!loic From: loic@adesign.uucp (Loic Dachary) Newsgroups: alt.sources Subject: gas-1.36 patches for COFF generation Message-ID: Date: 16 Oct 90 08:36:26 GMT Sender: loic@adesign.uucp Distribution: alt Organization: GNA c/o Axis Design 119 rue de Flandre, 75019 Paris, France Lines: 1209 Archive-name: gas-coff/part05 *** write.c Thu Apr 12 17:23:42 1990 --- /lasvegas/spare/usenet/port/gas-1.36/write.c Mon Oct 15 12:35:38 1990 *************** *** 30,35 **** --- 30,36 ---- trouble. */ + #include "oformat.h" #include "as.h" #include "md.h" #include "subsegs.h" *************** *** 37,64 **** #include "struc-symbol.h" #include "write.h" #include "symbols.h" #ifdef SPARC #include "sparc.h" #endif - void append(); - #ifdef hpux #define EXEC_MACHINE_TYPE HP9000S200_ID #endif ! /* ! * In: length of relocation (or of address) in chars: 1, 2 or 4. ! * Out: GNU LD relocation length code: 0, 1, or 2. ! */ ! ! static unsigned char ! ! nbytes_r_length [] = { ! 42, 0, 1, 42, 2 ! }; ! static struct frag * text_frag_root; static struct frag * data_frag_root; --- 38,59 ---- #include "struc-symbol.h" #include "write.h" #include "symbols.h" + #include "append.h" + #ifdef coff + #include + #endif /* coff */ #ifdef SPARC #include "sparc.h" #endif #ifdef hpux #define EXEC_MACHINE_TYPE HP9000S200_ID #endif ! #ifdef coff ! extern time_t time(); ! #endif /* coff */ static struct frag * text_frag_root; static struct frag * data_frag_root; *************** *** 66,84 **** static struct frag * text_last_frag; /* Last frag in segment. */ static struct frag * data_last_frag; /* Last frag in segment. */ ! static struct exec the_exec; static long int string_byte_count; static char * the_object_file; - #ifndef SPARC - static - #endif char * next_object_file_charP; /* Tracks object file bytes. */ - static long int size_of_the_object_file; /* # bytes in object file. */ - /* static long int length; JF unused */ /* String length, including trailing '\0'. */ static void relax_segment(); --- 61,74 ---- static struct frag * text_last_frag; /* Last frag in segment. */ static struct frag * data_last_frag; /* Last frag in segment. */ ! static object_headers headers; static long int string_byte_count; static char * the_object_file; char * next_object_file_charP; /* Tracks object file bytes. */ /* static long int length; JF unused */ /* String length, including trailing '\0'. */ static void relax_segment(); *************** *** 85,93 **** void emit_segment(); static relax_addressT relax_align(); static long int fixup_segment(); - #ifndef SPARC - static void emit_relocations(); - #endif /* * fix_new() * --- 75,80 ---- *************** *** 144,150 **** register struct frchain * next_frchainP; register fragS * * prev_fragPP; register char * name; ! register symbolS * symbolP; register symbolS ** symbolPP; /* register fixS * fixP; JF unused */ unsigned --- 131,137 ---- register struct frchain * next_frchainP; register fragS * * prev_fragPP; register char * name; ! symbolS * symbolP; register symbolS ** symbolPP; /* register fixS * fixP; JF unused */ unsigned *************** *** 153,158 **** --- 140,152 ---- syms_siz, tr_siz, dr_siz; + #ifdef coff + SCNHDR text_section_header; + SCNHDR data_section_header; + SCNHDR bss_section_header; + symbolS* last_functionP = (symbolS*)0; + symbolS* last_tagP; + #endif /* coff */ void output_file_create(); void output_file_append(); void output_file_close(); *************** *** 160,168 **** --- 154,168 ---- void gdb_emit(); void gdb_end(); #endif + long int object_file_size; extern long omagic; /* JF magic # to write out. Is different for Suns and Vaxen and other boxes */ + #ifdef coff + /* Initialize the stack used to keep track of the matching .bb .be */ + stack* block_stack = stack_init(512, sizeof(symbolS*)); + #endif /* coff */ + #ifdef VMS /* * Under VMS we try to be compatible with VAX-11 "C". Thus, we *************** *** 261,273 **** */ know( text_last_frag -> fr_type == rs_fill && text_last_frag -> fr_offset == 0 ); ! text_siz=text_last_frag->fr_address; #ifdef SPARC ! text_siz= (text_siz+7)&(~7); ! text_last_frag->fr_address=text_siz; #endif - md_number_to_chars((char *)&the_exec.a_text,text_siz, sizeof(the_exec.a_text)); - /* the_exec . a_text = text_last_frag -> fr_address; */ /* * Join the 2 segments into 1 huge segment. --- 261,272 ---- */ know( text_last_frag -> fr_type == rs_fill && text_last_frag -> fr_offset == 0 ); ! H_SET_TEXT_SIZE(&headers,text_last_frag->fr_address); #ifdef SPARC ! H_SET_TEXT_SIZE(&headers,H_GET_TEXT_SIZE(&headers) + ! (H_GET_TEXT_SIZE(&headers)+7)&(~7)); ! text_last_frag->fr_address=H_GET_TEXT_SIZE(&headers); #endif /* * Join the 2 segments into 1 huge segment. *************** *** 281,294 **** register relax_addressT slide; know( text_last_frag -> fr_type == rs_fill && text_last_frag -> fr_offset == 0 ); ! data_siz=data_last_frag->fr_address; #ifdef SPARC ! data_siz += (8 - (data_siz % 8)) % 8; ! data_last_frag->fr_address = data_siz; #endif ! md_number_to_chars((char *)&the_exec.a_data,data_siz,sizeof(the_exec.a_data)); ! /* the_exec . a_data = data_last_frag -> fr_address; */ ! slide = text_siz; /* Address in file of the data segment. */ for (fragP = data_frag_root; fragP; fragP = fragP -> fr_next) --- 280,292 ---- register relax_addressT slide; know( text_last_frag -> fr_type == rs_fill && text_last_frag -> fr_offset == 0 ); ! H_SET_DATA_SIZE(&headers,data_last_frag->fr_address); #ifdef SPARC ! H_SET_DATA_SIZE(&headers,(H_GET_DATA_SIZE(&headers) + ! (8 - (H_GET_DATA_SIZE(&headers) % 8)) % 8)); ! data_last_frag->fr_address = H_GET_DATA_SIZE(&headers); #endif ! slide = H_GET_TEXT_SIZE(&headers); /* & in file of the data segment. */ for (fragP = data_frag_root; fragP; fragP = fragP -> fr_next) *************** *** 298,314 **** know( text_last_frag ); text_last_frag -> fr_next = data_frag_root; } ! else { ! md_number_to_chars((char *)&the_exec.a_data,0,sizeof(the_exec.a_data)); ! data_siz = 0; ! } ! bss_address_frag . fr_address = text_siz + data_siz; #ifdef SPARC local_bss_counter=(local_bss_counter+7)&(~7); #endif ! md_number_to_chars((char *)&the_exec.a_bss,local_bss_counter,sizeof(the_exec.a_bss)); ! /* * --- 296,310 ---- know( text_last_frag ); text_last_frag -> fr_next = data_frag_root; } ! else ! H_SET_DATA_SIZE(&headers,0); ! bss_address_frag . fr_address = H_GET_TEXT_SIZE(&headers) + ! H_GET_DATA_SIZE(&headers); #ifdef SPARC local_bss_counter=(local_bss_counter+7)&(~7); #endif ! H_SET_BSS_SIZE(&headers,local_bss_counter); /* * *************** *** 340,380 **** symbolP->sy_forward=0; } } ! symbolPP = & symbol_rootP; /* -> last symbol chain link. */ { ! register long int symbol_number; ! symbol_number = 0; while (symbolP = * symbolPP) { ! name = symbolP -> sy_name; ! if(flagseen['R'] && (symbolP->sy_nlist.n_type&N_DATA)) { ! symbolP->sy_nlist.n_type&= ~N_DATA; ! symbolP->sy_nlist.n_type|= N_TEXT; ! } ! /* if(symbolP->sy_forward) { ! symbolP->sy_value += symbolP->sy_forward->sy_value + symbolP->sy_forward->sy_frag->fr_address; ! } */ symbolP -> sy_value += symbolP -> sy_frag -> fr_address; - /* JF the 128 bit is a hack so stabs like - "LET_STMT:23. . ." don't go away */ - /* CPH: 128 bit hack is moby loser. N_SO for file "Lower.c" - fell through the cracks. I think that N_STAB should be - used instead of 128. */ /* JF the \001 bit is to make sure that local labels ( 1: - 9: don't make it into the symtable either */ #ifndef VMS /* Under VMS we need to keep local symbols */ ! if ( !name || (symbolP->sy_nlist.n_type&N_STAB) ! || (name[0]!='\001' && (flagseen ['L'] || name [0] != 'L' ))) #endif /* not VMS */ { - symbolP -> sy_number = symbol_number ++; #ifndef VMS ! if (name) { /* Ordinary case. */ symbolP -> sy_name_offset = string_byte_count; ! string_byte_count += strlen (symbolP -> sy_name) + 1; } else /* .Stabd case. */ #endif /* not VMS */ --- 336,581 ---- symbolP->sy_forward=0; } } ! { ! register int symbol_number = 0; ! #if defined(coff) ! symbolS* symbol_externP = (symbolS*)0; ! symbolS* symbol_extern_lastP = (symbolS*)0; ! ! /* The symbol list should be ordered according to the following sequence ! * order : ! * . .file symbol ! * . debug entries for functions ! * . fake symbols for .text .data and .bss ! * . defined symbols ! * . undefined symbols ! * But this is not mandatory. The only important point is to put the ! * undefined symbols at the end of the list. ! */ ! ! { ! /* Is there a .file symbol ? If not insert one at the beginning. */ ! if(symbol_rootP == NULL || ! S_GET_STORAGE_CLASS(symbol_rootP) != C_FILE) ! c_dot_file_symbol("fake"); ! ! /* ! * Build up static symbols for .text, .data and .bss ! */ ! dot_text_symbol = (symbolS*) ! c_section_symbol(".text", 0, H_GET_TEXT_SIZE(&headers), ! 0/*text_relocation_number*/, 0/*text_lineno_number*/); ! dot_data_symbol = (symbolS*) ! c_section_symbol(".data", H_GET_TEXT_SIZE(&headers), ! H_GET_DATA_SIZE(&headers), ! 0/*data_relocation_number*/, ! 0); /* There is no data lineno entries */ ! dot_bss_symbol = (symbolS*) ! c_section_symbol(".bss", H_GET_TEXT_SIZE(&headers) + ! H_GET_DATA_SIZE(&headers), ! H_GET_BSS_SIZE(&headers), ! 0, /* No relocation for a bss section. */ ! 0); /* There is no bss lineno entries */ ! } ! ! symbolP = symbol_rootP; ! if(symbolP) { ! while(symbolP) { ! /* If the symbol has a tagndx entry, resolve it */ ! if(SF_GET_TAGGED(symbolP)) { ! SA_SET_SYM_TAGNDX(symbolP, ! ((symbolS*)SA_GET_SYM_TAGNDX(symbolP))->sy_number); ! } ! /* Debug symbol do not need all this rubbish */ ! if(!SF_GET_DEBUG(symbolP)) { ! symbolS* real_symbolP; ! /* L* and C_EFCN symbols never merge. */ ! if(!SF_GET_LOCAL(symbolP) && ! (real_symbolP = ! symbol_find_base(S_GET_NAME(symbolP), DO_NOT_STRIP)) && ! real_symbolP != symbolP) { ! /* Move the debug data from the debug symbol to the ! real symbol. Do NOT do the oposite (i.e. move from ! real symbol to symbol and remove real symbol from the ! list.) Because some pointers refer to the real symbol ! whereas no pointers refer to the symbol. */ ! c_symbol_merge(symbolP, real_symbolP); ! /* Replace the current symbol by the real one */ ! /* The symbols will never be the last or the first ! because : 1st symbol is .file and 3 last symbols are ! .text, .data, .bss */ ! real_symbolP->sy_previous->sy_next = real_symbolP->sy_next; ! real_symbolP->sy_next->sy_previous = real_symbolP->sy_previous; ! symbolP->sy_previous->sy_next = real_symbolP; ! symbolP->sy_next->sy_previous = real_symbolP; ! real_symbolP->sy_next = symbolP->sy_next; ! real_symbolP->sy_previous = symbolP->sy_previous; ! symbolP = real_symbolP; ! } ! if(flagseen['R'] && S_IS_DATA(symbolP)) ! S_SET_TEXT(symbolP); ! ! symbolP->sy_value += symbolP->sy_frag->fr_address; ! ! if(!S_IS_DEFINED(symbolP)) ! S_SET_EXTERNAL(symbolP); ! else if(S_GET_STORAGE_CLASS(symbolP) == C_NULL) ! S_SET_STORAGE_CLASS(symbolP, C_STAT); ! ! /* Mainly to speed up if not -g */ ! if(SF_GET_PROCESS(symbolP)) { ! /* Handle the nested blocks auxiliary info. */ ! if(S_GET_STORAGE_CLASS(symbolP) == C_BLOCK) { ! if(!strcmp(S_GET_NAME(symbolP), ".bb")) ! stack_push(block_stack, &symbolP); ! else { /* .eb */ ! register symbolS* begin_symbolP; ! begin_symbolP = *(symbolS**)stack_pop(block_stack); ! if(begin_symbolP == (symbolS*)0) ! as_warn("mismatched .eb"); ! else ! SA_SET_SYM_ENDNDX(begin_symbolP, symbol_number); ! } ! } ! /* If we are able to identify the type of a function, and we ! are out of a function (last_functionP == 0) then, the ! function symbol will be associated with an auxiliary ! entry. */ ! if(last_functionP == (symbolS*)0 && ! SF_GET_FUNCTION(symbolP)) { ! last_functionP = symbolP; ! S_SET_NUMBER_AUXILIARY(symbolP, 1); ! /* Clobber possible stale .dim information. */ ! memset(&symbolP->sy_auxent, '\0', sizeof(union auxent)); ! } ! /* The C_FCN do not need any additional information. ! I don't even know if this is needed for sdb. But the ! standard assembler generate it, so... ! */ ! if(S_GET_STORAGE_CLASS(symbolP) == C_EFCN) { ! if(last_functionP == (symbolS*)0) ! as_fatal("C_EFCN symbol out of scope"); ! SA_SET_SYM_FSIZE(last_functionP, ! (long)(symbolP->sy_value - ! last_functionP->sy_value)); ! SA_SET_SYM_ENDNDX(last_functionP, symbol_number); ! last_functionP = (symbolS*)0; ! } ! } ! } else { ! /* First descriptor of a structure must point to the next ! slot outside the structure description. */ ! if(SF_GET_TAG(symbolP)) ! last_tagP = symbolP; ! else if(S_GET_STORAGE_CLASS(symbolP) == C_EOS) ! /* +2 take in account the current symbol */ ! SA_SET_SYM_ENDNDX(last_tagP, symbol_number+2); ! } ! ! /* We must put the external symbols appart. The loader ! does not bomb if we do not. But the references in ! the endndx field for a .bb symbol are not corrected ! if an external symbol is removed between .bb and .be. ! I.e int the following case : ! [20] .bb endndx = 22 ! [21] foo external ! [22] .be ! ld will move the symbol 21 to the end of the list but ! endndx will still be 22 instead of 21. */ ! { ! register symbolS* thisP = symbolP; ! ! symbolP = thisP->sy_next; ! /* remove C_EFCN and LOCAL (L...) symbols */ ! if(SF_GET_LOCAL(thisP)) { ! thisP->sy_next->sy_previous = thisP->sy_previous; ! thisP->sy_previous->sy_next = thisP->sy_next; ! } else { ! if(S_GET_STORAGE_CLASS(thisP) == C_EXT && ! !SF_GET_FUNCTION(thisP)) { ! /* Remove from the list */ ! thisP->sy_next->sy_previous = thisP->sy_previous; ! thisP->sy_previous->sy_next = thisP->sy_next; ! /* Move at the end of the list */ ! if (symbol_extern_lastP) { ! symbol_extern_lastP->sy_next = thisP; ! thisP->sy_previous = symbol_extern_lastP; ! } else { ! symbol_externP = thisP; ! } ! thisP->sy_next = (symbolS*)0; ! symbol_extern_lastP = thisP; ! } else { ! if(SF_GET_STRING(thisP)) { ! thisP->sy_name_offset = string_byte_count; ! string_byte_count += strlen(S_GET_NAME(thisP)) + 1; ! } else ! thisP->sy_name_offset = 0; ! thisP->sy_number = symbol_number; ! symbol_number += 1 + S_GET_NUMBER_AUXILIARY(thisP); ! } ! } ! } ! } ! symbol_lastP->sy_next = symbol_externP; ! symbolP = symbol_externP; ! while(symbolP) { ! if(SF_GET_STRING(symbolP)) { ! symbolP->sy_name_offset = string_byte_count; ! string_byte_count += strlen(S_GET_NAME(symbolP)) + 1; ! } else ! symbolP->sy_name_offset = 0; ! symbolP->sy_number = symbol_number; ! symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP); ! symbolP = symbolP->sy_next; ! } ! } ! { ! lineno* lineP; ! for(lineP = lineno_rootP; lineP; lineP = lineP->next) { ! if(lineP->line.l_lnno) ! lineP->line.l_addr.l_paddr += ! ((fragS*)lineP->frag)->fr_address; ! else { ! /* There is a good chance that the symbol pointed to ! is not the one that will be emitted and that the ! sy_number is not accurate. */ ! char* name; ! name = (char*)lineP->line.l_addr.l_symndx; ! if((symbolP = symbol_find_base(name, DO_NOT_STRIP)) == ! (symbolS*)0) ! as_warn("line number lost symbol %s", name); ! else ! lineP->line.l_addr.l_symndx = symbolP->sy_number; ! } ! text_lineno_number++; ! } ! } ! #elif defined(aout) ! symbolPP = & symbol_rootP; /* -> last symbol chain link. */ while (symbolP = * symbolPP) { ! name = S_GET_NAME(symbolP); ! if(flagseen['R'] && S_IS_DATA(symbolP)) ! S_SET_TEXT(symbolP); symbolP -> sy_value += symbolP -> sy_frag -> fr_address; /* JF the \001 bit is to make sure that local labels ( 1: - 9: don't make it into the symtable either */ #ifndef VMS /* Under VMS we need to keep local symbols */ ! if (!S_IS_LOCAL(symbolP)) #endif /* not VMS */ { #ifndef VMS ! /* The + 1 after strlen account for the \0 at the end of each string */ ! symbolP -> sy_number = symbol_number ++; ! if(!S_IS_STABD(symbolP)) { /* Ordinary case. */ symbolP -> sy_name_offset = string_byte_count; ! string_byte_count += ! strlen (S_GET_NAME(symbolP)) + 1; } else /* .Stabd case. */ #endif /* not VMS */ *************** *** 382,397 **** symbolPP = & (symbolP -> sy_next); } #ifndef VMS ! else * symbolPP = symbolP -> sy_next; #endif /* not VMS */ } /* for each symbol */ ! syms_siz = sizeof( struct nlist) * symbol_number; ! md_number_to_chars((char *)&the_exec.a_syms,syms_siz,sizeof(the_exec.a_syms)); ! /* the_exec . a_syms = sizeof( struct nlist) * symbol_number; */ } - /* * Addresses of frags now reflect addresses we use in the object file. * Symbol values are correct. --- 583,601 ---- symbolPP = & (symbolP -> sy_next); } #ifndef VMS ! else /* skip the symbol */ * symbolPP = symbolP -> sy_next; #endif /* not VMS */ } /* for each symbol */ ! #elif defined(elf) ! do it yourself ! ! #else ! you lose ! #endif ! H_SET_STRING_SIZE(&headers,string_byte_count); ! H_SET_SYMBOL_TABLE_SIZE(&headers, symbol_number); } /* * Addresses of frags now reflect addresses we use in the object file. * Symbol values are correct. *************** *** 553,595 **** * Scan every FixS performing fixups. We had to wait until now to do * this because md_convert_frag() may have made some fixSs. */ ! /* the_exec . a_trsize ! = sizeof(struct relocation_info) * fixup_segment (text_fix_root, N_TEXT); ! the_exec . a_drsize ! = sizeof(struct relocation_info) * fixup_segment (data_fix_root, N_DATA); */ ! ! tr_siz=sizeof(struct relocation_info) * fixup_segment (text_fix_root, N_TEXT); ! md_number_to_chars((char *)&the_exec.a_trsize, tr_siz ,sizeof(the_exec.a_trsize)); ! dr_siz=sizeof(struct relocation_info) * fixup_segment (data_fix_root, N_DATA); ! md_number_to_chars((char *)&the_exec.a_drsize, dr_siz, sizeof(the_exec.a_drsize)); ! md_number_to_chars((char *)&the_exec.a_magic,omagic,sizeof(the_exec.a_magic)); ! md_number_to_chars((char *)&the_exec.a_entry,0,sizeof(the_exec.a_entry)); #ifdef EXEC_MACHINE_TYPE ! md_number_to_chars((char *)&the_exec.a_machtype, EXEC_MACHINE_TYPE, sizeof(the_exec.a_machtype)); #endif #ifdef EXEC_VERSION ! md_number_to_chars((char *)&the_exec.a_version,EXEC_VERSION,sizeof(the_exec.a_version)); #endif - - /* the_exec . a_entry = 0; */ ! size_of_the_object_file = ! sizeof( the_exec ) + ! text_siz + ! data_siz + ! syms_siz + ! tr_siz + ! dr_siz + ! string_byte_count; ! ! next_object_file_charP ! = the_object_file ! = xmalloc ( size_of_the_object_file ); output_file_create (out_file_name); ! append (& next_object_file_charP, (char *)(&the_exec), (unsigned long)sizeof(the_exec)); /* * Emit code. --- 757,876 ---- * Scan every FixS performing fixups. We had to wait until now to do * this because md_convert_frag() may have made some fixSs. */ ! ! H_SET_RELOCATION_SIZE(&headers, ! RELSZ*fixup_segment (text_fix_root, SEG_TEXT), ! RELSZ*fixup_segment (data_fix_root, SEG_DATA)); ! H_SET_MAGIC_NUMBER(&headers,omagic); ! H_SET_ENTRY_POINT(&headers,0); #ifdef EXEC_MACHINE_TYPE ! H_SET_MACHINE_TYPE(&headers,EXEC_MACHINE_TYPE); #endif #ifdef EXEC_VERSION ! H_SET_VERSION(&headers,EXEC_VERSION); #endif ! #ifdef coff ! { ! register int text_relocation_number = 0; ! register int data_relocation_number = 0; ! register fixS* fixP; ! ! /* Count the number of relocation entries for text and data */ ! for(fixP = text_fix_root; fixP; fixP = fixP->fx_next) ! if(fixP->fx_addsy) ! text_relocation_number++; ! SA_SET_SCN_NRELOC(dot_text_symbol, text_relocation_number); ! /* Assign the number of line number entries for the text section */ ! SA_SET_SCN_NLINNO(dot_text_symbol, text_lineno_number); ! /* Assign the size of the section */ ! SA_SET_SCN_SCNLEN(dot_text_symbol, H_GET_TEXT_SIZE(&headers)); ! ! for(fixP = data_fix_root; fixP; fixP = fixP->fx_next) ! if(fixP->fx_addsy) ! data_relocation_number++; ! SA_SET_SCN_NRELOC(dot_data_symbol, data_relocation_number); ! /* Assign the size of the section */ ! SA_SET_SCN_SCNLEN(dot_data_symbol, H_GET_DATA_SIZE(&headers)); ! ! /* Assign the size of the section */ ! SA_SET_SCN_SCNLEN(dot_bss_symbol, H_GET_BSS_SIZE(&headers)); ! } ! ! /* Fill in extra coff fields */ ! ! /* Initialize general line number information. */ ! H_SET_LINENO_SIZE(&headers, text_lineno_number * LINESZ); ! ! /* filehdr */ ! H_SET_FILE_MAGIC_NUMBER(&headers, FILE_HEADER_MAGIC); ! H_SET_NUMBER_OF_SECTIONS(&headers, 3); /* text+data+bss */ ! H_SET_TIME_STAMP(&headers, (long)time((long*)0)); ! H_SET_SYMBOL_TABLE_POINTER(&headers, ! H_GET_SYMBOL_TABLE_FILE_OFFSET(&headers)); ! /* symbol table size allready set */ ! H_SET_SIZEOF_OPTIONAL_HEADER(&headers, AOUTHDRSZ); ! H_SET_FLAGS(&headers, (text_lineno_number == 0 ? F_LNNO : 0 ) | ! BYTE_ORDERING); ! ! /* aouthdr */ ! /* magic number allready set */ ! H_SET_VERSION_STAMP(&headers, 0); ! /* Text, data, bss size; entry point; text_start and data_start ! are already set */ ! ! /* Build section headers */ ! ! c_section_header(&text_section_header, ! ".text", ! 0, ! H_GET_TEXT_SIZE(&headers), ! H_GET_TEXT_FILE_OFFSET(&headers), ! SA_GET_SCN_NRELOC(dot_text_symbol) ? ! H_GET_RELOCATION_FILE_OFFSET(&headers) : 0, ! text_lineno_number ? H_GET_LINENO_FILE_OFFSET(&headers) : 0, ! SA_GET_SCN_NRELOC(dot_text_symbol), ! text_lineno_number); ! c_section_header(&data_section_header, ! ".data", ! H_GET_TEXT_SIZE(&headers), ! H_GET_DATA_SIZE(&headers), ! H_GET_DATA_SIZE(&headers) ? ! H_GET_DATA_FILE_OFFSET(&headers) : 0, ! SA_GET_SCN_NRELOC(dot_data_symbol) ? ! H_GET_RELOCATION_FILE_OFFSET(&headers) + ! text_section_header.s_nreloc * RELSZ : 0, ! 0, /* No line number information */ ! SA_GET_SCN_NRELOC(dot_data_symbol), ! 0); /* No line number information */ ! c_section_header(&bss_section_header, ! ".bss", ! H_GET_TEXT_SIZE(&headers) + H_GET_DATA_SIZE(&headers), ! H_GET_BSS_SIZE(&headers), ! 0, /* No file offset */ ! 0, /* No relocation information */ ! 0, /* No line number information */ ! 0, /* No relocation information */ ! 0); /* No line number information */ ! ! #endif /* coff */ ! ! object_file_size = H_GET_FILE_SIZE(&headers); ! next_object_file_charP = the_object_file = xmalloc ( object_file_size ); output_file_create (out_file_name); ! ! H_OUTPUT(&headers, &next_object_file_charP); ! ! #ifdef coff ! /* Output the section headers */ ! c_section_header_append(&text_section_header, &next_object_file_charP); ! c_section_header_append(&data_section_header, &next_object_file_charP); ! c_section_header_append(&bss_section_header, &next_object_file_charP); ! #endif /* coff */ ! /* * Emit code. *************** *** 614,642 **** */ emit_relocations (text_fix_root, (relax_addressT)0); emit_relocations (data_fix_root, text_last_frag -> fr_address); /* ! * Emit all symbols left in the symbol chain. ! * Any symbol still undefined is made N_EXT. */ ! for ( symbolP = symbol_rootP; symbolP; symbolP = symbolP -> sy_next ) ! { ! register char * temp; ! ! temp = symbolP -> sy_nlist . n_un . n_name; ! /* JF fix the numbers up. Call by value RULES! */ ! md_number_to_chars((char *)&(symbolP -> sy_nlist . n_un . n_strx ),symbolP -> sy_name_offset,sizeof(symbolP -> sy_nlist . n_un . n_strx )); ! md_number_to_chars((char *)&(symbolP->sy_nlist.n_desc),symbolP->sy_nlist.n_desc,sizeof(symbolP -> sy_nlist . n_desc)); ! md_number_to_chars((char *)&(symbolP->sy_nlist.n_value),symbolP->sy_nlist.n_value,sizeof(symbolP->sy_nlist.n_value)); ! /* symbolP -> sy_nlist . n_un . n_strx = symbolP -> sy_name_offset; JF replaced by md above */ ! if (symbolP -> sy_type == N_UNDF) ! symbolP -> sy_type |= N_EXT; /* Any undefined symbols become N_EXT. */ ! append (& next_object_file_charP, (char *)(& symbolP -> sy_nlist), ! (unsigned long)sizeof(struct nlist)); ! symbolP -> sy_nlist . n_un . n_name = temp; ! } /* for each symbol */ /* - * next_object_file_charP -> slot for next object byte. * Emit strings. * Find strings by crawling along symbol table chain. */ --- 895,914 ---- */ emit_relocations (text_fix_root, (relax_addressT)0); emit_relocations (data_fix_root, text_last_frag -> fr_address); + + #ifdef coff /* ! * Emit line number entries. */ ! emit_lineno(lineno_rootP, &next_object_file_charP); ! #endif /* coff */ ! ! /* ! * Emit symbols. ! */ ! emit_symbols (symbol_rootP,&next_object_file_charP); /* * Emit strings. * Find strings by crawling along symbol table chain. */ *************** *** 644,661 **** md_number_to_chars((char *)&string_byte_count, string_byte_count, sizeof(string_byte_count)); append (& next_object_file_charP, (char *)&string_byte_count, (unsigned long)sizeof(string_byte_count)); ! for ( symbolP = symbol_rootP; symbolP; symbolP = symbolP -> sy_next ) ! { ! if (symbolP -> sy_name) ! { /* Ordinary case: not .stabd. */ ! append (& next_object_file_charP, symbolP -> sy_name, ! (unsigned long)(strlen (symbolP -> sy_name) + 1)); ! } ! } /* for each symbol */ ! ! know( next_object_file_charP == the_object_file + size_of_the_object_file ); ! output_file_append (the_object_file, size_of_the_object_file, out_file_name); #ifdef DONTDEF if (flagseen['G']) /* GDB symbol file to be appended? */ --- 916,934 ---- md_number_to_chars((char *)&string_byte_count, string_byte_count, sizeof(string_byte_count)); append (& next_object_file_charP, (char *)&string_byte_count, (unsigned long)sizeof(string_byte_count)); ! for(symbolP = symbol_rootP; symbolP; symbolP = symbolP->sy_next) { ! #ifdef coff ! if(SF_GET_STRING(symbolP)) ! #else /* coff */ ! if(S_GET_NAME(symbolP)) ! #endif /* coff */ ! append(&next_object_file_charP, S_GET_NAME(symbolP), ! (unsigned long)(strlen (S_GET_NAME(symbolP)) + 1)); ! } ! know( next_object_file_charP == the_object_file + object_file_size); ! /* Write the data to the file */ ! output_file_append (the_object_file,object_file_size,out_file_name); #ifdef DONTDEF if (flagseen['G']) /* GDB symbol file to be appended? */ *************** *** 692,698 **** void relax_segment (segment_frag_root, segment_type) struct frag * segment_frag_root; ! segT segment_type; /* N_DATA or N_TEXT */ { register struct frag * fragP; register relax_addressT address; --- 965,971 ---- void relax_segment (segment_frag_root, segment_type) struct frag * segment_frag_root; ! segT segment_type; /* SEG_DATA or SEG_TEXT */ { register struct frag * fragP; register relax_addressT address; *************** *** 730,736 **** case rs_machine_dependent: address += md_estimate_size_before_relax ! (fragP, seg_N_TYPE [(int) segment_type]); break; #ifndef WORKING_DOT_WORD --- 1003,1009 ---- case rs_machine_dependent: address += md_estimate_size_before_relax ! (fragP, seg_SEG((int) segment_type)); break; #ifndef WORKING_DOT_WORD *************** *** 837,845 **** target = offset; if (symbolP) { ! know( ((symbolP -> sy_type & N_TYPE) == N_ABS) || ((symbolP -> sy_type & N_TYPE) == N_DATA) || ((symbolP -> sy_type & N_TYPE) == N_TEXT)); ! know( symbolP -> sy_frag ); ! know( (symbolP->sy_type&N_TYPE)!=N_ABS || symbolP->sy_frag==&zero_address_frag ); target += symbolP -> sy_value + symbolP -> sy_frag -> fr_address; --- 1110,1121 ---- target = offset; if (symbolP) { ! know(S_IS_ABS(symbolP) || ! S_IS_DATA(symbolP) || ! S_IS_TEXT(symbolP)) ! know(symbolP -> sy_frag); ! know(!S_IS_ABS(symbolP) || ! symbolP->sy_frag==&zero_address_frag ); target += symbolP -> sy_value + symbolP -> sy_frag -> fr_address; *************** *** 866,875 **** target = offset; if (symbolP) { ! know( ((symbolP -> sy_type & N_TYPE) == N_ABS) || ((symbolP -> sy_type & ! N_TYPE) == N_DATA) || ((symbolP -> sy_type & N_TYPE) == N_TEXT)); ! know( symbolP -> sy_frag ); ! know( (symbolP->sy_type&N_TYPE)!=N_ABS || symbolP->sy_frag==&zero_address_frag ); target += symbolP -> sy_value + symbolP -> sy_frag -> fr_address; --- 1142,1153 ---- target = offset; if (symbolP) { ! know(S_IS_ABS(symbolP) || ! S_IS_DATA(symbolP) || ! S_IS_TEXT(symbolP)) ! know(symbolP -> sy_frag); ! know(!S_IS_ABS(symbolP) || ! symbolP->sy_frag==&zero_address_frag ); target += symbolP -> sy_value + symbolP -> sy_frag -> fr_address; *************** *** 1021,1045 **** add_number = fixP -> fx_offset; pcrel = fixP -> fx_pcrel; if(add_symbolP) ! add_symbol_N_TYPE = add_symbolP -> sy_type & N_TYPE; if (sub_symbolP) { if(!add_symbolP) /* Its just -sym */ { ! if(sub_symbolP->sy_type!=N_ABS) ! as_warn("Negative of non-absolute symbol %s", sub_symbolP->sy_name); ! add_number-=sub_symbolP->sy_value; } ! else if ( ((sub_symbolP -> sy_type ^ add_symbol_N_TYPE) & N_TYPE) == 0 ! && ( add_symbol_N_TYPE == N_DATA ! || add_symbol_N_TYPE == N_TEXT ! || add_symbol_N_TYPE == N_BSS ! || add_symbol_N_TYPE == N_ABS)) { /* Difference of 2 symbols from same segment. */ /* Can't make difference of 2 undefineds: 'value' means */ /* something different for N_UNDF. */ ! add_number += add_symbolP -> sy_value - sub_symbolP -> sy_value; add_symbolP = NULL; fixP -> fx_addsy = NULL; } --- 1299,1328 ---- add_number = fixP -> fx_offset; pcrel = fixP -> fx_pcrel; if(add_symbolP) ! add_symbol_N_TYPE = SEG_seg(S_GET_SEGMENT(add_symbolP)); if (sub_symbolP) { if(!add_symbolP) /* Its just -sym */ { ! if(SEG_seg(sub_symbolP->sy_type)!=SEG_ABSOLUTE) ! as_warn("Negative of non-absolute symbol %s", ! S_GET_NAME(sub_symbolP)); ! add_number-=S_GET_VALUE(sub_symbolP); } ! /* if sub_symbol is in the same segment that add_symbol ! and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */ ! else if((SEG_seg(S_GET_SEGMENT(sub_symbolP)) == ! add_symbol_N_TYPE) && ! ((add_symbol_N_TYPE == SEG_DATA) || ! (add_symbol_N_TYPE == SEG_TEXT) || ! (add_symbol_N_TYPE == SEG_BSS) || ! (add_symbol_N_TYPE == SEG_ABSOLUTE))) { /* Difference of 2 symbols from same segment. */ /* Can't make difference of 2 undefineds: 'value' means */ /* something different for N_UNDF. */ ! add_number += S_GET_VALUE(add_symbolP) - ! S_GET_VALUE(sub_symbolP); add_symbolP = NULL; fixP -> fx_addsy = NULL; } *************** *** 1046,1059 **** else { /* Different segments in subtraction. */ ! know( sub_symbolP -> sy_type != (N_ABS | N_EXT)) ! if (sub_symbolP -> sy_type == N_ABS) ! add_number -= sub_symbolP -> sy_value; else { ! as_warn("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.", ! seg_name[(int)N_TYPE_seg[sub_symbolP->sy_type&N_TYPE]], ! sub_symbolP -> sy_name, fragP -> fr_address + where); } } } --- 1329,1342 ---- else { /* Different segments in subtraction. */ ! know(!(S_IS_EXTERNAL(sub_symbolP) && S_IS_ABS(sub_symbolP))); ! if (S_IS_ABS(sub_symbolP)) ! add_number -= S_GET_VALUE(sub_symbolP); else { ! as_warn("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.", ! segment_name((int)SEG_seg(S_GET_SEGMENT(sub_symbolP))), ! S_GET_NAME(sub_symbolP), fragP -> fr_address + where); } } } *************** *** 1066,1072 **** * SEG_UNKNOWN, but it is now in the local segment. * So we know how to do the address without relocation. */ ! add_number += add_symbolP -> sy_value; add_number -= size + where + fragP -> fr_address; pcrel = 0; /* Lie. Don't want further pcrel processing. */ fixP -> fx_addsy = NULL; /* No relocations please. */ --- 1349,1355 ---- * SEG_UNKNOWN, but it is now in the local segment. * So we know how to do the address without relocation. */ ! add_number += S_GET_VALUE(add_symbolP); add_number -= size + where + fragP -> fr_address; pcrel = 0; /* Lie. Don't want further pcrel processing. */ fixP -> fx_addsy = NULL; /* No relocations please. */ *************** *** 1082,1101 **** { switch (add_symbol_N_TYPE) { ! case N_ABS: ! add_number += add_symbolP -> sy_value; fixP -> fx_addsy = NULL; add_symbolP = NULL; break; ! case N_BSS: ! case N_DATA: ! case N_TEXT: seg_reloc_count ++; ! add_number += add_symbolP -> sy_value; break; ! case N_UNDF: seg_reloc_count ++; break; --- 1365,1388 ---- { switch (add_symbol_N_TYPE) { ! case SEG_ABSOLUTE: ! add_number += S_GET_VALUE(add_symbolP); fixP -> fx_addsy = NULL; add_symbolP = NULL; break; ! case SEG_BSS: ! case SEG_DATA: ! case SEG_TEXT: seg_reloc_count ++; ! add_number += S_GET_VALUE(add_symbolP); break; ! case SEG_UNKNOWN: ! #ifdef coff ! if(S_IS_COMMON(add_symbolP)) ! add_number += S_GET_VALUE(add_symbolP); ! #endif /* coff */ seg_reloc_count ++; break; *************** *** 1125,1131 **** case 0: #ifdef SPARC fixP->fx_addnumber = add_number; ! md_number_to_imm(place, add_number, size, fixP, this_segment_type); #else md_number_to_imm (place, add_number, size); /* OVE: the immediates, like disps, have lsb at lowest address */ --- 1412,1419 ---- case 0: #ifdef SPARC fixP->fx_addnumber = add_number; ! md_number_to_imm(place, add_number, size, fixP, ! seg_SEG(this_segment_type)); #else md_number_to_imm (place, add_number, size); /* OVE: the immediates, like disps, have lsb at lowest address */ *************** *** 1149,1215 **** return (seg_reloc_count); } /* fixup_segment() */ - - /* The sparc needs its own emit_relocations() */ - #ifndef SPARC - /* - * emit_relocations() - * - * Crawl along a fixS chain. Emit the segment's relocations. - */ - static void - emit_relocations (fixP, segment_address_in_file) - register fixS * fixP; /* Fixup chain for this segment. */ - relax_addressT segment_address_in_file; - { - struct relocation_info ri; - register symbolS * symbolP; - - /* JF this is for paranoia */ - bzero((char *)&ri,sizeof(ri)); - for ( ; fixP; fixP = fixP -> fx_next) - { - if (symbolP = fixP -> fx_addsy) - { - - #ifndef hpux - /* These two 'cuz of NS32K */ - ri . r_bsr = fixP -> fx_bsr; - ri . r_disp = fixP -> fx_im_disp; - #endif - - ri . r_length = nbytes_r_length [fixP -> fx_size]; - ri . r_pcrel = fixP -> fx_pcrel; - ri . r_address = fixP -> fx_frag -> fr_address - + fixP -> fx_where - - segment_address_in_file; - if ((symbolP -> sy_type & N_TYPE) == N_UNDF) - { - ri . r_extern = 1; - ri . r_symbolnum = symbolP -> sy_number; - } - else - { - ri . r_extern = 0; - ri . r_symbolnum = symbolP -> sy_type & N_TYPE; - } - - /* - The 68k machines assign bit-fields from higher bits to - lower bits ("left-to-right") within the int. VAXen assign - bit-fields from lower bits to higher bits ("right-to-left"). - Both handle multi-byte numbers in their usual fashion - (Big-endian and little-endian stuff). - Thus we need a machine dependent routine to make - sure the structure is written out correctly. FUN! - */ - md_ri_to_chars((char *) &ri, ri); - append (&next_object_file_charP, (char *)& ri, (unsigned long)sizeof(ri)); - } - } - - } - #endif int is_dnrange(f1,f2) --- 1437,1442 ---- *** write.h Tue May 30 20:36:06 1989 --- /lasvegas/spare/usenet/port/gas-1.36/write.h Wed Sep 12 09:29:10 1990 *************** *** 72,77 **** --- 72,79 ---- COMMON fixS * data_fix_root; /* Chains fixSs. */ COMMON fixS ** seg_fix_rootP; /* -> one of above. */ + COMMON char * next_object_file_charP; + bit_fixS *bit_fix_new(); /* end: write.h */ *** xmalloc.c Wed Mar 1 23:48:34 1989 --- /lasvegas/spare/usenet/port/gas-1.36/xmalloc.c Wed Sep 12 09:28:43 1990 *************** *** 43,48 **** --- 43,50 ---- #include #endif + #define error as_fatal + char * xmalloc(n) long n; { *** xrealloc.c Wed Mar 1 23:48:33 1989 --- /lasvegas/spare/usenet/port/gas-1.36/xrealloc.c Wed Sep 12 09:28:43 1990 *************** *** 45,50 **** --- 45,52 ---- #include #endif + #define error as_fatal + char * xrealloc (ptr, n) register char *ptr; -- Loic Dachary loic@adesign.uucp or loic@afp.uucp Voice +33 1 40 35 20 20