aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog14
-rw-r--r--gas/as.c2
-rw-r--r--gas/expr.c2
-rw-r--r--gas/read.c2
-rw-r--r--gas/symbols.c24
-rw-r--r--gas/symbols.h2
6 files changed, 43 insertions, 3 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 374c60e..e8e58fd 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,19 @@
2010-12-01 Maciej W. Rozycki <macro@codesourcery.com>
+ * symbols.h (dot_symbol): New declaration.
+ (dot_symbol_init): New prototype.
+ * symbols.c (dot_symbol): New variable.
+ (symbol_clone): Assert it's not dot_symbol being cloned.
+ (dot_symbol_init): New function.
+ (symbol_clone_if_forward_ref): Create a new temporary symbol
+ when trying to clone dot_symbol.
+ * expr.c (current_location): Refer to dot_symbol instead of
+ making a new temporary symbol.
+ * read.c (read_a_source_file): Update dot_symbol as we go.
+ * as.c (main): Call dot_symbol_init.
+
+2010-12-01 Maciej W. Rozycki <macro@codesourcery.com>
+
* symbols.c (symbol_clone_if_forward_ref): Don't limit cloning
to expr_section symbols; clone all equated symbols. Clear
sy_resolving of the cloned copy.
diff --git a/gas/as.c b/gas/as.c
index d9aa6e2..4937351 100644
--- a/gas/as.c
+++ b/gas/as.c
@@ -1181,6 +1181,8 @@ main (int argc, char ** argv)
output_file_create (out_file_name);
gas_assert (stdoutput != 0);
+ dot_symbol_init ();
+
#ifdef tc_init_after_args
tc_init_after_args ();
#endif
diff --git a/gas/expr.c b/gas/expr.c
index 620fdce..215b2ba 100644
--- a/gas/expr.c
+++ b/gas/expr.c
@@ -705,7 +705,7 @@ current_location (expressionS *expressionp)
else
{
expressionp->X_op = O_symbol;
- expressionp->X_add_symbol = symbol_temp_new_now ();
+ expressionp->X_add_symbol = &dot_symbol;
expressionp->X_add_number = 0;
}
}
diff --git a/gas/read.c b/gas/read.c
index bd3fa58..ad9363a 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -629,6 +629,7 @@ read_a_source_file (char *name)
was_new_line = is_end_of_line[(unsigned char) input_line_pointer[-1]];
if (was_new_line)
{
+ symbol_set_value_now (&dot_symbol);
#ifdef md_start_line_hook
md_start_line_hook ();
#endif
@@ -1128,6 +1129,7 @@ read_a_source_file (char *name)
md_after_pass_hook ();
#endif
}
+ symbol_set_value_now (&dot_symbol);
quit:
diff --git a/gas/symbols.c b/gas/symbols.c
index e432b86..5fae547 100644
--- a/gas/symbols.c
+++ b/gas/symbols.c
@@ -48,6 +48,7 @@ static struct hash_control *local_hash;
symbolS *symbol_rootP;
symbolS *symbol_lastP;
symbolS abs_symbol;
+symbolS dot_symbol;
#ifdef DEBUG_SYMS
#define debug_verify_symchain verify_symbol_chain
@@ -557,6 +558,9 @@ symbol_clone (symbolS *orgsymP, int replace)
symbolS *newsymP;
asymbol *bsymorg, *bsymnew;
+ /* Make sure we never clone the dot special symbol. */
+ gas_assert (orgsymP != &dot_symbol);
+
/* Running local_symbol_convert on a clone that's not the one currently
in local_hash would incorrectly replace the hash entry. Thus the
symbol must be converted here. Note that the rest of the function
@@ -658,8 +662,13 @@ symbol_clone_if_forward_ref (symbolS *symbolP, int is_forward)
|| add_symbol != symbolP->sy_value.X_add_symbol
|| op_symbol != symbolP->sy_value.X_op_symbol)
{
- symbolP = symbol_clone (symbolP, 0);
- symbolP->sy_resolving = 0;
+ if (symbolP != &dot_symbol)
+ {
+ symbolP = symbol_clone (symbolP, 0);
+ symbolP->sy_resolving = 0;
+ }
+ else
+ symbolP = symbol_temp_new_now ();
}
symbolP->sy_value.X_add_symbol = add_symbol;
@@ -2749,6 +2758,17 @@ symbol_begin (void)
if (LOCAL_LABELS_FB)
fb_label_init ();
}
+
+void
+dot_symbol_init (void)
+{
+ dot_symbol.bsym = bfd_make_empty_symbol (stdoutput);
+ if (dot_symbol.bsym == NULL)
+ as_fatal ("bfd_make_empty_symbol: %s", bfd_errmsg (bfd_get_error ()));
+ dot_symbol.bsym->name = ".";
+ dot_symbol.sy_forward_ref = 1;
+ dot_symbol.sy_value.X_op = O_constant;
+}
int indent_level;
diff --git a/gas/symbols.h b/gas/symbols.h
index 377a130..1d5b2a3 100644
--- a/gas/symbols.h
+++ b/gas/symbols.h
@@ -28,6 +28,7 @@ extern symbolS *symbol_rootP; /* all the symbol nodes */
extern symbolS *symbol_lastP; /* last struct symbol we made, or NULL */
extern symbolS abs_symbol;
+extern symbolS dot_symbol;
extern int symbol_table_frozen;
@@ -60,6 +61,7 @@ symbolS *symbol_temp_make (void);
symbolS *colon (const char *sym_name);
void local_colon (int n);
void symbol_begin (void);
+void dot_symbol_init (void);
void symbol_print_statistics (FILE *);
void symbol_table_insert (symbolS * symbolP);
valueT resolve_symbol_value (symbolS *);