2008-02-20 H.J. Lu 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. * obj.h (obj_validate_symbol_value): New. * read.c (assign_symbol): Call obj_validate_symbol_value. * symbols.c (resolve_symbol_value): Likewise. * write.c (write_object_file): Stop if there is an error. --- gas/config/obj-elf.c.reg 2008-02-20 10:18:53.000000000 -0800 +++ gas/config/obj-elf.c 2008-02-20 15:29:24.000000000 -0800 @@ -2326,6 +2326,23 @@ elf_init_stab_section (segT seg) #endif obj_elf_init_stab_section (seg); } + +void +elf_obj_validate_symbol_value (symbolS *symbolP) +{ + char *file; + unsigned int line; + + if (!symbolP || !IS_ELF) + return; + + if (symbolP->bsym->section == reg_section) + { + /* Report error only if we know where it is. */ + if (expr_symbol_where (symbolP, &file, &line)) + as_bad_where (file, line, _("Invalid symbol value.")); + } +} 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-20 14:39:45.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/obj.h.reg 2007-10-30 11:48:37.000000000 -0700 +++ gas/obj.h 2008-02-20 14:59:24.000000000 -0800 @@ -34,6 +34,10 @@ void obj_read_begin_hook (void); void obj_symbol_new_hook (symbolS * symbolP); #endif +#ifndef obj_validate_symbol_value +#define obj_validate_symbol_value(s) +#endif + void obj_symbol_to_chars (char **where, symbolS * symbolP); extern const pseudo_typeS obj_pseudo_table[]; --- gas/read.c.reg 2008-02-08 09:02:19.000000000 -0800 +++ gas/read.c 2008-02-20 14:59:55.000000000 -0800 @@ -3020,6 +3020,7 @@ assign_symbol (char *name, int mode) S_SET_FORWARD_REF (symbolP); pseudo_set (symbolP); + obj_validate_symbol_value (symbolP); } /* Handle the .equ, .equiv, .eqv, and .set directives. If EQUIV is 1, --- gas/symbols.c.reg 2008-02-20 14:38:33.000000000 -0800 +++ gas/symbols.c 2008-02-20 15:01:34.000000000 -0800 @@ -1415,7 +1415,10 @@ resolve_symbol_value (symbolS *symp) } if (finalize_syms) - S_SET_VALUE (symp, final_val); + { + obj_validate_symbol_value (symp); + S_SET_VALUE (symp, final_val); + } exit_dont_set_value: /* Always set the segment, even if not finalizing the value. --- gas/write.c.reg 2007-10-30 11:48:38.000000000 -0700 +++ gas/write.c 2008-02-20 15:22:12.000000000 -0800 @@ -1830,6 +1830,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 ();