summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>1998-02-28 00:52:21 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>1998-02-28 00:52:21 +0000
commitaec8fae7b71e7994f4fc91c851ee819c8e3a51d9 (patch)
tree738a29567df2714c4663ec36767197634909609e
parentc3a25357ea4388e10eda41500b43ed181dfab2cb (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.h5
-rw-r--r--gnu/usr.bin/gas/config/obj-aout.c24
-rw-r--r--gnu/usr.bin/gas/config/obj-aout.h6
-rw-r--r--gnu/usr.bin/gas/config/obj-bout.c15
-rw-r--r--gnu/usr.bin/gas/config/obj-bout.h6
-rw-r--r--gnu/usr.bin/gas/config/obj-coff.c43
-rw-r--r--gnu/usr.bin/gas/config/obj-coff.h14
-rw-r--r--gnu/usr.bin/gas/config/obj-coffbfd.c56
-rw-r--r--gnu/usr.bin/gas/config/obj-coffbfd.h29
-rw-r--r--gnu/usr.bin/gas/config/obj-generic.h5
-rw-r--r--gnu/usr.bin/gas/config/obj-ieee.c31
-rw-r--r--gnu/usr.bin/gas/config/obj-vms.c24
-rw-r--r--gnu/usr.bin/gas/config/obj-vms.h6
-rw-r--r--gnu/usr.bin/gas/config/tc-m88k.c174
-rw-r--r--gnu/usr.bin/gas/expr.h15
-rw-r--r--gnu/usr.bin/gas/read.c19
-rw-r--r--gnu/usr.bin/gas/struc-symbol.h15
-rw-r--r--gnu/usr.bin/gas/symbols.c90
-rw-r--r--gnu/usr.bin/gas/symbols.h12
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__ */