This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] PR gas/19896: Don't change defined symbol to undefined
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: binutils at sourceware dot org
- Date: Fri, 1 Apr 2016 08:52:39 -0700
- Subject: [PATCH] PR gas/19896: Don't change defined symbol to undefined
- Authentication-results: sourceware.org; auth=none
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
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