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] elf directive parsing fix


Hi,
Until this patch, assembling this elf directive:
   .hidden
would result in an obscure linker failure of the form:
   "hidden symbol '' isn't defined"

Elf directives which expect a symbolic argument but don't get one, were
ignored by the assembler. However, empty symbols were created for the
missing arguments. These empty symbols cannot be resolved by the linker
and since they are nameless, the error message appears garbled.

I added a routine to reject such cases and issue an error. This new
routine is a wrapper around the oft-repeated code to parse the input
line and call symbol_find_or_make.

Tested with arm-eabi.  I do not yet have write access but someone else
here at CodeSourcery will be able to apply this patch.
Ok?

Rhonda Wittels
CodeSourcery

2010-07-14 Rhonda Wittels <rhonda@codesourcery.com>

	* config/obj-elf.c (get_sym_from_input_line_and_check): New
	function to catch missing pseudo-op arguments.
	(obj_elf_local): Call new function.
	(obj_elf_weak): Likewise.
	(obj_elf_visibility): Likewise.
	(obj_elf_vtable_entry): Likewise.
	(obj_elf_type): Likewise.

	testsuite/
	* gas/elf/pseudo.s: New.
	* gas/elf/pseudo.l: New.
	* gas/elf/pseudo.d: New.
	* gas/elf/elf.exp: Run the new test.

Index: config/obj-elf.c
===================================================================
RCS file: /cvs/src/src/gas/config/obj-elf.c,v
retrieving revision 1.127
diff -c -3 -p -r1.127 obj-elf.c
*** config/obj-elf.c	18 May 2010 03:31:04 -0000	1.127
--- config/obj-elf.c	14 Jul 2010 14:00:56 -0000
*************** obj_elf_lcomm (int ignore ATTRIBUTE_UNUS
*** 393,412 ****
      symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
  }

  static void
  obj_elf_local (int ignore ATTRIBUTE_UNUSED)
  {
-   char *name;
    int c;
    symbolS *symbolP;

    do
      {
!       name = input_line_pointer;
!       c = get_symbol_end ();
!       symbolP = symbol_find_or_make (name);
!       *input_line_pointer = c;
!       SKIP_WHITESPACE ();
        S_CLEAR_EXTERNAL (symbolP);
        symbol_get_obj (symbolP)->local = 1;
        if (c == ',')
--- 393,428 ----
      symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
  }

+ static symbolS *
+ get_sym_from_input_line_and_check (void)
+ {
+   char *name;
+   char c;
+   symbolS *sym;
+
+   name = input_line_pointer;
+   c = get_symbol_end ();
+   sym = symbol_find_or_make (name);
+   *input_line_pointer = c;
+   SKIP_WHITESPACE ();
+
+   /* There is no symbol name if input_line_pointer has not moved.  */
+   if (name == input_line_pointer) {
+     as_bad (_("Missing symbol name in directive"));
+   }
+   return sym;
+ }
+
  static void
  obj_elf_local (int ignore ATTRIBUTE_UNUSED)
  {
    int c;
    symbolS *symbolP;

    do
      {
!       symbolP = get_sym_from_input_line_and_check();
!       c = *input_line_pointer;
        S_CLEAR_EXTERNAL (symbolP);
        symbol_get_obj (symbolP)->local = 1;
        if (c == ',')
*************** obj_elf_local (int ignore ATTRIBUTE_UNUS
*** 424,440 ****
  static void
  obj_elf_weak (int ignore ATTRIBUTE_UNUSED)
  {
-   char *name;
    int c;
    symbolS *symbolP;

    do
      {
!       name = input_line_pointer;
!       c = get_symbol_end ();
!       symbolP = symbol_find_or_make (name);
!       *input_line_pointer = c;
!       SKIP_WHITESPACE ();
        S_SET_WEAK (symbolP);
        symbol_get_obj (symbolP)->local = 1;
        if (c == ',')
--- 440,452 ----
  static void
  obj_elf_weak (int ignore ATTRIBUTE_UNUSED)
  {
    int c;
    symbolS *symbolP;

    do
      {
!       symbolP = get_sym_from_input_line_and_check();
!       c = *input_line_pointer;
        S_SET_WEAK (symbolP);
        symbol_get_obj (symbolP)->local = 1;
        if (c == ',')
*************** obj_elf_weak (int ignore ATTRIBUTE_UNUSE
*** 452,458 ****
  static void
  obj_elf_visibility (int visibility)
  {
-   char *name;
    int c;
    symbolS *symbolP;
    asymbol *bfdsym;
--- 464,469 ----
*************** obj_elf_visibility (int visibility)
*** 460,471 ****

    do
      {
!       name = input_line_pointer;
!       c = get_symbol_end ();
!       symbolP = symbol_find_or_make (name);
!       *input_line_pointer = c;
!
!       SKIP_WHITESPACE ();

        bfdsym = symbol_get_bfdsym (symbolP);
        elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
--- 471,477 ----

    do
      {
!       symbolP = get_sym_from_input_line_and_check ();

        bfdsym = symbol_get_bfdsym (symbolP);
        elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
*************** obj_elf_visibility (int visibility)
*** 475,480 ****
--- 481,487 ----
        elfsym->internal_elf_sym.st_other &= ~3;
        elfsym->internal_elf_sym.st_other |= visibility;

+       c = *input_line_pointer;
        if (c == ',')
  	{
  	  input_line_pointer ++;
*************** obj_elf_symver (int ignore ATTRIBUTE_UNU
*** 1242,1255 ****
    char old_lexat;
    symbolS *sym;

!   name = input_line_pointer;
!   c = get_symbol_end ();
!
!   sym = symbol_find_or_make (name);

-   *input_line_pointer = c;
-
-   SKIP_WHITESPACE ();
    if (*input_line_pointer != ',')
      {
        as_bad (_("expected comma after name in .symver"));
--- 1249,1256 ----
    char old_lexat;
    symbolS *sym;

! sym = get_sym_from_input_line_and_check ();

    if (*input_line_pointer != ',')
      {
        as_bad (_("expected comma after name in .symver"));
*************** obj_elf_vtable_inherit (int ignore ATTRI
*** 1378,1397 ****
  struct fix *
  obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
  {
-   char *name;
    symbolS *sym;
    offsetT offset;
-   char c;

    if (*input_line_pointer == '#')
      ++input_line_pointer;

!   name = input_line_pointer;
!   c = get_symbol_end ();
!   sym = symbol_find_or_make (name);
!   *input_line_pointer = c;
!
!   SKIP_WHITESPACE ();
    if (*input_line_pointer != ',')
      {
        as_bad (_("expected comma after name in .vtable_entry"));
--- 1379,1391 ----
  struct fix *
  obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
  {
    symbolS *sym;
    offsetT offset;

    if (*input_line_pointer == '#')
      ++input_line_pointer;

!   sym = get_sym_from_input_line_and_check ();
    if (*input_line_pointer != ',')
      {
        as_bad (_("expected comma after name in .vtable_entry"));
*************** obj_elf_type_name (char *cp)
*** 1613,1632 ****
  static void
  obj_elf_type (int ignore ATTRIBUTE_UNUSED)
  {
-   char *name;
    char c;
    int type;
    const char *type_name;
    symbolS *sym;
    elf_symbol_type *elfsym;

!   name = input_line_pointer;
!   c = get_symbol_end ();
!   sym = symbol_find_or_make (name);
    elfsym = (elf_symbol_type *) symbol_get_bfdsym (sym);
-   *input_line_pointer = c;

-   SKIP_WHITESPACE ();
    if (*input_line_pointer == ',')
      ++input_line_pointer;

--- 1607,1622 ----
  static void
  obj_elf_type (int ignore ATTRIBUTE_UNUSED)
  {
    char c;
    int type;
    const char *type_name;
    symbolS *sym;
    elf_symbol_type *elfsym;

!   sym = get_sym_from_input_line_and_check ();
!   c = *input_line_pointer;
    elfsym = (elf_symbol_type *) symbol_get_bfdsym (sym);

    if (*input_line_pointer == ',')
      ++input_line_pointer;

Index: testsuite/gas/elf/elf.exp
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/elf/elf.exp,v
retrieving revision 1.59
diff -c -3 -p -r1.59 elf.exp
*** testsuite/gas/elf/elf.exp	5 Jul 2010 15:07:20 -0000	1.59
--- testsuite/gas/elf/elf.exp	14 Jul 2010 14:00:57 -0000
*************** if { ([istarget "*-*-*elf*"]		
*** 127,132 ****
--- 127,133 ----
  	    run_dump_test equ-reloc
  	}
      }
+     run_dump_test "pseudo"
      run_dump_test "section0"
      run_dump_test "section1"
      if {! [istarget "h8300-*-*"]} then {
Index: testsuite/gas/elf/pseudo.d
===================================================================
RCS file: testsuite/gas/elf/pseudo.d
diff -N testsuite/gas/elf/pseudo.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gas/elf/pseudo.d	14 Jul 2010 14:00:57 -0000
***************
*** 0 ****
--- 1,2 ----
+ #name: Ill-formed directives
+ #error-output: pseudo.l
Index: testsuite/gas/elf/pseudo.l
===================================================================
RCS file: testsuite/gas/elf/pseudo.l
diff -N testsuite/gas/elf/pseudo.l
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gas/elf/pseudo.l	14 Jul 2010 14:00:57 -0000
***************
*** 0 ****
--- 1,12 ----
+ [^:]*: Assembler messages:
+ [^:]*:2: Error: Missing symbol name in directive
+ [^:]*:4: Error: Missing symbol name in directive
+ [^:]*:6: Error: Missing symbol name in directive
+ [^:]*:8: Error: Missing symbol name in directive
+ [^:]*:10: Error: Missing symbol name in directive
+ [^:]*:12: Error: Missing symbol name in directive
+ [^:]*:14: Error: Missing symbol name in directive
+ [^:]*:14: Error: expected comma after name in .symver
+ [^:]*:16: Error: Missing symbol name in directive
+ [^:]*:18: Error: Missing symbol name in directive
+ [^:]*:18: Error: unrecognized symbol type ""
Index: testsuite/gas/elf/pseudo.s
===================================================================
RCS file: testsuite/gas/elf/pseudo.s
diff -N testsuite/gas/elf/pseudo.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gas/elf/pseudo.s	14 Jul 2010 14:00:57 -0000
***************
*** 0 ****
--- 1,18 ----
+ 	.hidden h1n1
+ 	.hidden
+ 	# next line has spaces
+ 	.hidden
+ 	# next line has tabs
+ 	.hidden			
+ 	.internal i2
+ 	.internal
+ 	.protected porpoise
+ 	.protected
+ 	.local foo
+ 	.local
+ 	.symver foo, foo@version1
+ 	.symver
+ 	.weak wimp
+ 	.weak
+ 	.type foo1,object
+ 	.type


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