This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] PR gas/19896: Don't change defined symbol to undefined


We shouldn't allow changing defined symbol to undefined due to bad
input.

OK for master?

H.J.
---
	PR gas/19896
	* read.c (pseudo_set_1): New prototype.
	(assign_symbol): Call pseudo_set_1 instead of pseudo_set.
	(pseudo_set): Renamed to ...
	(pseudo_set_1): This.  Don't change defined symbol to undefined.
	(pseudo_set): New.  Call pseudo_set_1.
	* testsuite/gas/elf/elf.exp: Run pr19896.
	* testsuite/gas/elf/pr19896.d: New file.
	* testsuite/gas/elf/pr19896.l: Likewise.
	* testsuite/gas/elf/pr19896.s: Likewise.
---
 gas/read.c                      | 18 +++++++++++++++++-
 gas/testsuite/gas/elf/elf.exp   |  2 ++
 gas/testsuite/gas/elf/pr19896.d |  1 +
 gas/testsuite/gas/elf/pr19896.l |  3 +++
 gas/testsuite/gas/elf/pr19896.s |  6 ++++++
 5 files changed, 29 insertions(+), 1 deletion(-)
 create mode 100644 gas/testsuite/gas/elf/pr19896.d
 create mode 100644 gas/testsuite/gas/elf/pr19896.l
 create mode 100644 gas/testsuite/gas/elf/pr19896.s

diff --git a/gas/read.c b/gas/read.c
index 35d44c1..67646e6 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -248,6 +248,7 @@ static void pobegin (void);
 static size_t get_non_macro_line_sb (sb *);
 static void generate_file_debug (void);
 static char *_find_end_of_line (char *, int, int, int);
+static void pseudo_set_1 (symbolS *, int);
 
 void
 read_begin (void)
@@ -3211,6 +3212,7 @@ static void
 assign_symbol (char *name, int mode)
 {
   symbolS *symbolP;
+  int redefined;
 
   if (name[0] == '.' && name[1] == '\0')
     {
@@ -3249,12 +3251,14 @@ assign_symbol (char *name, int mode)
 #endif
     }
 
+  redefined = 0;
   if (S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP))
     {
       if ((mode != 0 || !S_IS_VOLATILE (symbolP))
 	  && !S_CAN_BE_REDEFINED (symbolP))
 	{
 	  as_bad (_("symbol `%s' is already defined"), name);
+	  redefined = 1;
 	  symbolP = symbol_clone (symbolP, 0);
 	}
       /* If the symbol is volatile, copy the symbol and replace the
@@ -3269,7 +3273,7 @@ assign_symbol (char *name, int mode)
   else if (mode < 0)
     S_SET_FORWARD_REF (symbolP);
 
-  pseudo_set (symbolP);
+  pseudo_set_1 (symbolP, redefined);
 }
 
 /* Handle the .equ, .equiv, .eqv, and .set directives.  If EQUIV is 1,
@@ -3776,6 +3780,12 @@ set_zero_frag (symbolS *symbolP)
 void
 pseudo_set (symbolS *symbolP)
 {
+  pseudo_set_1 (symbolP, 0);
+}
+
+static void
+pseudo_set_1 (symbolS *symbolP, int redefined)
+{
   expressionS exp;
   segT seg;
 
@@ -3847,6 +3857,12 @@ pseudo_set (symbolS *symbolP)
       /* For x=undef+const, create an expression symbol.
 	 For x=x+const, just update x except when x is an undefined symbol
 	 For x=defined+const, evaluate x.  */
+      if (redefined && seg == undefined_section)
+	{
+	  as_bad ("can't change defined symbol `%s' to undefined",
+		  S_GET_NAME (symbolP));
+	  return;
+	}
       if (symbolP == exp.X_add_symbol
 	  && (seg != undefined_section
 	      || !symbol_constant_p (symbolP)))
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index e4ca205..08dda91 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -228,6 +228,8 @@ if { [is_elf_format] } then {
 
     run_dump_test "bignums"
     
+    run_dump_test "pr19896"
+
     load_lib gas-dg.exp
     dg-init
     dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/err-*.s $srcdir/$subdir/warn-*.s]] "" ""
diff --git a/gas/testsuite/gas/elf/pr19896.d b/gas/testsuite/gas/elf/pr19896.d
new file mode 100644
index 0000000..59ba79c
--- /dev/null
+++ b/gas/testsuite/gas/elf/pr19896.d
@@ -0,0 +1 @@
+#error-output: pr19896.l
diff --git a/gas/testsuite/gas/elf/pr19896.l b/gas/testsuite/gas/elf/pr19896.l
new file mode 100644
index 0000000..fdce1be
--- /dev/null
+++ b/gas/testsuite/gas/elf/pr19896.l
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:6: Error: symbol `mempcpy' is already defined
+.*:6: Error: can't change defined symbol `mempcpy' to undefined
diff --git a/gas/testsuite/gas/elf/pr19896.s b/gas/testsuite/gas/elf/pr19896.s
new file mode 100644
index 0000000..92fbe11
--- /dev/null
+++ b/gas/testsuite/gas/elf/pr19896.s
@@ -0,0 +1,6 @@
+	.globl mempcpy
+	.type mempcpy,%function
+mempcpy:
+	.byte 0
+	.size mempcpy,.-mempcpy
+	mempcpy = __mempcpy
-- 
2.5.5


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]