diff options
author | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1998-02-28 00:52:21 +0000 |
---|---|---|
committer | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1998-02-28 00:52:21 +0000 |
commit | aec8fae7b71e7994f4fc91c851ee819c8e3a51d9 (patch) | |
tree | 738a29567df2714c4663ec36767197634909609e | |
parent | c3a25357ea4388e10eda41500b43ed181dfab2cb (diff) |
A merge of the late resolution of symbols code Ian Lance Taylor added to
gas2 back in 1993. gcc2.8 generates code which relies on this.
-rw-r--r-- | gnu/usr.bin/gas/as.h | 5 | ||||
-rw-r--r-- | gnu/usr.bin/gas/config/obj-aout.c | 24 | ||||
-rw-r--r-- | gnu/usr.bin/gas/config/obj-aout.h | 6 | ||||
-rw-r--r-- | gnu/usr.bin/gas/config/obj-bout.c | 15 | ||||
-rw-r--r-- | gnu/usr.bin/gas/config/obj-bout.h | 6 | ||||
-rw-r--r-- | gnu/usr.bin/gas/config/obj-coff.c | 43 | ||||
-rw-r--r-- | gnu/usr.bin/gas/config/obj-coff.h | 14 | ||||
-rw-r--r-- | gnu/usr.bin/gas/config/obj-coffbfd.c | 56 | ||||
-rw-r--r-- | gnu/usr.bin/gas/config/obj-coffbfd.h | 29 | ||||
-rw-r--r-- | gnu/usr.bin/gas/config/obj-generic.h | 5 | ||||
-rw-r--r-- | gnu/usr.bin/gas/config/obj-ieee.c | 31 | ||||
-rw-r--r-- | gnu/usr.bin/gas/config/obj-vms.c | 24 | ||||
-rw-r--r-- | gnu/usr.bin/gas/config/obj-vms.h | 6 | ||||
-rw-r--r-- | gnu/usr.bin/gas/config/tc-m88k.c | 174 | ||||
-rw-r--r-- | gnu/usr.bin/gas/expr.h | 15 | ||||
-rw-r--r-- | gnu/usr.bin/gas/read.c | 19 | ||||
-rw-r--r-- | gnu/usr.bin/gas/struc-symbol.h | 15 | ||||
-rw-r--r-- | gnu/usr.bin/gas/symbols.c | 90 | ||||
-rw-r--r-- | gnu/usr.bin/gas/symbols.h | 12 |
19 files changed, 393 insertions, 196 deletions
diff --git a/gnu/usr.bin/gas/as.h b/gnu/usr.bin/gas/as.h index 0a0a0f0018f..18e97fe99a3 100644 --- a/gnu/usr.bin/gas/as.h +++ b/gnu/usr.bin/gas/as.h @@ -1,4 +1,4 @@ -/* $OpenBSD: as.h,v 1.2 1996/04/23 00:15:51 niklas Exp $ */ +/* $OpenBSD: as.h,v 1.3 1998/02/28 00:51:54 niklas Exp $ */ /* as.h - global header file Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc. @@ -400,10 +400,9 @@ void subsegs_begin(); /* this one starts the chain of target dependant headers */ #include "targ-env.h" -/* these define types needed by the interfaces */ +#include "expr.h" #include "struc-symbol.h" #include "write.h" -#include "expr.h" #include "frags.h" #include "hash.h" #include "read.h" diff --git a/gnu/usr.bin/gas/config/obj-aout.c b/gnu/usr.bin/gas/config/obj-aout.c index 2d8665ad5e2..bdc6a01f125 100644 --- a/gnu/usr.bin/gas/config/obj-aout.c +++ b/gnu/usr.bin/gas/config/obj-aout.c @@ -1,4 +1,4 @@ -/* $OpenBSD: obj-aout.c,v 1.3 1998/02/15 18:49:22 niklas Exp $ */ +/* $OpenBSD: obj-aout.c,v 1.4 1998/02/28 00:52:03 niklas Exp $ */ /* a.out object file format Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. @@ -208,7 +208,7 @@ symbolS *symbolP; { md_number_to_chars((char *)&(S_GET_OFFSET(symbolP)), S_GET_OFFSET(symbolP), sizeof(S_GET_OFFSET(symbolP))); md_number_to_chars((char *)&(S_GET_DESC(symbolP)), S_GET_DESC(symbolP), sizeof(S_GET_DESC(symbolP))); - md_number_to_chars((char *)&(S_GET_VALUE(symbolP)), S_GET_VALUE(symbolP), sizeof(S_GET_VALUE(symbolP))); + md_number_to_chars((char *)&(symbolP->sy_symbol.n_value), S_GET_VALUE(symbolP), sizeof(symbolP->sy_symbol.n_value)); append(where, (char *)&symbolP->sy_symbol, sizeof(obj_symbol_type)); } /* obj_symbol_to_chars() */ @@ -468,24 +468,6 @@ object_headers *headers; symbolS **symbolPP; int symbol_number = 0; - /* JF deal with forward references first... */ - for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { - if (symbolP->sy_forward && symbolP->sy_forward != symbolP) { - S_SET_SEGMENT(symbolP, - S_GET_SEGMENT(symbolP->sy_forward)); - S_SET_VALUE(symbolP, S_GET_VALUE(symbolP) - + S_GET_VALUE(symbolP->sy_forward) - + symbolP->sy_forward->sy_frag->fr_address); - - symbolP->sy_aux |= symbolP->sy_forward->sy_aux; - symbolP->sy_sizexp = symbolP->sy_forward->sy_sizexp; - if (S_IS_EXTERNAL(symbolP->sy_forward) - && !S_IS_DEBUG(symbolP)) - S_SET_EXTERNAL(symbolP); - } /* if it has a forward reference */ - symbolP->sy_forward=0; - } /* walk the symbol chain */ - tc_crawl_symbol_chain(headers); symbolPP = &symbol_rootP; /*->last symbol chain link. */ @@ -494,7 +476,7 @@ object_headers *headers; S_SET_SEGMENT(symbolP, SEG_TEXT); } /* if pushing data into text */ - S_SET_VALUE(symbolP, S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address); + resolve_symbol_value (symbolP); /* OK, here is how we decide which symbols go out into the brave new symtab. Symbols that do are: diff --git a/gnu/usr.bin/gas/config/obj-aout.h b/gnu/usr.bin/gas/config/obj-aout.h index e59b1a04b46..55ec1196c8b 100644 --- a/gnu/usr.bin/gas/config/obj-aout.h +++ b/gnu/usr.bin/gas/config/obj-aout.h @@ -1,4 +1,4 @@ -/* $OpenBSD: obj-aout.h,v 1.2 1996/04/23 00:15:59 niklas Exp $ */ +/* $OpenBSD: obj-aout.h,v 1.3 1998/02/28 00:52:04 niklas Exp $ */ /* obj-aout.h, a.out object file format for gas, the assembler. Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. @@ -87,8 +87,6 @@ typedef struct nlist obj_symbol_type; /* Symbol table entry */ #define S_IS_STABD(s) (S_GET_NAME(s) == (char *)0) /* Accessors */ -/* The value of the symbol */ -#define S_GET_VALUE(s) (((s)->sy_symbol.n_value)) /* The name of the symbol */ #define S_GET_NAME(s) ((s)->sy_symbol.n_un.n_name) /* The pointer to the string table */ @@ -103,8 +101,6 @@ typedef struct nlist obj_symbol_type; /* Symbol table entry */ #define S_GET_DESC(s) ((s)->sy_symbol.n_desc) /* Modifiers */ -/* Set the value of the symbol */ -#define S_SET_VALUE(s,v) ((s)->sy_symbol.n_value = (unsigned long) (v)) /* Assume that a symbol cannot be simultaneously in more than on segment */ /* set segment */ #define S_SET_SEGMENT(s,seg) ((s)->sy_symbol.n_type &= ~N_TYPE,(s)->sy_symbol.n_type|=SEGMENT_TO_SYMBOL_TYPE(seg)) diff --git a/gnu/usr.bin/gas/config/obj-bout.c b/gnu/usr.bin/gas/config/obj-bout.c index d1408ab3c72..573129e152b 100644 --- a/gnu/usr.bin/gas/config/obj-bout.c +++ b/gnu/usr.bin/gas/config/obj-bout.c @@ -1,4 +1,4 @@ -/* $OpenBSD: obj-bout.c,v 1.2 1998/02/15 18:49:24 niklas Exp $ */ +/* $OpenBSD: obj-bout.c,v 1.3 1998/02/28 00:52:06 niklas Exp $ */ /* b.out object file format Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. @@ -360,17 +360,6 @@ object_headers *headers; symbolS *symbolP; int symbol_number = 0; - /* JF deal with forward references first... */ - for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { - if (symbolP->sy_forward) { - S_SET_VALUE(symbolP, S_GET_VALUE(symbolP) - + S_GET_VALUE(symbolP->sy_forward) - + symbolP->sy_forward->sy_frag->fr_address); - - symbolP->sy_forward=0; - } /* if it has a forward reference */ - } /* walk the symbol chain */ - tc_crawl_symbol_chain(headers); symbolPP = & symbol_rootP; /*->last symbol chain link. */ @@ -379,7 +368,7 @@ object_headers *headers; S_SET_SEGMENT(symbolP, SEG_TEXT); } /* if pusing data into text */ - S_SET_VALUE(symbolP, S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address); + resolve_symbol_value(symbolP); /* OK, here is how we decide which symbols go out into the brave new symtab. Symbols that do are: diff --git a/gnu/usr.bin/gas/config/obj-bout.h b/gnu/usr.bin/gas/config/obj-bout.h index fb7999469cf..c65d32bc43b 100644 --- a/gnu/usr.bin/gas/config/obj-bout.h +++ b/gnu/usr.bin/gas/config/obj-bout.h @@ -1,4 +1,4 @@ -/* $OpenBSD: obj-bout.h,v 1.2 1998/02/15 18:49:25 niklas Exp $ */ +/* $OpenBSD: obj-bout.h,v 1.3 1998/02/28 00:52:07 niklas Exp $ */ /* b.out object file format Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. @@ -194,8 +194,6 @@ struct relocation_info { #define S_IS_STABD(s) (S_GET_NAME(s) == NULL) /* Accessors */ -/* The value of the symbol */ -#define S_GET_VALUE(s) ((unsigned long) ((s)->sy_symbol.n_value)) /* The name of the symbol */ #define S_GET_NAME(s) ((s)->sy_symbol.n_un.n_name) /* The pointer to the string table */ @@ -210,8 +208,6 @@ struct relocation_info { #define S_GET_DESC(s) ((s)->sy_symbol.n_desc) /* Modifiers */ -/* Set the value of the symbol */ -#define S_SET_VALUE(s,v) ((s)->sy_symbol.n_value = (unsigned long) (v)) /* Assume that a symbol cannot be simultaneously in more than on segment */ /* set segment */ #define S_SET_SEGMENT(s,seg) ((s)->sy_symbol.n_type &= ~N_TYPE,(s)->sy_symbol.n_type|=SEGMENT_TO_SYMBOL_TYPE(seg)) diff --git a/gnu/usr.bin/gas/config/obj-coff.c b/gnu/usr.bin/gas/config/obj-coff.c index 3bcc1a7b92a..fc9429a7d38 100644 --- a/gnu/usr.bin/gas/config/obj-coff.c +++ b/gnu/usr.bin/gas/config/obj-coff.c @@ -1,4 +1,4 @@ -/* $OpenBSD: obj-coff.c,v 1.2 1998/02/15 18:49:26 niklas Exp $ */ +/* $OpenBSD: obj-coff.c,v 1.3 1998/02/28 00:52:08 niklas Exp $ */ /* coff object file format Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. @@ -421,6 +421,9 @@ void obj_symbol_to_chars(where, symbolP) char **where; symbolS *symbolP; { + /* Move the value into the COFF symbol itself. */ + symbolP->sy_symbol.ost_entry.n_value = S_GET_VALUE (symbolP); + #ifdef BFD_HEADERS unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux; unsigned int i; @@ -1301,11 +1304,16 @@ static void obj_coff_val() { S_SET_VALUE(def_symbol_in_progress, obstack_next_free(&frags) - frag_now->fr_literal); /* If the .val is != from the .def (e.g. statics) */ } else if (strcmp(S_GET_NAME(def_symbol_in_progress), symbol_name)) { - def_symbol_in_progress->sy_forward = symbol_find_or_make(symbol_name); - + def_symbol_in_progress->sy_value.X_add_symbol = + symbol_find_or_make (symbol_name); + def_symbol_in_progress->sy_value.X_subtract_symbol = + NULL; + def_symbol_in_progress->sy_value.X_add_number = 0; + def_symbol_in_progress->sy_value.X_seg = SEG_UNKNOWN; + /* If the segment is undefined when the forward - reference is solved, then copy the segment id - from the forward symbol. */ + reference is resolved, then copy the segment id + from the forward symbol. */ SF_SET_GET_SEGMENT(def_symbol_in_progress); } /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */ @@ -1392,29 +1400,6 @@ object_headers *headers; /* Initialize the stack used to keep track of the matching .bb .be */ stack* block_stack = stack_init(512, sizeof(symbolS*)); - /* JF deal with forward references first... */ - for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) { - - if (symbolP->sy_forward) { - S_SET_VALUE(symbolP, (S_GET_VALUE(symbolP) - + S_GET_VALUE(symbolP->sy_forward) - + symbolP->sy_forward->sy_frag->fr_address)); - - if ( -#ifndef TE_I386AIX - SF_GET_GET_SEGMENT(symbolP) -#else - SF_GET_GET_SEGMENT(symbolP) - && S_GET_SEGMENT(symbolP) == SEG_UNKNOWN -#endif /* TE_I386AIX */ - ) { - S_SET_SEGMENT(symbolP, S_GET_SEGMENT(symbolP->sy_forward)); - } /* forward segment also */ - - symbolP->sy_forward=0; - } /* if it has a forward reference */ - } /* walk the symbol chain */ - tc_crawl_symbol_chain(headers); /* The symbol list should be ordered according to the following sequence @@ -1528,7 +1513,7 @@ object_headers *headers; S_SET_SEGMENT(symbolP, SEG_TEXT); } /* push data into text */ - S_SET_VALUE(symbolP, S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address); + resolve_symbol_value(symbolP); if (!S_IS_DEFINED(symbolP) && !SF_GET_LOCAL(symbolP)) { S_SET_EXTERNAL(symbolP); diff --git a/gnu/usr.bin/gas/config/obj-coff.h b/gnu/usr.bin/gas/config/obj-coff.h index 6bc8d76056d..682b8102a1f 100644 --- a/gnu/usr.bin/gas/config/obj-coff.h +++ b/gnu/usr.bin/gas/config/obj-coff.h @@ -1,4 +1,4 @@ -/* $OpenBSD: obj-coff.h,v 1.2 1998/02/15 18:49:27 niklas Exp $ */ +/* $OpenBSD: obj-coff.h,v 1.3 1998/02/28 00:52:10 niklas Exp $ */ /* coff object file format Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. @@ -191,7 +191,7 @@ typedef struct { section == 0 and value > 0 (external bss symbol) */ #define S_IS_DEFINED(s) ((s)->sy_symbol.ost_entry.n_scnum > C_UNDEF_SECTION || \ ((s)->sy_symbol.ost_entry.n_scnum == C_UNDEF_SECTION && \ - (s)->sy_symbol.ost_entry.n_value > 0)) + S_GET_VALUE(s) > 0)) /* True if a debug special symbol entry */ #define S_IS_DEBUG(s) ((s)->sy_symbol.ost_entry.n_scnum == C_DEBUG_SECTION) /* True if a symbol is local symbol name */ @@ -200,12 +200,14 @@ typedef struct { (s)->sy_symbol.ost_entry.n_scnum == C_REGISTER_SECTION || \ (S_LOCAL_NAME(s) && !flagseen['L'])) /* True if a symbol is not defined in this file */ -#define S_IS_EXTERN(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 && (s)->sy_symbol.ost_entry.n_value == 0) +#define S_IS_EXTERN(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 \ + && S_GET_VALUE (s) == 0) /* * True if a symbol can be multiply defined (bss symbols have this def * though it is bad practice) */ -#define S_IS_COMMON(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 && (s)->sy_symbol.ost_entry.n_value != 0) +#define S_IS_COMMON(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 + && S_GET_VALUE (s) != 0) /* True if a symbol name is in the string table, i.e. its length is > 8. */ #define S_IS_STRING(s) (strlen(S_GET_NAME(s)) > 8 ? 1 : 0) @@ -216,8 +218,6 @@ typedef struct { #define S_GET_OFFSET(s) ((s)->sy_symbol.ost_entry.n_offset) /* The zeroes if symbol name is longer than 8 chars */ #define S_GET_ZEROES(s) ((s)->sy_symbol.ost_entry.n_zeroes) -/* The value of the symbol */ -#define S_GET_VALUE(s) ((unsigned) ((s)->sy_symbol.ost_entry.n_value)) /* The numeric value of the segment */ #define S_GET_SEGMENT(s) (N_TYPE_seg[(s)->sy_symbol.ost_entry.n_scnum+4]) /* The data type */ @@ -234,8 +234,6 @@ typedef struct { #define S_SET_OFFSET(s,v) ((s)->sy_symbol.ost_entry.n_offset = (v)) /* The zeroes if symbol name is longer than 8 chars */ #define S_SET_ZEROES(s,v) ((s)->sy_symbol.ost_entry.n_zeroes = (v)) -/* Set the value of the symbol */ -#define S_SET_VALUE(s,v) ((s)->sy_symbol.ost_entry.n_value = (v)) /* The numeric value of the segment */ #define S_SET_SEGMENT(s,v) ((s)->sy_symbol.ost_entry.n_scnum = SEGMENT_TO_SYMBOL_TYPE(v)) /* The data type */ diff --git a/gnu/usr.bin/gas/config/obj-coffbfd.c b/gnu/usr.bin/gas/config/obj-coffbfd.c index 981332212db..3f689844469 100644 --- a/gnu/usr.bin/gas/config/obj-coffbfd.c +++ b/gnu/usr.bin/gas/config/obj-coffbfd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: obj-coffbfd.c,v 1.2 1998/02/15 18:49:28 niklas Exp $ */ +/* $OpenBSD: obj-coffbfd.c,v 1.3 1998/02/28 00:52:11 niklas Exp $ */ /* coff object file format with bfd Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. @@ -163,8 +163,12 @@ const pseudo_typeS obj_pseudo_table[] = { { "data", obj_coff_data, 0 }, /* we don't yet handle this. */ { "ident", s_ignore, 0 }, - { "ABORT", s_abort, 0 }, - { "lcomm", obj_coff_lcomm, 0}, + { "ABORT", s_abort, 0 }, + { "lcomm", obj_coff_lcomm, 0 }, +#ifdef TC_M88K + /* The m88k uses sdef instead of def. */ + { "sdef", obj_coff_def, 0 }, +#endif { NULL} /* end sentinel */ }; /* obj_pseudo_table */ @@ -555,6 +559,7 @@ char * { unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux; unsigned int i; + long val; /* Turn any symbols with register attributes into abs symbols */ if (S_GET_SEGMENT(symbolP) == SEG_REGISTER) @@ -563,10 +568,13 @@ char * } /* At the same time, relocate all symbols to their output value */ - S_SET_VALUE(symbolP, - segment_info[S_GET_SEGMENT(symbolP)].scnhdr.s_paddr - + S_GET_VALUE(symbolP)); - + val = (segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr + + S_GET_VALUE (symbolP)); + + S_SET_VALUE (symbolP, val); + + symbolP->sy_symbol.ost_entry.n_value = val; + where += bfd_coff_swap_sym_out(abfd, &symbolP->sy_symbol.ost_entry, where); @@ -1096,7 +1104,12 @@ static void obj_coff_val() { S_SET_VALUE(def_symbol_in_progress, obstack_next_free(&frags) - frag_now->fr_literal); /* If the .val is != from the .def (e.g. statics) */ } else if (strcmp(S_GET_NAME(def_symbol_in_progress), symbol_name)) { - def_symbol_in_progress->sy_forward = symbol_find_or_make(symbol_name); + def_symbol_in_progress->sy_value.X_add_symbol = + symbol_find_or_make (symbol_name); + def_symbol_in_progress->sy_value.X_subtract_symbol = + NULL; + def_symbol_in_progress->sy_value.X_add_number = 0; + def_symbol_in_progress->sy_value.X_seg = SEG_UNKNOWN; /* If the segment is undefined when the forward reference is solved, then copy the segment id @@ -1223,8 +1236,7 @@ static unsigned int DEFUN_VOID(yank_symbols) S_SET_SEGMENT(symbolP, SEG_E0); } /* push data into text */ - S_SET_VALUE(symbolP, - S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address); + resolve_symbol_value(symbolP); if (!S_IS_DEFINED(symbolP) && !SF_GET_LOCAL(symbolP)) { @@ -1416,25 +1428,6 @@ static void /* Initialize the stack used to keep track of the matching .bb .be */ block_stack = stack_init(512, sizeof(symbolS*)); - /* JF deal with forward references first... */ - for (symbolP = symbol_rootP; - symbolP; - symbolP = symbol_next(symbolP)) - { - - if (symbolP->sy_forward) { - S_SET_VALUE(symbolP, (S_GET_VALUE(symbolP) - + S_GET_VALUE(symbolP->sy_forward) - + symbolP->sy_forward->sy_frag->fr_address)); - - if (SF_GET_GET_SEGMENT(symbolP)) { - S_SET_SEGMENT(symbolP, S_GET_SEGMENT(symbolP->sy_forward)); - } /* forward segment also */ - - symbolP->sy_forward=0; - } /* if it has a forward reference */ - } /* walk the symbol chain */ - /* The symbol list should be ordered according to the following sequence * order : @@ -2150,7 +2143,12 @@ static void DEFUN(fixup_segment,(fixP, this_segment_type), } /* if there was a + symbol */ if (pcrel) { +#ifndef TC_M88K + /* This adjustment is not correct on the m88k, + for which the linker does all the + computation. */ add_number -= md_pcrel_from(fixP); +#endif if (add_symbolP == 0) { fixP->fx_addsy = & abs_symbol; } /* if there's an add_symbol */ diff --git a/gnu/usr.bin/gas/config/obj-coffbfd.h b/gnu/usr.bin/gas/config/obj-coffbfd.h index 5e3a7c21e34..451ce56e227 100644 --- a/gnu/usr.bin/gas/config/obj-coffbfd.h +++ b/gnu/usr.bin/gas/config/obj-coffbfd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: obj-coffbfd.h,v 1.2 1998/02/15 18:49:28 niklas Exp $ */ +/* $OpenBSD: obj-coffbfd.h,v 1.3 1998/02/28 00:52:13 niklas Exp $ */ /* coff object file format Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. @@ -145,21 +145,24 @@ typedef struct section == 0 and value > 0 (external bss symbol) */ #define S_IS_DEFINED(s) ((s)->sy_symbol.ost_entry.n_scnum > C_UNDEF_SECTION || \ ((s)->sy_symbol.ost_entry.n_scnum == C_UNDEF_SECTION && \ - (s)->sy_symbol.ost_entry.n_value > 0)) + S_GET_VALUE (s) > 0)) /* True if a debug special symbol entry */ #define S_IS_DEBUG(s) ((s)->sy_symbol.ost_entry.n_scnum == C_DEBUG_SECTION) /* True if a symbol is local symbol name */ -/* A symbol name whose name begin with ^A is a gas internal pseudo symbol */ -#define S_IS_LOCAL(s) (S_GET_NAME(s)[0] == '\001' || \ - (s)->sy_symbol.ost_entry.n_scnum == C_REGISTER_SECTION || \ - (S_LOCAL_NAME(s) && !flagseen['L'])) +/* A symbol name whose name includes ^A is a gas internal pseudo symbol */ +#define S_IS_LOCAL(s) \ + ((s)->sy_symbol.ost_entry.n_scnum == C_REGISTER_SECTION \ + || (S_LOCAL_NAME(s) && !flagseen['L']) \ + || (strchr (s, '\001') != NULL)) /* True if a symbol is not defined in this file */ -#define S_IS_EXTERN(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 && (s)->sy_symbol.ost_entry.n_value == 0) +#define S_IS_EXTERN(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 \ + && S_GET_VALUE (s) == 0) /* * True if a symbol can be multiply defined (bss symbols have this def * though it is bad practice) */ -#define S_IS_COMMON(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 && (s)->sy_symbol.ost_entry.n_value != 0) +#define S_IS_COMMON(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 \ + && S_GET_VALUE (s) != 0) /* True if a symbol name is in the string table, i.e. its length is > 8. */ #define S_IS_STRING(s) (strlen(S_GET_NAME(s)) > 8 ? 1 : 0) @@ -170,8 +173,6 @@ typedef struct #define S_GET_OFFSET(s) ((s)->sy_symbol.ost_entry.n_offset) /* The zeroes if symbol name is longer than 8 chars */ #define S_GET_ZEROES(s) ((s)->sy_symbol.ost_entry.n_zeroes) -/* The value of the symbol */ -#define S_GET_VALUE(s) ((unsigned) ((s)->sy_symbol.ost_entry.n_value)) /* The numeric value of the segment */ #define S_GET_SEGMENT(s) s_get_segment(s) /* The data type */ @@ -188,8 +189,6 @@ typedef struct #define S_SET_OFFSET(s,v) ((s)->sy_symbol.ost_entry.n_offset = (v)) /* The zeroes if symbol name is longer than 8 chars */ #define S_SET_ZEROES(s,v) ((s)->sy_symbol.ost_entry.n_zeroes = (v)) -/* Set the value of the symbol */ -#define S_SET_VALUE(s,v) ((s)->sy_symbol.ost_entry.n_value = (v)) /* The numeric value of the segment */ #define S_SET_SEGMENT(s,v) ((s)->sy_symbol.ost_entry.n_scnum = SEGMENT_TO_SYMBOL_TYPE(v)) /* The data type */ @@ -508,6 +507,12 @@ extern SCNHDR text_section_header; #endif #endif +/* Forward the segment of a forwarded symbol. */ +#define obj_frob_forward_symbol(symp) \ + (SF_GET_GET_SEGMENT (symp) \ + ? (S_SET_SEGMENT (symp, S_GET_SEGMENT (symp->sy_value.X_add_symbol)), 0) \ + : 0) + /* * Local Variables: * comment-column: 0 diff --git a/gnu/usr.bin/gas/config/obj-generic.h b/gnu/usr.bin/gas/config/obj-generic.h index 39495d6b398..6c4c8ec0f2c 100644 --- a/gnu/usr.bin/gas/config/obj-generic.h +++ b/gnu/usr.bin/gas/config/obj-generic.h @@ -1,4 +1,4 @@ -/* $OpenBSD: obj-generic.h,v 1.2 1998/02/15 18:49:29 niklas Exp $ */ +/* $OpenBSD: obj-generic.h,v 1.3 1998/02/28 00:52:14 niklas Exp $ */ /* This file is obj-generic.h Copyright (C) 1987-1992 Free Software Foundation, Inc. @@ -57,9 +57,6 @@ typedef void *object_headers; /* symbols have segments */ #define S_GET_SEGMENT(s) (SEG_UNKNOWN) #define S_SET_SEGMENT(s,v) ; - /* symbols have a value */ -#define S_GET_VALUE(s) (0) -#define S_SET_VALUE(s,v) ; /* symbols may be external */ #define S_IS_EXTERNAL(s) (0) #define S_SET_EXTERNAL(s) ; diff --git a/gnu/usr.bin/gas/config/obj-ieee.c b/gnu/usr.bin/gas/config/obj-ieee.c index f04a6809538..33d413e57ac 100644 --- a/gnu/usr.bin/gas/config/obj-ieee.c +++ b/gnu/usr.bin/gas/config/obj-ieee.c @@ -1,4 +1,4 @@ -/* $OpenBSD: obj-ieee.c,v 1.2 1998/02/15 18:49:30 niklas Exp $ */ +/* $OpenBSD: obj-ieee.c,v 1.3 1998/02/28 00:52:15 niklas Exp $ */ /* obj-format for ieee-695 records. Copyright (C) 1991, 1992 Free Software Foundation, Inc. @@ -203,7 +203,15 @@ void DEFUN(do_relocs_for,(idx), if (s) { if ((s->flags & BSF_UNDEFINED) == 0) { to->section = s->section; - to->addend += s->value ; + + /* We can refer directly to the + value field here, rather than + using S_GET_VALUE, because this + is only called after do_symbols, + which sets up the value + field. */ + to->addend += s->value; + to->sym_ptr_ptr = 0; if (to->howto->pcrel_offset) { /* This is a pcrel relocation, the addend should be adjusted */ @@ -257,7 +265,8 @@ static void DEFUN(do_symbols, (abfd), { ptr->sy_symbol.sy.section = (asection *)(segment_info[ptr->sy_symbol.seg].user_stuff); - ptr->sy_symbol.sy.value += ptr->sy_frag->fr_address; + S_SET_VALUE(ptr, S_GET_VALUE(ptr) + + ptr->sy_frag->fr_address); if (ptr->sy_symbol.sy.flags == 0) { ptr->sy_symbol.sy.flags = BSF_LOCAL ; } @@ -276,6 +285,7 @@ static void DEFUN(do_symbols, (abfd), abort(); } } + ptr->sy_symbol.sy.value = S_GET_VALUE(ptr); count++; } symbol_ptr_vec = (asymbol **)malloc((count+1) * sizeof(asymbol *)); @@ -315,14 +325,6 @@ void DEFUN_VOID(bfd_as_write_hook) } - - -S_GET_VALUE(x) -symbolS *x; -{ - return x->sy_symbol.sy.value; -} - S_SET_SEGMENT(x,y) symbolS *x ; int y; @@ -364,13 +366,6 @@ symbolS*x; char *y; { x->sy_symbol.sy.name = y; } -S_SET_VALUE(s,v) -symbolS *s; -long v; -{ - s->sy_symbol.sy.value = v; -} - S_GET_OTHER(x) { abort() ;} S_IS_DEBUG(x) { abort(); } diff --git a/gnu/usr.bin/gas/config/obj-vms.c b/gnu/usr.bin/gas/config/obj-vms.c index e5b101c06a3..10dc83d4e59 100644 --- a/gnu/usr.bin/gas/config/obj-vms.c +++ b/gnu/usr.bin/gas/config/obj-vms.c @@ -1,4 +1,4 @@ -/* $OpenBSD: obj-vms.c,v 1.2 1998/02/15 18:49:32 niklas Exp $ */ +/* $OpenBSD: obj-vms.c,v 1.3 1998/02/28 00:52:17 niklas Exp $ */ /* vms.c -- Write out a VAX/VMS object file Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc. @@ -469,18 +469,6 @@ obj_crawl_symbol_chain (headers) symbolS **symbolPP; int symbol_number = 0; - /* JF deal with forward references first... */ - for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) - { - if (symbolP->sy_forward) - { - S_SET_VALUE (symbolP, S_GET_VALUE (symbolP) - + S_GET_VALUE (symbolP->sy_forward) - + symbolP->sy_forward->sy_frag->fr_address); - symbolP->sy_forward = 0; - } /* if it has a forward reference */ - } /* walk the symbol chain */ - { /* crawl symbol table */ register int symbol_number = 0; @@ -488,7 +476,7 @@ obj_crawl_symbol_chain (headers) symbolPP = &symbol_rootP; /* -> last symbol chain link. */ while ((symbolP = *symbolPP) != NULL) { - S_GET_VALUE (symbolP) += symbolP->sy_frag->fr_address; + resolve_symbol_value (symbolP); /* OK, here is how we decide which symbols go out into the brave new symtab. Symbols that do are: @@ -4421,7 +4409,8 @@ VMS_Check_For_Main () * inserted. */ if (S_GET_VALUE (symbolP) >= 2) - S_GET_VALUE (symbolP) += 6; + S_SET_VALUE (symbolP, + S_GET_VALUE (symbolP) + 6); } } /* @@ -4435,11 +4424,12 @@ VMS_Check_For_Main () S_SET_TYPE (symbolP, N_UNDF); S_GET_OTHER (symbolP) = 0; S_GET_DESC (symbolP) = 0; - S_GET_VALUE (symbolP) = 0; + S_SET_VALUE (symbolP, 0); symbolP->sy_name_offset = 0; symbolP->sy_number = 0; symbolP->sy_frag = New_Frag; - symbolP->sy_forward = 0; + symbolP->sy_resolved = 0; + symbolP->sy_resolving = 0; /* this actually inserts at the beginning of the list */ symbol_append (symbol_rootP, symbolP, &symbol_rootP, &symbol_lastP); diff --git a/gnu/usr.bin/gas/config/obj-vms.h b/gnu/usr.bin/gas/config/obj-vms.h index ea065bb0b94..d78b4c7ea68 100644 --- a/gnu/usr.bin/gas/config/obj-vms.h +++ b/gnu/usr.bin/gas/config/obj-vms.h @@ -1,4 +1,4 @@ -/* $OpenBSD: obj-vms.h,v 1.2 1998/02/15 18:49:33 niklas Exp $ */ +/* $OpenBSD: obj-vms.h,v 1.3 1998/02/28 00:52:18 niklas Exp $ */ /* VMS object file format Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc. @@ -152,8 +152,6 @@ typedef struct nlist obj_symbol_type; /* Symbol table entry */ #define S_IS_STABD(s) (S_GET_NAME(s) == (char *)0) /* Accessors */ -/* The value of the symbol */ -#define S_GET_VALUE(s) (((s)->sy_symbol.n_value)) /* The name of the symbol */ #define S_GET_NAME(s) ((s)->sy_symbol.n_un.n_name) /* The pointer to the string table */ @@ -170,8 +168,6 @@ typedef struct nlist obj_symbol_type; /* Symbol table entry */ #define S_GET_DESC(s) ((s)->sy_symbol.n_desc) /* Modifiers */ -/* Set the value of the symbol */ -#define S_SET_VALUE(s,v) ((s)->sy_symbol.n_value = (unsigned long) (v)) /* Assume that a symbol cannot be simultaneously in more than on segment */ /* set segment */ #define S_SET_SEGMENT(s,seg) ((s)->sy_symbol.n_type &= ~N_TYPE,(s)->sy_symbol.n_type|=SEGMENT_TO_SYMBOL_TYPE(seg)) diff --git a/gnu/usr.bin/gas/config/tc-m88k.c b/gnu/usr.bin/gas/config/tc-m88k.c index 49c293b45c0..adb8d550faf 100644 --- a/gnu/usr.bin/gas/config/tc-m88k.c +++ b/gnu/usr.bin/gas/config/tc-m88k.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tc-m88k.c,v 1.2 1998/02/15 18:49:38 niklas Exp $ */ +/* $OpenBSD: tc-m88k.c,v 1.3 1998/02/28 00:52:20 niklas Exp $ */ /* m88k.c -- Assembler for the Motorola 88000 Contributed by Devon Bowen of Buffalo University @@ -226,6 +226,7 @@ md_assemble (op) char *op; { char *param, *thisfrag; + char c; struct m88k_opcode *format; struct m88k_insn insn; @@ -235,14 +236,46 @@ md_assemble (op) for (param = op; *param != 0 && !isspace (*param); param++) ; - if (*param != 0) - *param++ = 0; + c = *param; + *param++ = '\0'; /* try to find the instruction in the hash table */ if ((format = (struct m88k_opcode *) hash_find (op_hash, op)) == NULL) { - as_fatal ("Invalid mnemonic '%s'", op); + extern struct hash_control *po_hash; + pseudo_typeS *pop; + char *hold; + + /* The m88k assembler does not use `.' before pseudo-ops, for + some reason. So if don't find an opcode, try for a + pseudo-op. */ + pop = (pseudo_typeS *) hash_find (po_hash, op); + + if (pop == NULL) + { + as_bad ("Invalid mnemonic '%s'", op); + return; + } + + /* Restore the character after the opcode. */ + *--param = c; + + /* Now we have to hack. The pseudo-op code expects + input_line_pointer to point to the first non-whitespace + character after the pseudo-op itself. The calling code has + already advanced input_line_pointer to the end of the line + and inserted a null byte. We set things up for the pseudo-op + code, and then prepare to return from this function. */ + hold = input_line_pointer; + *hold = ';'; + input_line_pointer = param; + SKIP_WHITESPACE (); + + (*pop->poc_handler) (pop->poc_val); + + input_line_pointer = hold; + return; } @@ -940,6 +973,13 @@ int nbytes; #ifdef comment +#if 0 + +/* This routine is never called. What is it for? + Ian Taylor, Cygnus Support 13 Jul 1993 */ + +#endif /* 0 */ + void md_number_to_imm (buf, val, nbytes, fixP, seg_type) unsigned char *buf; @@ -1232,6 +1272,13 @@ md_end () #ifdef comment +#if 0 + +/* As far as I can tell, this routine is never called. What is it + doing here? + Ian Taylor, Cygnus Support 13 Jul 1993 */ + + /* * Risc relocations are completely different, so it needs * this machine dependent routine to emit them. @@ -1339,6 +1386,14 @@ relax_addressT segment_address_in_file; } /* tc_aout_fix_to_chars() */ +#endif /* 0 */ + +#if 0 + +/* This routine can be subsumed by s_lcomm in read.c. + Ian Taylor, Cygnus Support 13 Jul 1993 */ + + static void s_bss() { @@ -1397,6 +1452,117 @@ s_bss() return; } +#endif /* 0 */ + +#ifdef M88KCOFF + +/* These functions are needed if we are linking with obj-coffbfd.c. + That file may be replaced by a more BFD oriented version at some + point. If that happens, these functions should be rexamined. + + Ian Lance Taylor, Cygnus Support, 13 July 1993. */ + +/* Given a fixS structure (created by a call to fix_new, above), + return the BFD relocation type to use for it. */ + +short +tc_coff_fix2rtype (fixp) + fixS *fixp; +{ + switch (fixp->fx_r_type) + { + case RELOC_LO16: + return R_LVRT16; + case RELOC_HI16: + return R_HVRT16; + case RELOC_PC16: + return R_PCR16L; + case RELOC_PC26: + return R_PCR26L; + case RELOC_32: + return R_VRT32; + case RELOC_IW16: + return R_VRT16; + default: + abort (); + } +} + +/* Apply a fixS to the object file. Since COFF does not use addends + in relocs, the addend is actually stored directly in the object + file itself. */ + +void +md_apply_fix (fixp, val) + fixS *fixp; + long val; +{ + char *buf; + + buf = fixp->fx_frag->fr_literal + fixp->fx_where; + + switch (fixp->fx_r_type) + { + case RELOC_IW16: + buf[2] = val >> 8; + buf[3] = val; + break; + + case RELOC_LO16: + buf[0] = val >> 8; + buf[1] = val; + break; + + case RELOC_HI16: + buf[0] = val >> 24; + buf[1] = val >> 16; + break; + + case RELOC_PC16: + buf[0] = val >> 10; + buf[1] = val >> 2; + break; + + case RELOC_PC26: + buf[0] |= (val >> 26) & 0x03; + buf[1] = val >> 18; + buf[2] = val >> 10; + buf[3] = val >> 2; + break; + + case RELOC_32: + buf[0] = val >> 24; + buf[1] = val >> 16; + buf[2] = val >> 8; + buf[3] = val; + break; + + default: + abort (); + } +} + +/* Where a PC relative offset is calculated from. On the m88k they + are calculated from just after the instruction. */ + +long +md_pcrel_from (fixp) + fixS *fixp; +{ + switch (fixp->fx_r_type) + { + case RELOC_PC16: + return fixp->fx_frag->fr_address + fixp->fx_where - 2; + case RELOC_PC26: + return fixp->fx_frag->fr_address + fixp->fx_where; + default: + abort (); + } + /*NOTREACHED*/ +} + +#endif /* M88KCOFF */ + /* We have no need to default values of symbols. */ /* ARGSUSED */ diff --git a/gnu/usr.bin/gas/expr.h b/gnu/usr.bin/gas/expr.h index a4e5165c356..a12a4d279cf 100644 --- a/gnu/usr.bin/gas/expr.h +++ b/gnu/usr.bin/gas/expr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: expr.h,v 1.2 1998/02/15 18:48:45 niklas Exp $ */ +/* $OpenBSD: expr.h,v 1.3 1998/02/28 00:51:56 niklas Exp $ */ /* expr.h -> header file for expr.c Copyright (C) 1987, 1992 Free Software Foundation, Inc. @@ -45,13 +45,12 @@ */ typedef struct { - symbolS *X_add_symbol; /* foo */ - symbolS *X_subtract_symbol; /* bar */ - symbolS *X_got_symbol; /* got */ - long X_add_number; /* 42. Must be signed. */ - segT X_seg; /* What segment (expr type)? */ -} -expressionS; + struct symbol *X_add_symbol; /* foo */ + struct symbol *X_subtract_symbol; /* bar */ + struct symbol *X_got_symbol; /* got */ + long X_add_number; /* 42. Must be signed. */ + segT X_seg; /* What segment (expr type)? */ +} expressionS; /* result should be type (expressionS *). */ #define expression(result) expr(0,result) diff --git a/gnu/usr.bin/gas/read.c b/gnu/usr.bin/gas/read.c index a5ee2f6a49a..df16b052a99 100644 --- a/gnu/usr.bin/gas/read.c +++ b/gnu/usr.bin/gas/read.c @@ -1,4 +1,4 @@ -/* $OpenBSD: read.c,v 1.6 1998/02/15 21:08:31 niklas Exp $ */ +/* $OpenBSD: read.c,v 1.7 1998/02/28 00:51:57 niklas Exp $ */ /* read.c - read a source file - @@ -21,7 +21,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef lint -static char rcsid[] = "$OpenBSD: read.c,v 1.6 1998/02/15 21:08:31 niklas Exp $"; +static char rcsid[] = "$OpenBSD: read.c,v 1.7 1998/02/28 00:51:57 niklas Exp $"; #endif #define MASK_CHAR (0xFF) /* If your chars aren't 8 bits, you will @@ -1428,9 +1428,8 @@ symbolS * symbolP; && (S_GET_SEGMENT(exp.X_add_symbol) == S_GET_SEGMENT(exp.X_subtract_symbol))) { if (exp.X_add_symbol->sy_frag != exp.X_subtract_symbol->sy_frag) { - as_bad("Unknown expression: symbols %s and %s are in different frags.", - S_GET_NAME(exp.X_add_symbol), S_GET_NAME(exp.X_subtract_symbol)); - need_pass_2++; + symbolP->sy_value = exp; + break; } exp.X_add_number+=S_GET_VALUE(exp.X_add_symbol) - S_GET_VALUE(exp.X_subtract_symbol); @@ -1463,13 +1462,19 @@ symbolS * symbolP; break; case SEG_PASS1: /* Not an error. Just try another pass. */ - symbolP->sy_forward=exp.X_add_symbol; + symbolP->sy_value.X_add_symbol = exp.X_add_symbol; + symbolP->sy_value.X_subtract_symbol = NULL; + symbolP->sy_value.X_add_number = 0; + symbolP->sy_value.X_seg = SEG_UNKNOWN; as_bad("Unknown expression"); know(need_pass_2 == 1); break; case SEG_UNKNOWN: - symbolP->sy_forward=exp.X_add_symbol; + symbolP->sy_value.X_add_symbol = exp.X_add_symbol; + symbolP->sy_value.X_subtract_symbol = NULL; + symbolP->sy_value.X_add_number = 0; + symbolP->sy_value.X_seg = SEG_UNKNOWN; /* as_warn("unknown symbol"); */ /* need_pass_2 = 1; */ break; diff --git a/gnu/usr.bin/gas/struc-symbol.h b/gnu/usr.bin/gas/struc-symbol.h index 3fef4c8ad50..f3d442d4e0b 100644 --- a/gnu/usr.bin/gas/struc-symbol.h +++ b/gnu/usr.bin/gas/struc-symbol.h @@ -1,4 +1,4 @@ -/* $OpenBSD: struc-symbol.h,v 1.2 1998/02/15 18:48:59 niklas Exp $ */ +/* $OpenBSD: struc-symbol.h,v 1.3 1998/02/28 00:51:59 niklas Exp $ */ /* struct_symbol.h - Internal symbol structure Copyright (C) 1987, 1992 Free Software Foundation, Inc. @@ -32,13 +32,15 @@ struct symbol /* our version of an nlist node */ long sy_number; /* 24 bit symbol number. */ /* Symbol numbers start at 0 and are */ /* unsigned. */ + + /* The value of the symbol. */ + expressionS sy_value; + struct symbol *sy_next; /* forward chain, or NULL */ #ifdef SYMBOLS_NEED_BACKPOINTERS struct symbol *sy_previous; /* backward chain, or NULL */ #endif /* SYMBOLS_NEED_BACKPOINTERS */ struct frag *sy_frag; /* NULL or -> frag this symbol attaches to. */ - struct symbol *sy_forward; /* value is really that of this other symbol */ - /* We will probably want to add a sy_segment here soon. */ #ifdef PIC /* Force symbol into symbol table, even if local */ @@ -55,6 +57,13 @@ struct symbol /* our version of an nlist node */ #define BIND_LOCAL 0 /* currently not used */ #define BIND_GLOBAL 1 /* currently not used */ #define BIND_WEAK 2 + + /* Whether symbol value has been completely resolved (used during + final pass over symbol table). */ + int sy_resolved : 1; + /* Whether the symbol value is currently being resolved (used to + detect loops in symbol dependencies). */ + int sy_resolving : 1; }; typedef struct symbol symbolS; diff --git a/gnu/usr.bin/gas/symbols.c b/gnu/usr.bin/gas/symbols.c index 63fa4e0e944..5e82d9d5f1a 100644 --- a/gnu/usr.bin/gas/symbols.c +++ b/gnu/usr.bin/gas/symbols.c @@ -1,4 +1,4 @@ -/* $OpenBSD: symbols.c,v 1.2 1998/02/15 18:49:01 niklas Exp $ */ +/* $OpenBSD: symbols.c,v 1.3 1998/02/28 00:52:00 niklas Exp $ */ /* symbols.c -symbol table- @@ -21,7 +21,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef lint -static char rcsid[] = "$OpenBSD: symbols.c,v 1.2 1998/02/15 18:49:01 niklas Exp $"; +static char rcsid[] = "$OpenBSD: symbols.c,v 1.3 1998/02/28 00:52:00 niklas Exp $"; #endif #include "as.h" @@ -77,6 +77,69 @@ static local_label_countT static /* Returned to caller, then copied. */ char symbol_name_build[12]; /* used for created names ("4f") */ +/* Resolve the value of a symbol. This is called during the final + pass over the symbol table to resolve any symbols with complex + values. */ + +void +resolve_symbol_value (symp) + symbolS *symp; +{ + if (symp->sy_resolved) + return; + + if (symp->sy_resolving) + { + as_bad ("Symbol definition loop encountered at %s", + S_GET_NAME (symp)); + S_SET_VALUE (symp, (valueT) 0); + } + else + { + symp->sy_resolving = 1; + + if (symp->sy_value.X_seg == SEG_ABSOLUTE) + S_SET_VALUE (symp, S_GET_VALUE (symp) + symp->sy_frag->fr_address); + else if (symp->sy_value.X_seg == SEG_UNKNOWN) + { + resolve_symbol_value (symp->sy_value.X_add_symbol); + +#ifdef obj_frob_forward_symbol + /* Some object formats need to forward the segment. */ + obj_frob_forward_symbol (symp); +#endif + + S_SET_VALUE (symp, + (symp->sy_value.X_add_number + + symp->sy_frag->fr_address + + S_GET_VALUE (symp->sy_value.X_add_symbol))); + S_SET_SEGMENT (symp, S_GET_SEGMENT (symp->sy_value.X_add_symbol)); + } + else if (symp->sy_value.X_seg == SEG_DIFFERENCE) + { + resolve_symbol_value (symp->sy_value.X_add_symbol); + resolve_symbol_value (symp->sy_value.X_subtract_symbol); + if (S_GET_SEGMENT (symp->sy_value.X_add_symbol) + != S_GET_SEGMENT (symp->sy_value.X_subtract_symbol)) + as_bad ("%s is difference of symbols in different sections", + S_GET_NAME (symp)); + S_SET_VALUE (symp, + (symp->sy_value.X_add_number + + symp->sy_frag->fr_address + + S_GET_VALUE (symp->sy_value.X_add_symbol) + - S_GET_VALUE (symp->sy_value.X_subtract_symbol))); + S_SET_SEGMENT (symp, SEG_ABSOLUTE); + } + else + { + /* More cases need to be added here. */ + abort (); + } + } + + symp->sy_resolved = 1; +} + #ifdef LOCAL_LABELS_DOLLAR int local_label_defined[10]; #endif @@ -194,8 +257,6 @@ fragS *frag; /* Associated fragment */ /* symbol_clear_list_pointers(symbolP); uneeded if symbol is born zeroed. */ symbolP->sy_frag = frag; - /* krm: uneeded if symbol is born zeroed. - symbolP->sy_forward = NULL; */ /* JF */ symbolP->sy_number = ~0; symbolP->sy_name_offset = ~0; @@ -645,6 +706,27 @@ char *s; return(symbol_decode); } /* decode_local_label_name() */ +/* Get the value of a symbol. */ + +valueT +S_GET_VALUE (s) + symbolS *s; +{ + if (s->sy_value.X_seg != SEG_ABSOLUTE) + as_bad ("Attempt to get value of unresolved symbol %s", S_GET_NAME (s)); + return (valueT) s->sy_value.X_add_number; +} + +/* Set the value of a symbol. */ + +void +S_SET_VALUE (s, val) + symbolS *s; + valueT val; +{ + s->sy_value.X_seg = SEG_ABSOLUTE; + s->sy_value.X_add_number = (long) val; +} /* * Local Variables: diff --git a/gnu/usr.bin/gas/symbols.h b/gnu/usr.bin/gas/symbols.h index 8f4d317f070..481483096e5 100644 --- a/gnu/usr.bin/gas/symbols.h +++ b/gnu/usr.bin/gas/symbols.h @@ -1,4 +1,4 @@ -/* $OpenBSD: symbols.h,v 1.2 1998/02/15 18:49:02 niklas Exp $ */ +/* $OpenBSD: symbols.h,v 1.3 1998/02/28 00:52:01 niklas Exp $ */ /* symbols.h - @@ -51,6 +51,11 @@ void local_colon(int n); void symbol_begin(void); void symbol_table_insert(symbolS *symbolP); void verify_symbol_chain(symbolS *rootP, symbolS *lastP); +void resolve_symbol_value(symbolS *); + +/* Get and set the values of symbols. These used to be macros. */ +extern valueT S_GET_VALUE(symbolS *); +extern void S_SET_VALUE(symbolS *, valueT); #else /* not __STDC__ */ @@ -66,6 +71,11 @@ void local_colon(); void symbol_begin(); void symbol_table_insert(); void verify_symbol_chain(); +void resolve_symbol_value(); + +/* Get and set the values of symbols. These used to be macros. */ +extern valueT S_GET_VALUE(); +extern void S_SET_VALUE(); #endif /* not __STDC__ */ |