From: loic@adesign.uucp (Loic Dachary) Newsgroups: alt.sources Subject: gas-1.36 patches for COFF generation Message-ID: Date: 16 Oct 90 08:35:16 GMT *** m68k.c Wed May 16 16:47:44 1990 --- /lasvegas/spare/usenet/port/gas-1.36/m68k.c Sat Oct 13 09:21:00 1990 *************** *** 22,27 **** --- 22,28 ---- #include #include "m68k-opcode.h" + #include "oformat.h" #include "as.h" #include "obstack.h" #include "frags.h" *************** *** 2669,2675 **** know(fragP->fr_symbol); /* The displacement of the address, from current location. */ ! disp = (fragP->fr_symbol->sy_value + fragP->fr_offset) - object_address; switch(fragP->fr_subtype) { case TAB(BCC68000,BYTE): --- 2670,2676 ---- know(fragP->fr_symbol); /* The displacement of the address, from current location. */ ! disp = (S_GET_VALUE(fragP->fr_symbol) + fragP->fr_offset) - object_address; switch(fragP->fr_subtype) { case TAB(BCC68000,BYTE): *************** *** 2798,2804 **** /* handle SZ_UNDEF first, it can be changed to BYTE or SHORT */ switch(fragP->fr_subtype) { case TAB(DBCC,SZ_UNDEF): ! if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) { fragP->fr_subtype=TAB(DBCC,SHORT); fragP->fr_var+=2; break; --- 2799,2805 ---- /* handle SZ_UNDEF first, it can be changed to BYTE or SHORT */ switch(fragP->fr_subtype) { case TAB(DBCC,SZ_UNDEF): ! if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) { fragP->fr_subtype=TAB(DBCC,SHORT); fragP->fr_var+=2; break; *************** *** 2820,2826 **** break; case TAB(BCC68000,SZ_UNDEF): ! if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) { fragP->fr_subtype=TAB(BCC68000,BYTE); break; } --- 2821,2827 ---- break; case TAB(BCC68000,SZ_UNDEF): ! if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) { fragP->fr_subtype=TAB(BCC68000,BYTE); break; } *************** *** 2839,2845 **** break; case TAB(BRANCH,SZ_UNDEF): ! if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) { fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE); break; } else if(flagseen['m']) { --- 2840,2846 ---- break; case TAB(BRANCH,SZ_UNDEF): ! if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) { fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE); break; } else if(flagseen['m']) { *************** *** 2880,2886 **** case TAB(BRANCH,BYTE): /* We can't do a short jump to the next instruction, so we force word mode. */ ! if(fragP->fr_symbol && fragP->fr_symbol->sy_value==0 && fragP->fr_symbol->sy_frag==fragP->fr_next) { fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),SHORT); fragP->fr_var+=2; --- 2881,2887 ---- case TAB(BRANCH,BYTE): /* We can't do a short jump to the next instruction, so we force word mode. */ ! if(fragP->fr_symbol && S_GET_VALUE(fragP->fr_symbol)==0 && fragP->fr_symbol->sy_frag==fragP->fr_next) { fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),SHORT); fragP->fr_var+=2; *************** *** 2887,2893 **** } break; case TAB(FBRANCH,SZ_UNDEF): ! if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) { fragP->fr_subtype=TAB(FBRANCH,SHORT); fragP->fr_var+=2; } else { --- 2888,2894 ---- } break; case TAB(FBRANCH,SZ_UNDEF): ! if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) { fragP->fr_subtype=TAB(FBRANCH,SHORT); fragP->fr_var+=2; } else { *************** *** 2896,2902 **** } break; case TAB(PCREL,SZ_UNDEF): ! if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) { fragP->fr_subtype=TAB(PCREL,SHORT); fragP->fr_var+=2; } else { --- 2897,2903 ---- } break; case TAB(PCREL,SZ_UNDEF): ! if(S_GET_SEGMENT(fragP->fr_symbol)==segtype) { fragP->fr_subtype=TAB(PCREL,SHORT); fragP->fr_var+=2; } else { *************** *** 2910,2915 **** --- 2911,2917 ---- return fragP->fr_var + fragP->fr_fix - old_fix; } + #ifdef aout /* the bit-field entries in the relocation_info struct plays hell with the byte-order problems of cross-assembly. So as a hack, I added this mach. dependent ri twiddler. Ugly, but it gets *************** *** 2935,2940 **** --- 2937,2943 ---- /* now put it back where you found it */ bcopy (the_bytes, (char *)ri_p, sizeof(struct relocation_info)); } + #endif /* aout */ #ifndef WORKING_DOT_WORD int md_short_jump_size = 4; *** read.c Tue Mar 6 22:08:29 1990 --- /lasvegas/spare/usenet/port/gas-1.36/read.c Mon Oct 15 11:31:29 1990 *************** *** 35,40 **** --- 35,41 ---- #include #include #include + #include "oformat.h" #include "as.h" #include "read.h" #include "md.h" *************** *** 115,121 **** --- 116,127 ---- static int is_it_end_of_statement(); static void pobegin(); static void pseudo_set(); + #ifdef coff + static void def(); + static void line(); + #else /* coff */ static void stab(); + #endif /* coff */ static void stringer(); extern char line_comment_chars[]; *************** *** 131,136 **** --- 137,149 ---- static char *old_input; static char *old_limit; + #ifdef coff + static struct hash_control* tag_hash; + static void tag_init(); + static void tag_insert(); + static symbolS* tag_find(); + #endif /* coff */ + #ifndef WORKING_DOT_WORD struct broken_word *broken_words; int new_broken_words = 0; *************** *** 143,148 **** --- 156,164 ---- read_begin() { pobegin(); + #ifdef coff + tag_init(); + #endif /* coff */ obstack_begin( ¬es, 5000 ); #define BIGNUM_BEGIN_SIZE (16) bignum_low = xmalloc((long)BIGNUM_BEGIN_SIZE); *************** *** 155,162 **** po_hash = NULL; /* use before set up: NULL-> address error */ void s_abort(), s_align(), s_comm(), s_data(); ! void s_desc(), s_even(), s_file(), s_fill(); void s_globl(), s_lcomm(), s_line(), s_lsym(); void s_org(), s_set(), s_space(), s_text(); --- 171,181 ---- po_hash = NULL; /* use before set up: NULL-> address error */ + #ifdef aout + void s_desc(); + #endif /* aout */ void s_abort(), s_align(), s_comm(), s_data(); ! void s_even(), s_file(), s_fill(); void s_globl(), s_lcomm(), s_line(), s_lsym(); void s_org(), s_set(), s_space(), s_text(); *************** *** 181,187 **** --- 200,208 ---- { "byte", cons, 1 }, { "comm", s_comm, 0 }, { "data", s_data, 0 }, + #ifdef aout { "desc", s_desc, 0 }, + #endif /* aout */ { "double", float_cons, 'd' }, { "file", s_file, 0 }, { "fill", s_fill, 0 }, *************** *** 207,215 **** --- 228,241 ---- { "short", cons, 2 }, { "single", float_cons, 'f' }, { "space", s_space, 0 }, + #ifdef coff + { "def", def, 0 }, + { "ln", line, 0 }, + #else /* coff */ { "stabd", stab, 'd' }, { "stabn", stab, 'n' }, { "stabs", stab, 's' }, + #endif /* coff */ { "text", s_text, 0 }, #ifndef SPARC { "word", cons, 2 }, *************** *** 570,588 **** *p = 0; symbolP = symbol_find_or_make (name); *p = c; ! if ( (symbolP -> sy_type & N_TYPE) != N_UNDF || ! symbolP -> sy_other != 0 || symbolP -> sy_desc != 0) { as_warn( "Ignoring attempt to re-define symbol"); ignore_rest_of_line(); return; } ! if (symbolP -> sy_value) { ! if (symbolP -> sy_value != temp) as_warn( "Length of .comm \"%s\" is already %d. Not changed to %d.", ! symbolP -> sy_name, symbolP -> sy_value, temp); } else { ! symbolP -> sy_value = temp; ! symbolP -> sy_type |= N_EXT; } know( symbolP -> sy_frag == &zero_address_frag ); demand_empty_rest_of_line(); --- 596,619 ---- *p = 0; symbolP = symbol_find_or_make (name); *p = c; ! if (S_IS_DEFINED(symbolP) ! #ifdef aout ! || S_GET_OTHER(symbolP) != 0 || S_GET_DESC(symbolP) != 0 ! #endif /* aout */ ! ) { as_warn( "Ignoring attempt to re-define symbol"); ignore_rest_of_line(); return; } ! if (S_GET_VALUE(symbolP)) { ! if (S_GET_VALUE(symbolP) != temp) as_warn( "Length of .comm \"%s\" is already %d. Not changed to %d.", ! S_GET_NAME(symbolP), ! S_GET_VALUE(symbolP), ! temp); } else { ! S_SET_VALUE(symbolP, temp); ! S_SET_EXTERNAL(symbolP); } know( symbolP -> sy_frag == &zero_address_frag ); demand_empty_rest_of_line(); *************** *** 598,603 **** --- 629,635 ---- demand_empty_rest_of_line(); } + #ifdef aout void s_desc() { *************** *** 627,648 **** *p = 0; symbolP = symbol_find_or_make (name); *p = c; ! symbolP -> sy_desc = temp; } demand_empty_rest_of_line(); } void s_file() { ! register char *s; ! int length; ! ! /* Some assemblers tolerate immediately following '"' */ ! if ( s = demand_copy_string( & length ) ) { ! new_logical_line (s, -1); ! demand_empty_rest_of_line(); ! } } void --- 659,684 ---- *p = 0; symbolP = symbol_find_or_make (name); *p = c; ! S_SET_DESC(symbolP,temp); } demand_empty_rest_of_line(); } + #endif /* aout */ void s_file() { ! register char *s; ! int length; ! ! /* Some assemblers tolerate immediately following '"' */ ! if ( s = demand_copy_string( & length ) ) { ! new_logical_line (s, -1); ! demand_empty_rest_of_line(); ! } ! #ifdef coff ! c_dot_file_symbol(s); ! #endif /* coff */ } void *************** *** 825,831 **** symbolP = symbol_find_or_make (name); * input_line_pointer = c; SKIP_WHITESPACE(); ! symbolP -> sy_type |= N_EXT; if(c==',') { input_line_pointer++; SKIP_WHITESPACE(); --- 861,867 ---- symbolP = symbol_find_or_make (name); * input_line_pointer = c; SKIP_WHITESPACE(); ! S_SET_EXTERNAL(symbolP); if(c==',') { input_line_pointer++; SKIP_WHITESPACE(); *************** *** 864,882 **** *p = 0; symbolP = symbol_find_or_make (name); *p = c; ! if ( symbolP -> sy_other == 0 ! && symbolP -> sy_desc == 0 ! && ( ( symbolP -> sy_type == N_BSS ! && symbolP -> sy_value == local_bss_counter) ! || ( (symbolP -> sy_type & N_TYPE) == N_UNDF ! && symbolP -> sy_value == 0))) { ! symbolP -> sy_value = local_bss_counter; ! symbolP -> sy_type = N_BSS; symbolP -> sy_frag = & bss_address_frag; local_bss_counter += temp; } else as_warn( "Ignoring attempt to re-define symbol from %d. to %d.", ! symbolP -> sy_value, local_bss_counter ); demand_empty_rest_of_line(); } --- 900,926 ---- *p = 0; symbolP = symbol_find_or_make (name); *p = c; ! if ( ! #ifdef aout ! S_GET_OTHER(symbolP) == 0 && ! S_GET_DESC(symbolP) == 0 && ! #endif /* aout */ ! (S_IS_BSS(symbolP) && S_GET_VALUE(symbolP) == local_bss_counter) ! /* What S_GET_VALUE(symbolP) == 0 is supposed to mean (in aout case) ? ! In the coff case it clearly does not mean anything (the only case ! where a symbol is not defined is from an external declaration (extern a) ! and this kind of symbol have a 0 value. */ ! || (!S_IS_DEFINED(symbolP) && S_GET_VALUE(symbolP) == 0)) { ! S_SET_VALUE(symbolP,local_bss_counter); ! S_SET_BSS(symbolP); ! #ifdef coff ! S_SET_STORAGE_CLASS(symbolP, C_STAT); ! #endif /* coff */ symbolP -> sy_frag = & bss_address_frag; local_bss_counter += temp; } else as_warn( "Ignoring attempt to re-define symbol from %d. to %d.", ! S_GET_VALUE(symbolP), local_bss_counter ); demand_empty_rest_of_line(); } *************** *** 929,942 **** segment = expression (& exp); if ( segment != SEG_ABSOLUTE && segment != SEG_DATA && segment != SEG_TEXT && segment != SEG_BSS) { ! as_warn("Bad expression: %s", seg_name [(int)segment]); ignore_rest_of_line(); return; } know( segment == SEG_ABSOLUTE || segment == SEG_DATA || segment == SEG_TEXT || segment == SEG_BSS ); *p = 0; ! symbolP = symbol_new (name,(unsigned char)(seg_N_TYPE [(int) segment]), 0, 0, (valueT)(exp . X_add_number), & zero_address_frag); *p = c; demand_empty_rest_of_line(); } --- 973,991 ---- segment = expression (& exp); if ( segment != SEG_ABSOLUTE && segment != SEG_DATA && segment != SEG_TEXT && segment != SEG_BSS) { ! as_warn("Bad expression: %s", segment_name((int)segment)); ignore_rest_of_line(); return; } know( segment == SEG_ABSOLUTE || segment == SEG_DATA || segment == SEG_TEXT || segment == SEG_BSS ); *p = 0; ! #ifdef coff ! symbolP = symbol_new(name, segment, (valueT)(exp . X_add_number), ! 0, &zero_address_frag); ! #else /* coff */ ! symbolP = symbol_new (name,(unsigned char)(seg_SEG((int) segment)), 0, 0, (valueT)(exp . X_add_number), & zero_address_frag); + #endif /* coff */ *p = c; demand_empty_rest_of_line(); } *************** *** 972,978 **** if ( ! need_pass_2 ) { if (segment != now_seg && segment != SEG_ABSOLUTE) as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.", ! seg_name [(int) segment], seg_name [(int) now_seg]); p = frag_var (rs_org, 1, 1, (relax_substateT)0, exp . X_add_symbol, exp . X_add_number, (char *)0); * p = temp_fill; --- 1021,1027 ---- if ( ! need_pass_2 ) { if (segment != now_seg && segment != SEG_ABSOLUTE) as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.", ! segment_name((int) segment), segment_name((int) now_seg)); p = frag_var (rs_org, 1, 1, (relax_substateT)0, exp . X_add_symbol, exp . X_add_number, (char *)0); * p = temp_fill; *************** *** 1017,1023 **** if ( ! need_pass_2 ) { if (segment != now_seg && segment != SEG_ABSOLUTE) as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.", ! seg_name [(int) segment], seg_name [(int) now_seg]); ptr = frag_var (rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol, exp.X_add_number, (char *)0); *ptr= 0; --- 1066,1073 ---- if ( ! need_pass_2 ) { if (segment != now_seg && segment != SEG_ABSOLUTE) as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.", ! segment_name((int) segment), ! segment_name((int) now_seg)); ptr = frag_var (rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol, exp.X_add_number, (char *)0); *ptr= 0; *************** *** 1104,1109 **** --- 1154,1476 ---- know( is_end_of_line [input_line_pointer [-1]] ); } + #ifdef coff + /* + * Handle .ln directives. + */ + + static void + line(what) + int what; + { + c_line_new(obstack_next_free(&frags) - frag_now->fr_literal, + get_absolute_expression(), + frag_now); + demand_empty_rest_of_line(); + + return; + } + /* + * def() + * + * Handle .def directives. + * + * One would say : why can't we symbol_new if the symbol does not + * allready exists and fill it with debug information. Because of + * the C_EFCN special symbol. It would clobber the value of the + * function symbol before we have a chance to notice that it is + * a C_EFCN. And a second reason is that the code is more clear this + * way. (at least I think it is:-). + * + */ + + #define SKIP_SEMI_COLON() while(*input_line_pointer++ != ';') + #define SKIP_WHITESPACES() while(*input_line_pointer == ' ' || \ + *input_line_pointer == '\t') \ + input_line_pointer++; + + #define NEXT_DEF_DIRECTIVE() SKIP_SEMI_COLON(); SKIP_WHITESPACES() + #define equal !strcmp + #define MAX_DIRECTIVE 20 + + static void + def(what) + int what; + { + char name_end; /* Char after the end of name */ + symbolS* symbolP; /* Debug symbol just created */ + symbolS symbol; /* Temporary symbol to hold .def */ + char* symbol_name; /* Name of the debug symbol */ + char* symbol_name_copy; /* Temporary copy of the name */ + unsigned int symbol_name_length; /* */ + char* directiveP; /* Name of the pseudo opcode */ + char directive[MAX_DIRECTIVE]; /* Backup of the directive */ + char end = 0; /* If 1, stop parsing */ + + SKIP_WHITESPACES(); + + symbolP = &symbol; + memset((char*)symbolP, '\0', sizeof(symbolS)); + + symbol_name = input_line_pointer; + name_end = get_symbol_end(); + symbol_name_length = strlen(symbol_name); + symbol_name_copy = xmalloc(symbol_name_length + 1); + strcpy(symbol_name_copy, symbol_name); + + /* Initialize the new symbol */ + #if STRIP_UNDERSCORE + S_SET_NAME(symbolP, *symbol_name_copy == '_' ? symbol_name_copy + 1 : + symbol_name_copy); + #else /* STRIP_UNDERSCORE */ + S_SET_NAME(symbolP, symbol_name_copy); + #endif /* STRIP_UNDERSCORE */ + symbolP->sy_name_offset = ~0; + symbolP->sy_number = ~0; + symbolP->sy_frag = &zero_address_frag; + if(S_IS_STRING(symbolP)) + SF_SET_STRING(symbolP); + + *input_line_pointer = name_end; + + while(!end) { + NEXT_DEF_DIRECTIVE(); + directiveP = input_line_pointer; + name_end = get_symbol_end(); + strncpy(directive, directiveP, MAX_DIRECTIVE); + *input_line_pointer = name_end; + SKIP_WHITESPACES(); + switch(directive[1]) { + case 'd': + if(equal(directive, ".dim")) { + register int dim_index; + register int dimension; + + S_SET_NUMBER_AUXILIARY(symbolP, 1); + for(dim_index = 0; dim_index < DIMNUM; dim_index++) { + SKIP_WHITESPACES(); + SA_SET_SYM_DIMEN(symbolP, dim_index, + get_absolute_expression()); + switch(*input_line_pointer) { + case ',': + input_line_pointer++; + break; + default: + as_warn("badly formed .dim directive"); + case ';': + dim_index = DIMNUM; + break; + } + } + } else + as_warn("unknown debug directive : %s", directive); + break; + case 'e': + if(equal(directive, ".endef")) + end = 1; + else + as_warn("unknown debug directive : %s", directive); + break; + case 'l': + if(equal(directive, ".line")) { + S_SET_NUMBER_AUXILIARY(symbolP, 1); + SA_SET_SYM_LNNO(symbolP, get_absolute_expression()); + } else + as_warn("unknown debug directive : %s", directive); + break; + case 's': + if(equal(directive, ".size")) { + S_SET_NUMBER_AUXILIARY(symbolP, 1); + SA_SET_SYM_SIZE(symbolP, get_absolute_expression()); + } else if(equal(directive, ".scl")) + S_SET_STORAGE_CLASS(symbolP, get_absolute_expression()); + else + as_warn("unknown debug directive : %s", directive); + break; + case 't': + if(equal(directive, ".tag")) { + symbolS * tag_symbolP; + + S_SET_NUMBER_AUXILIARY(symbolP, 1); + symbol_name = input_line_pointer; + name_end = get_symbol_end(); + /* Assume that the symbol referred to by .tag is + always defined. */ + SA_SET_SYM_TAGNDX(symbolP, (long)tag_find(symbol_name)); + if(SA_GET_SYM_TAGNDX(symbolP) == 0L) + as_warn("tag not found for .tag %s", symbol_name); + SF_SET_TAGGED(symbolP); + *input_line_pointer = name_end; + } else if(equal(directive, ".type")) { + S_SET_DATA_TYPE(symbolP, get_absolute_expression()); + if(ISFCN(S_GET_DATA_TYPE(symbolP)) && + S_GET_STORAGE_CLASS(symbolP) != C_TPDEF) + SF_SET_FUNCTION(symbolP); + } else + as_warn("unknown debug directive : %s", directive); + break; + case 'v': + if(equal(directive, ".val")) { + if(is_name_beginner(*input_line_pointer)) { + symbol_name = input_line_pointer; + name_end = get_symbol_end(); + if(equal(symbol_name, ".")) { + symbolP->sy_frag = frag_now; + S_SET_VALUE(symbolP, obstack_next_free(&frags) - + frag_now->fr_literal); + /* If the .val is != from the .def (i.e. statics) */ + } else if(strcmp(symbol_name_copy, symbol_name)) { + register symbolS* forwardP; + if(forwardP = symbol_find(symbol_name)) + symbolP->sy_forward = forwardP; + else + /* Create a new undefined symbol. */ + symbolP->sy_forward = + symbol_new (symbol_name, SEG_UNKNOWN, + 0, 0, &zero_address_frag); + } + /* Otherwise, it is the name of a non debug symbol and its + value will be calculated later. */ + *input_line_pointer = name_end; + } else + S_SET_VALUE(symbolP, get_absolute_expression()); + } else + as_warn("unknown debug directive : %s", directive); + break; + default: + as_warn("unknown debug directive : %s", directive); + break; + } + } + demand_empty_rest_of_line(); + + /* Set the section number according to storage class. */ + switch(S_GET_STORAGE_CLASS(symbolP)) { + case C_STRTAG: case C_ENTAG: case C_UNTAG: + SF_SET_TAG(symbolP); + case C_FILE: + case C_TPDEF: + SF_SET_DEBUG(symbolP); + S_SET_SEGMENT(symbolP, C_DEBUG_SECTION); + break; + case C_EFCN: + SF_SET_LOCAL(symbolP); /* Do not emit this symbol. */ + case C_BLOCK: + SF_SET_PROCESS(symbolP); /* Will need processing before writing */ + case C_FCN: + S_SET_SEGMENT(symbolP, C_TEXT_SECTION); + break; + case C_AUTO: + case C_REG: + case C_MOS: case C_MOE: case C_MOU: + case C_ARG: + case C_REGPARM: + case C_FIELD: + case C_EOS: + SF_SET_DEBUG(symbolP); + S_SET_SEGMENT(symbolP, C_ABS_SECTION); + break; + case C_EXT: + case C_STAT: + /* Valid but set somewhere else (s_comm, s_lcomm, colon) */ + break; + case C_USTATIC: + case C_EXTDEF: + case C_LABEL: + case C_ULABEL: + as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(symbolP)); + break; + } + /* Now that we have build up a debug symbol, try to find if we should + merge with an existing symbol or not. */ + /* If symbol does not exist, or symbol is a end function mark, + or symbol is in debug or abs section, + insert it in the list of symbols. */ + if(S_GET_STORAGE_CLASS(symbolP) == C_EFCN || + S_GET_SEGMENT(symbolP) == C_DEBUG_SECTION || + S_GET_SEGMENT(symbolP) == C_ABS_SECTION || + (symbolP = symbol_find_base(S_GET_NAME(symbolP), DO_NOT_STRIP)) == + (symbolS*)0) { + + symbolP = (symbolS *)obstack_alloc(¬es, sizeof(symbolS)); + memcpy((char*)symbolP, &symbol, sizeof(symbolS)); + + symbol_lastP->sy_next = symbolP; + symbolP->sy_previous = symbol_lastP; + symbol_lastP = symbolP; + + } else { + /* This symbol allready exists, merge the newly created symbol into + the old one. This is not mandatory. The linker can handle + duplicate symbols correctly. But I guess that it save a *lot* + of space if the assembly file defines a lot of symbols. */ + /* The debug entry (symbol) is merged into symbolP. */ + c_symbol_merge(&symbol, symbolP); + /* For the function, the symbol *must* be were the debug symbol + appear. Move the existing symbol to the current place. */ + /* Do not take in account special cases where symbolP is first + in the list. It is always after a .bf */ + if(SF_GET_FUNCTION(symbolP)) { + /* If it already is at the end of the symbol list, do nothing */ + if(symbolP != symbol_lastP) { + /* Remove from the list */ + symbolP->sy_next->sy_previous = symbolP->sy_previous; + symbolP->sy_previous->sy_next = symbolP->sy_next; + /* Append at the end of the list */ + symbol_lastP->sy_next = symbolP; + symbolP->sy_previous = symbol_lastP; + symbol_lastP = symbolP; + } + } else + free(symbol_name_copy); + } + + /* If symbol is a {structure,union} tag, associate symbol to its name. */ + if(SF_GET_TAG(symbolP)) + tag_insert(S_GET_NAME(symbolP), symbolP); + + /* Create the line number entry pointing on the function being defined */ + if(SF_GET_FUNCTION(symbolP)) { + c_line_new((long)S_GET_NAME(symbolP), 0, &zero_address_frag); + SF_SET_PROCESS(symbolP); + } + } + + /* + * Maintain a list of the tagnames of the structres. + */ + + static void + tag_init() + { + tag_hash = hash_new(); + return ; + } + + static void + tag_insert(name, symbolP) + char* name; + symbolS* symbolP; + { + register char * error_string; + + if(*(error_string = hash_jam (tag_hash, name, (char *)symbolP))) { + as_fatal("Inserting \"%s\" into structure table failed: %s", + name, error_string); + } + return ; + } + + static symbolS* + tag_find(name) + char* name; + { + #if STRIP_UNDERSCORE + if(*name == '_') name++; + #endif /* STRIP_UNDERSCORE */ + return((symbolS*)hash_find(tag_hash, name)); + } + #else /* coff */ /* * stab() * *************** *** 1158,1165 **** symbolP = symbol_new (string, 0,0,0,0,(struct frag *)0); switch (what) { case 'd': ! symbolP->sy_name = NULL; /* .stabd feature. */ ! symbolP->sy_value = obstack_next_free(& frags) - frag_now->fr_literal; symbolP->sy_frag = frag_now; break; --- 1525,1533 ---- symbolP = symbol_new (string, 0,0,0,0,(struct frag *)0); switch (what) { case 'd': ! S_SET_NAME(symbolP,NULL); /* .stabd feature. */ ! S_SET_VALUE(symbolP,obstack_next_free(&frags) - ! frag_now->fr_literal); symbolP->sy_frag = frag_now; break; *************** *** 1185,1191 **** } if (! goof) { if (get_absolute_expression_and_terminator (& longint) == ',') ! symbolP->sy_other = longint; else { as_warn( "I want a comma after the n_other expression" ); goof = TRUE; --- 1553,1559 ---- } if (! goof) { if (get_absolute_expression_and_terminator (& longint) == ',') ! S_SET_OTHER(symbolP,longint); else { as_warn( "I want a comma after the n_other expression" ); goof = TRUE; *************** *** 1193,1199 **** } } if (! goof) { ! symbolP->sy_desc = get_absolute_expression (); if (what == 's' || what == 'n') { if (* input_line_pointer != ',') { as_warn( "I want a comma after the n_desc expression" ); --- 1561,1567 ---- } } if (! goof) { ! S_SET_DESC(symbolP, get_absolute_expression ()); if (what == 's' || what == 'n') { if (* input_line_pointer != ',') { as_warn( "I want a comma after the n_desc expression" ); *************** *** 1212,1217 **** --- 1580,1586 ---- else demand_empty_rest_of_line (); } + #endif /* coff */ /* * pseudo_set() *************** *** 1230,1239 **** { expressionS exp; register segT segment; int ext; know( symbolP ); /* NULL pointer is logic error. */ ! ext=(symbolP->sy_type&N_EXT); if ((segment = expression( & exp )) == SEG_NONE) { as_warn( "Missing expression: absolute 0 assumed" ); --- 1599,1612 ---- { expressionS exp; register segT segment; + #ifdef aout int ext; + #endif /* aout */ know( symbolP ); /* NULL pointer is logic error. */ ! #ifdef aout ! ext=S_IS_EXTERNAL(symbolP); ! #endif /* aout */ if ((segment = expression( & exp )) == SEG_NONE) { as_warn( "Missing expression: absolute 0 assumed" ); *************** *** 1245,1272 **** case SEG_BIG: as_warn( "%s number illegal. Absolute 0 assumed.", exp . X_add_number > 0 ? "Bignum" : "Floating-Point" ); ! symbolP -> sy_type = N_ABS | ext; ! symbolP -> sy_value = 0; symbolP -> sy_frag = & zero_address_frag; break; case SEG_NONE: as_warn("No expression: Using absolute 0"); ! symbolP -> sy_type = N_ABS | ext; ! symbolP -> sy_value = 0; symbolP -> sy_frag = & zero_address_frag; break; case SEG_DIFFERENCE: if (exp.X_add_symbol && exp.X_subtract_symbol ! && (exp.X_add_symbol->sy_type & N_TYPE) ! == (exp.X_subtract_symbol->sy_type & N_TYPE)) exp.X_add_number+=exp.X_add_symbol->sy_value - exp.X_subtract_symbol->sy_value; else as_warn( "Complex expression. Absolute segment assumed." ); case SEG_ABSOLUTE: ! symbolP -> sy_type = N_ABS | ext; ! symbolP -> sy_value = exp . X_add_number; symbolP -> sy_frag = & zero_address_frag; break; --- 1618,1657 ---- case SEG_BIG: as_warn( "%s number illegal. Absolute 0 assumed.", exp . X_add_number > 0 ? "Bignum" : "Floating-Point" ); ! S_SET_ABS(symbolP); ! #ifdef aout ! ext ? S_SET_EXTERNAL(symbolP) : ! S_CLEAR_EXTERNAL(symbolP); ! #endif /* aout */ ! S_SET_VALUE(symbolP, 0); symbolP -> sy_frag = & zero_address_frag; break; case SEG_NONE: as_warn("No expression: Using absolute 0"); ! S_SET_ABS(symbolP); ! #ifdef aout ! ext ? S_SET_EXTERNAL(symbolP) : ! S_CLEAR_EXTERNAL(symbolP); ! #endif /* aout */ ! S_SET_VALUE(symbolP, 0); symbolP -> sy_frag = & zero_address_frag; break; case SEG_DIFFERENCE: if (exp.X_add_symbol && exp.X_subtract_symbol ! && (S_GET_SEGMENT(exp.X_add_symbol) == ! S_GET_SEGMENT(exp.X_subtract_symbol))) exp.X_add_number+=exp.X_add_symbol->sy_value - exp.X_subtract_symbol->sy_value; else as_warn( "Complex expression. Absolute segment assumed." ); case SEG_ABSOLUTE: ! S_SET_ABS(symbolP); ! #ifdef aout ! ext ? S_SET_EXTERNAL(symbolP) : ! S_CLEAR_EXTERNAL(symbolP); ! #endif /* aout */ ! S_SET_VALUE(symbolP, exp.X_add_number); symbolP -> sy_frag = & zero_address_frag; break; *************** *** 1273,1280 **** case SEG_DATA: case SEG_TEXT: case SEG_BSS: ! symbolP -> sy_type = seg_N_TYPE [(int) segment] | ext; ! symbolP -> sy_value= exp . X_add_number + exp . X_add_symbol -> sy_value; symbolP -> sy_frag = exp . X_add_symbol -> sy_frag; break; --- 1658,1673 ---- case SEG_DATA: case SEG_TEXT: case SEG_BSS: ! switch(segment) { ! case SEG_DATA: S_SET_DATA(symbolP); break; ! case SEG_TEXT: S_SET_TEXT(symbolP); break; ! case SEG_BSS: S_SET_BSS(symbolP); break; ! } ! #ifdef aout ! ext ? S_SET_EXTERNAL(symbolP) : ! S_CLEAR_EXTERNAL(symbolP); ! #endif /* aout */ ! S_SET_VALUE(symbolP, exp.X_add_number + S_GET_VALUE(exp.X_add_symbol)); symbolP -> sy_frag = exp . X_add_symbol -> sy_frag; break; *************** *** 1371,1378 **** if ( segment == SEG_DIFFERENCE && exp . X_add_symbol == NULL ) { as_warn( "Subtracting symbol \"%s\"(segment\"%s\") is too hard. Absolute segment assumed.", ! exp . X_subtract_symbol -> sy_name, ! seg_name [(int) N_TYPE_seg [exp . X_subtract_symbol -> sy_type & N_TYPE]]); segment = SEG_ABSOLUTE; /* Leave exp . X_add_number alone. */ } --- 1764,1771 ---- if ( segment == SEG_DIFFERENCE && exp . X_add_symbol == NULL ) { as_warn( "Subtracting symbol \"%s\"(segment\"%s\") is too hard. Absolute segment assumed.", ! S_GET_NAME(exp.X_subtract_symbol), ! segment_name((int)SEG_seg(S_GET_SEGMENT(exp.X_subtract_symbol)))); segment = SEG_ABSOLUTE; /* Leave exp . X_add_number alone. */ } *************** *** 1853,1860 **** if ( (retval = get_segmented_expression (expP)) == SEG_UNKNOWN ) { ! name1 = expP -> X_add_symbol ? expP -> X_add_symbol -> sy_name : ""; ! name2 = expP -> X_subtract_symbol ? expP -> X_subtract_symbol -> sy_name : ""; if ( name1 && name2 ) { as_warn("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.", --- 2246,2255 ---- if ( (retval = get_segmented_expression (expP)) == SEG_UNKNOWN ) { ! name1 = expP->X_add_symbol ? S_GET_NAME(expP->X_add_symbol) : ""; ! name2 = expP->X_subtract_symbol ? ! S_GET_NAME(expP->X_subtract_symbol) : ! ""; if ( name1 && name2 ) { as_warn("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.", *************** *** 1988,1994 **** equals(sym_name) char *sym_name; { ! register struct symbol * symbolP; /* symbol we are working with */ if(sym_name[0]=='.' && sym_name[1]=='\0') { /* Turn '. = mumble' into a .org mumble */ --- 2383,2389 ---- equals(sym_name) char *sym_name; { ! register symbolS * symbolP; /* symbol we are working with */ if(sym_name[0]=='.' && sym_name[1]=='\0') { /* Turn '. = mumble' into a .org mumble */ *************** *** 2006,2012 **** if ( ! need_pass_2 ) { if (segment != now_seg && segment != SEG_ABSOLUTE) as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.", ! seg_name [(int) segment], seg_name [(int) now_seg]); p = frag_var (rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol, exp.X_add_number, (char *)0); * p = 0; --- 2401,2408 ---- if ( ! need_pass_2 ) { if (segment != now_seg && segment != SEG_ABSOLUTE) as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.", ! segment_name((int) segment), ! segment_name((int) now_seg)); p = frag_var (rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol, exp.X_add_number, (char *)0); * p = 0; -- Loic Dachary loic@adesign.uucp or loic@afp.uucp Voice +33 1 40 35 20 20