This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH] bug 5543: do not allow register symbols to be global
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: Denys Vlasenko <vda dot linux at googlemail dot com>
- Cc: Binutils <binutils at sourceware dot org>
- Date: Thu, 21 Feb 2008 06:39:16 -0800
- Subject: Re: [PATCH] bug 5543: do not allow register symbols to be global
- References: <200802211239.27444.vda.linux@googlemail.com>
On Thu, Feb 21, 2008 at 12:39:27PM +0100, Denys Vlasenko wrote:
> Hello,
>
> Attached patch fixes bug 5543 for me.
> With this patch:
>
> .globl foo
> .set foo,(%eax)
>
> z.s: Assembler messages:
> z.s:2: Error: attempt to produce global register symbol
>
>
> and
>
> .set foo,(%eax)
> .globl foo
>
> z2.s: Assembler messages:
> z2.s:2: Error: cannot make register symbol global
> --
> vda
> diff -d -urpN src.0/gas/read.c src.1/gas/read.c
> --- src.0/gas/read.c 2008-02-07 09:40:29.000000000 +0100
> +++ src.1/gas/read.c 2008-02-21 12:21:50.000000000 +0100
> @@ -3604,6 +3604,11 @@ pseudo_set (symbolS *symbolP)
> break;
>
> case O_register:
> + if (S_IS_EXTERNAL (symbolP))
> + {
> + as_bad ("attempt to produce global register symbol");
> + return;
> + }
> S_SET_SEGMENT (symbolP, reg_section);
> S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
> set_zero_frag (symbolP);
> diff -d -urpN src.0/gas/symbols.c src.1/gas/symbols.c
> --- src.0/gas/symbols.c 2007-07-12 09:16:39.000000000 +0200
> +++ src.1/gas/symbols.c 2008-02-21 12:24:06.000000000 +0100
> @@ -2184,6 +2184,12 @@ S_SET_EXTERNAL (symbolS *s)
> _("section symbols are already global"));
> return;
> }
> + if (S_GET_SEGMENT (s) == reg_section)
> + {
> + /* Cannot make ".set foo,%reg" symbol global */
> + as_bad ("cannot make register symbol global");
> + return;
> + }
> s->bsym->flags |= BSF_GLOBAL;
> s->bsym->flags &= ~(BSF_LOCAL | BSF_WEAK);
>
It doesn't work for all cases like
.globl bar3
.equ bar3,(%eax+1)
mov bar3,%eax
We get into trouble only when we try to use bar3. This patch catches
all cases. But it doesn't report the correct line number.
H.J.
----
gas/
2008-02-21 H.J. Lu <hongjiu.lu@intel.com>
PR gas/5543
* config/obj-elf.c (elf_obj_validate_symbol_value): New.
* gas/config/obj-elf.h (elf_obj_validate_symbol_value): New.
(obj_validate_symbol_value): Likewise.
* write.c (obj_validate_symbol_value): Define if not defined.
(write_object_file): Call obj_validate_symbol_value to
check symbol value. Stop if there is an error.
gas/testsuite/
2008-02-21 H.J. Lu <hongjiu.lu@intel.com>
PR gas/5543
* gas/i386/i386.exp: Run inval-equ.
* gas/i386/inval-equ.l: New.
* gas/i386/inval-equ.s: Likewise.
--- gas/config/obj-elf.c.reg 2008-02-20 10:18:53.000000000 -0800
+++ gas/config/obj-elf.c 2008-02-21 06:37:33.000000000 -0800
@@ -2326,6 +2326,22 @@ elf_init_stab_section (segT seg)
#endif
obj_elf_init_stab_section (seg);
}
+
+void
+elf_obj_validate_symbol_value (symbolS *symbolP)
+{
+ if (!IS_ELF)
+ return;
+
+ if (symbolP->bsym->section == reg_section)
+ {
+ const char *name = S_GET_NAME (symbolP);
+
+ /* Report error only if we know the symbol name. */
+ if (name != reg_section->name)
+ as_bad (_("Invalid value for symbol `%s'"), name);
+ }
+}
const struct format_ops elf_format_ops =
{
--- gas/config/obj-elf.h.reg 2007-10-30 11:48:38.000000000 -0700
+++ gas/config/obj-elf.h 2008-02-21 06:31:22.000000000 -0800
@@ -235,6 +235,11 @@ extern void elf_pop_insert (void);
#define obj_pop_insert() elf_pop_insert()
#endif
+extern void elf_obj_validate_symbol_value (symbolS *);
+#ifndef obj_validate_symbol_value
+#define obj_validate_symbol_value(s) elf_obj_validate_symbol_value (s)
+#endif
+
#ifndef OBJ_MAYBE_ELF
/* If OBJ_MAYBE_ELF then obj-multi.h will define obj_ecoff_set_ext. */
#define obj_ecoff_set_ext elf_ecoff_set_ext
--- gas/testsuite/gas/i386/i386.exp.reg 2008-02-18 13:10:13.000000000 -0800
+++ gas/testsuite/gas/i386/i386.exp 2008-02-21 06:31:22.000000000 -0800
@@ -148,6 +148,7 @@ if [expr ([istarget "i*86-*-*"] || [ist
run_dump_test "mixed-mode-reloc32"
run_dump_test "att-regs"
run_dump_test "intel-regs"
+ run_list_test "inval-equ" "-al"
}
# This is a PE specific test.
--- gas/testsuite/gas/i386/inval-equ.l.reg 2008-02-21 06:13:14.000000000 -0800
+++ gas/testsuite/gas/i386/inval-equ.l 2008-02-21 06:31:22.000000000 -0800
@@ -0,0 +1,19 @@
+.*: Assembler messages:
+.*:10: Error: .*
+.*:10: Error: .*
+.*:10: Error: .*
+GAS LISTING .*
+
+
+[ ]*1[ ]+\.text
+[ ]*2[ ]+\.globl bar1
+[ ]*3[ ]+\.equ bar1,%eax
+[ ]*4[ ]+\.equ bar2,%eax
+[ ]*5[ ]+\.globl bar2
+[ ]*6[ ]+\?\?\?\? 89C0 mov bar1,%eax
+[ ]*7[ ]+\?\?\?\? 89C0 mov bar2,%eax
+[ ]*8[ ]+\.globl bar3
+[ ]*9[ ]+\.equ bar3,\(%eax\+1\)
+[ ]*10[ ]+\?\?\?\? A12A0000 mov bar3,%eax
+\*\*\*\* Error:Invalid value for symbol `bar3'
+[ ]*10[ ]+00
--- gas/testsuite/gas/i386/inval-equ.s.reg 2008-02-21 06:13:11.000000000 -0800
+++ gas/testsuite/gas/i386/inval-equ.s 2008-02-21 06:31:22.000000000 -0800
@@ -0,0 +1,10 @@
+ .text
+ .globl bar1
+ .equ bar1,%eax
+ .equ bar2,%eax
+ .globl bar2
+ mov bar1,%eax
+ mov bar2,%eax
+ .globl bar3
+ .equ bar3,(%eax+1)
+ mov bar3,%eax
--- gas/write.c.reg 2007-10-30 11:48:38.000000000 -0700
+++ gas/write.c 2008-02-21 06:31:22.000000000 -0800
@@ -1464,6 +1464,10 @@ subsegs_finish (void)
}
}
+#ifndef obj_validate_symbol_value
+#define obj_validate_symbol_value(s)
+#endif
+
/* Write the object file. */
void
@@ -1763,6 +1767,7 @@ write_object_file (void)
as_bad (_("Local symbol `%s' can't be equated to common symbol `%s'"),
name, S_GET_NAME (e->X_add_symbol));
}
+ obj_validate_symbol_value (symp);
symbol_remove (symp, &symbol_rootP, &symbol_lastP);
continue;
}
@@ -1816,6 +1821,8 @@ write_object_file (void)
target-specific muck with it; it's ready for output. */
if (symbol_get_bfdsym (symp)->flags & BSF_WARNING)
skip_next_symbol = TRUE;
+
+ obj_validate_symbol_value (symp);
}
}
@@ -1830,6 +1837,10 @@ write_object_file (void)
obj_adjust_symtab ();
#endif
+ /* Stop if there is an error. */
+ if (had_errors ())
+ return;
+
/* Now that all the sizes are known, and contents correct, we can
start writing to the file. */
set_symtab ();