gas-1.36 patches for COFF generation
Loic Dachary
loic at adesign.uucp
Tue Oct 16 18:35:16 AEST 1990
*** 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 <ctype.h>
#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 <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
+ #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 at adesign.uucp or loic at afp.uucp
Voice +33 1 40 35 20 20
More information about the Alt.sources
mailing list