add symbol qualifiers for mach-o to bfd/gas
authorIain Sandoe <iain@codesourcery.com>
Mon, 9 Jan 2012 10:47:50 +0000 (10:47 +0000)
committerIain Sandoe <iain@codesourcery.com>
Mon, 9 Jan 2012 10:47:50 +0000 (10:47 +0000)
bfd:

* mach-o.c (bfd_mach_o_bfd_copy_private_symbol_data): Implement.
(bfd_mach_o_write_symtab): Remove handling for indirect syms.
(bfd_mach_o_primary_symbol_sort_key): Likewise.
(bfd_mach_o_cf_symbols): Likewise.
(bfd_mach_o_sort_symbol_table): Remove.
(bfd_mach_o_mangle_symbols): Adjust arguments, remove handling
for indirect and dysymtab counts.  Do the symbol sorting here.
(bfd_mach_o_build_dysymtab_command): Count the symbol types here.
Make the indirect symbols a TODO.
(bfd_mach_o_build_commands): Adjust call to bfd_mach_o_mangle_symbols.
(bfd_mach_o_make_empty_symbol): Specifically flag unset symbols with
a non-zero value.
(bfd_mach_o_read_symtab_symbol): Record the symbol index.
(bfd_mach_o_read_symtab_symbol): Adjust recording of global status.
* mach-o.h (mach_o_data_struct): Remove indirect and dysymtab entries.
(IS_MACHO_INDIRECT): Remove.
(SYM_MACHO_FIELDS_UNSET, SYM_MACHO_FIELDS_NOT_VALIDATED): New.

gas:

* config/obj-macho.c (obj_mach_o_weak): Remove.
(obj_mach_o_common_parse): Set symbol qualifiers.
(LAZY, REFE): New macros.
(obj_mach_o_symbol_type): New enum.
(obj_mach_o_set_symbol_qualifier): New.
(obj_mach_o_sym_qual): New.
(mach_o_pseudo_table): Add symbol qualifiers, set indirect_symbol to
a dummy function.
(obj_mach_o_type_for_symbol): New.
(obj_macho_frob_label): New.
(obj_macho_frob_symbol): New.
* config/obj-macho.h (S_SET_ALIGN): Amend temorary var name.
(obj_frob_label, obj_macho_frob_label): Declare.
(obj_frob_symbol, obj_macho_frob_symbol): Declare.

gas/testsuite:

* gas/mach-o/err-syms-1.s: New.
* gas/mach-o/err-syms-2.s: New.
* gas/mach-o/err-syms-3.s: New.
* gas/mach-o/symbols-2.d: New.
* gas/mach-o/symbols-2.s: New.
* gas/mach-o/symbols-3.s: New.
* gas/mach-o/symbols-4.s: New.
* gas/mach-o/symbols-5.d: New.
* gas/mach-o/symbols-5.s: New.

16 files changed:
bfd/ChangeLog
bfd/mach-o.c
bfd/mach-o.h
gas/ChangeLog
gas/config/obj-macho.c
gas/config/obj-macho.h
gas/testsuite/ChangeLog
gas/testsuite/gas/mach-o/err-syms-1.s [new file with mode: 0644]
gas/testsuite/gas/mach-o/err-syms-2.s [new file with mode: 0644]
gas/testsuite/gas/mach-o/err-syms-3.s [new file with mode: 0644]
gas/testsuite/gas/mach-o/symbols-2.d [new file with mode: 0644]
gas/testsuite/gas/mach-o/symbols-2.s [new file with mode: 0644]
gas/testsuite/gas/mach-o/symbols-3.s [new file with mode: 0644]
gas/testsuite/gas/mach-o/symbols-4.s [new file with mode: 0644]
gas/testsuite/gas/mach-o/symbols-5.d [new file with mode: 0644]
gas/testsuite/gas/mach-o/symbols-5.s [new file with mode: 0644]

index c5b2a1b9b8832497239f097ec252561eba2de960..d820ad24c3ea34caea506741b9dd2e6ef4f11440 100644 (file)
@@ -1,3 +1,23 @@
+2012-01-09  Iain Sandoe  <idsandoe@googlemail.com>
+
+       * mach-o.c (bfd_mach_o_bfd_copy_private_symbol_data): Implement.
+       (bfd_mach_o_write_symtab): Remove handling for indirect syms.
+       (bfd_mach_o_primary_symbol_sort_key): Likewise.
+       (bfd_mach_o_cf_symbols): Likewise.
+       (bfd_mach_o_sort_symbol_table): Remove.
+       (bfd_mach_o_mangle_symbols): Adjust arguments, remove handling
+       for indirect and dysymtab counts.  Do the symbol sorting here.
+       (bfd_mach_o_build_dysymtab_command): Count the symbol types here.
+       Make the indirect symbols a TODO.
+       (bfd_mach_o_build_commands): Adjust call to bfd_mach_o_mangle_symbols.
+       (bfd_mach_o_make_empty_symbol): Specifically flag unset symbols with
+       a non-zero value.
+       (bfd_mach_o_read_symtab_symbol): Record the symbol index.
+       (bfd_mach_o_read_symtab_symbol): Adjust recording of global status.
+       * mach-o.h (mach_o_data_struct): Remove indirect and dysymtab entries.
+       (IS_MACHO_INDIRECT): Remove.
+       (SYM_MACHO_FIELDS_UNSET, SYM_MACHO_FIELDS_NOT_VALIDATED): New.
+
 2012-01-06  Nick Clifton  <nickc@redhat.com>
 
        PR binutils/13121
index 86012d5d0764629f030bada1fa58949fa319c0cd..07ca65a1f5df367d7cfd4ffc9fe5e47b9d48d3e2 100644 (file)
@@ -533,10 +533,17 @@ bfd_mach_o_section_get_nbr_indirect (bfd *abfd, bfd_mach_o_section *sec)
 
 bfd_boolean
 bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
-                                        asymbol *isymbol ATTRIBUTE_UNUSED,
+                                        asymbol *isymbol,
                                         bfd *obfd ATTRIBUTE_UNUSED,
-                                        asymbol *osymbol ATTRIBUTE_UNUSED)
+                                        asymbol *osymbol)
 {
+  bfd_mach_o_asymbol *os, *is;
+  os = (bfd_mach_o_asymbol *)osymbol;
+  is = (bfd_mach_o_asymbol *)isymbol;
+  os->n_type = is->n_type;
+  os->n_sect = is->n_sect;
+  os->n_desc = is->n_desc;
+  os->symbol.udata.i = is->symbol.udata.i;
   return TRUE;
 }
 
@@ -1400,22 +1407,6 @@ bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
     {
       bfd_size_type str_index;
       bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
-
-      /* For a bare indirect symbol, the system tools expect that the symbol
-        value will be the string table offset for its referenced counterpart.
-        
-        Normally, indirect syms will not be written this way, but rather as
-        part of the dysymtab command.
-        
-        In either case, correct operation depends on the symbol table being
-        sorted such that the indirect symbols are at the end (since the 
-        string table index is filled in below).  */
-
-      if (IS_MACHO_INDIRECT (s->n_type))
-       /* A pointer to the referenced symbol will be stored in the udata
-          field.  Use that to find the string index.  */
-       s->symbol.value = 
-           ((bfd_mach_o_asymbol *)s->symbol.udata.p)->symbol.udata.i;
      
       if (s->symbol.name == 0 || s->symbol.name[0] == '\0')
        /* An index of 0 always means the empty string.  */
@@ -1423,11 +1414,6 @@ bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
       else
         {
           str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
-          /* Record the string index.  This can be looked up by an indirect sym
-            which retains a pointer to its referenced counterpart, until it is
-            actually output.  */
-         if (IS_MACHO_INDIRECT (s->n_type))
-           s->symbol.udata.i = str_index;
 
           if (str_index == (bfd_size_type) -1)
             goto err;
@@ -1673,28 +1659,24 @@ bfd_mach_o_write_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
 }
 
 static unsigned
-bfd_mach_o_primary_symbol_sort_key (unsigned type)
+bfd_mach_o_primary_symbol_sort_key (bfd_mach_o_asymbol *s)
 {
-  unsigned mtyp = type & BFD_MACH_O_N_TYPE;
+  unsigned mtyp = s->n_type & BFD_MACH_O_N_TYPE;
 
   /* Just leave debug symbols where they are (pretend they are local, and
      then they will just be sorted on position).  */
-  if (type & BFD_MACH_O_N_STAB)
+  if (s->n_type & BFD_MACH_O_N_STAB)
     return 0;
 
-  /* Sort indirects to last.  */
-  if (mtyp == BFD_MACH_O_N_INDR)
-    return 3;
-
   /* Local (we should never see an undefined local AFAICT).  */
-  if (! (type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT)))
+  if (! (s->n_type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT)))
     return 0;
 
   /* Common symbols look like undefined externs.  */
   if (mtyp == BFD_MACH_O_N_UNDF)
     return 2;
 
-  /* A defined symbol that's not indirect or extern.  */
+  /* A defined non-local, non-debug symbol.  */
   return 1;
 }
 
@@ -1705,8 +1687,8 @@ bfd_mach_o_cf_symbols (const void *a, const void *b)
   bfd_mach_o_asymbol *sb = *(bfd_mach_o_asymbol **) b;
   unsigned int soa, sob;
 
-  soa = bfd_mach_o_primary_symbol_sort_key (sa->n_type);
-  sob = bfd_mach_o_primary_symbol_sort_key (sb->n_type);
+  soa = bfd_mach_o_primary_symbol_sort_key (sa);
+  sob = bfd_mach_o_primary_symbol_sort_key (sb);
   if (soa < sob)
     return -1;
 
@@ -1720,55 +1702,13 @@ bfd_mach_o_cf_symbols (const void *a, const void *b)
         return -1;
       if (sa->symbol.udata.i > sb->symbol.udata.i)
         return  1;
+
+      /* This is probably an error.  */
       return 0;
     }
 
-  /* Unless it's an indirect the second sort key is name.  */
-  if (soa < 3)
-    return strcmp (sa->symbol.name, sb->symbol.name);
-
-  /* Here be indirect symbols, which have different sort rules.  */
-
-  /* Next sort key for indirect, is the section index.  */
-  if (sa->n_sect < sb->n_sect)
-    return -1;
-
-  if (sa->n_sect > sb->n_sect)
-    return  1;
-
-  /* Last sort key is the order of definition - which should be in line with
-     the value, since a stub size of 0 is meaninglesss.  */
-
-  if (sa->symbol.value < sb->symbol.value)
-    return -1;
-
-  if (sa->symbol.value > sb->symbol.value)
-    return 1;
-
-  /* In the final analysis, this is probably an error ... but leave it alone
-     for now.  */
-  return 0;
-}
-
-/* When this is finished, return the number of non-indirect symbols.  */
-
-static unsigned int
-bfd_mach_o_sort_symbol_table (asymbol **symbols, unsigned int nin)
-{
-  qsort (symbols, (size_t) nin, sizeof (void *), bfd_mach_o_cf_symbols);
-  
-  /* Find the last non-indirect symbol.  
-     There must be at least one non-indirect symbol otherwise there's
-     nothing for the indirect(s) to refer to.  */
-  do
-    { 
-      bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[nin - 1];
-      if (IS_MACHO_INDIRECT (s->n_type))
-       nin--;
-      else
-       break;
-    } while (nin - 1 > 0);
-  return nin;
+  /* The second sort key is name.  */
+  return strcmp (sa->symbol.name, sb->symbol.name);
 }
 
 /* Process the symbols.
@@ -1784,18 +1724,14 @@ bfd_mach_o_sort_symbol_table (asymbol **symbols, unsigned int nin)
                (unsorted)
        ( ii) external defined
                (by name)
-       (iii) external undefined
+       (iii) external undefined/common
                (by name)
        ( iv) common
                (by name)
-       (  v) indirect 
-               (by section)
-                       (by position within section).
-
-   (c) Indirect symbols are moved to the end of the list.  */
+*/
 
 static bfd_boolean
-bfd_mach_o_mangle_symbols (bfd *abfd, bfd_mach_o_data_struct *mdata)
+bfd_mach_o_mangle_symbols (bfd *abfd)
 {
   unsigned long i;
   asymbol **symbols = bfd_get_outsymbols (abfd);
@@ -1807,11 +1743,15 @@ bfd_mach_o_mangle_symbols (bfd *abfd, bfd_mach_o_data_struct *mdata)
     {
       bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
 
-      if (s->n_type == BFD_MACH_O_N_UNDF && !(s->symbol.flags & BSF_DEBUGGING))
+      /* We use this value, which is out-of-range as a symbol index, to signal
+        that the mach-o-specific data are not filled in and need to be created
+        from the bfd values.  It is much preferable for the application to do
+        this, since more meaningful diagnostics can be made that way.  */
+
+      if (s->symbol.udata.i == SYM_MACHO_FIELDS_UNSET)
         {
-          /* As genuine Mach-O symbols type shouldn't be N_UNDF (undefined
-             symbols should be N_UNDEF | N_EXT), we suppose the back-end
-             values haven't been set.  */
+          /* No symbol information has been set - therefore determine
+             it from the bfd symbol flags/info.  */
           if (s->symbol.section == bfd_abs_section_ptr)
             s->n_type = BFD_MACH_O_N_ABS;
           else if (s->symbol.section == bfd_und_section_ptr)
@@ -1821,9 +1761,13 @@ bfd_mach_o_mangle_symbols (bfd *abfd, bfd_mach_o_data_struct *mdata)
                 s->n_desc |= BFD_MACH_O_N_WEAK_REF;
               /* mach-o automatically makes undefined symbols extern.  */
              s->n_type |= BFD_MACH_O_N_EXT;
+             s->symbol.flags |= BSF_GLOBAL;
             }
           else if (s->symbol.section == bfd_com_section_ptr)
-            s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
+           {
+              s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
+              s->symbol.flags |= BSF_GLOBAL;
+            }
           else
             s->n_type = BFD_MACH_O_N_SECT;
           
@@ -1839,54 +1783,18 @@ bfd_mach_o_mangle_symbols (bfd *abfd, bfd_mach_o_data_struct *mdata)
                && s->symbol.name == NULL))
        s->n_sect = s->symbol.section->target_index;
 
-      /* Unless we're looking at an indirect sym, note the input ordering.
-        We use this to keep local symbols ordered as per the input.  */
-      if (! IS_MACHO_INDIRECT (s->n_type))
-       s->symbol.udata.i = i;
+      /* Number to preserve order for local and debug syms.  */
+      s->symbol.udata.i = i;
     }
 
-  /* Sort the symbols and determine how many will remain in the main symbol
-     table, and how many will be emitted as indirect (assuming that we will
-     be emitting a dysymtab).  Renumber the sorted symbols so that the right
-     index will be found during indirection.  */
-  i = bfd_mach_o_sort_symbol_table (symbols, bfd_get_symcount (abfd));
-  if (bfd_mach_o_should_emit_dysymtab ())
-    {
-      /* Point at the first indirect symbol.  */
-      if (i < bfd_get_symcount (abfd))
-       {
-         mdata->indirect_syms = &symbols[i];
-         mdata->nindirect = bfd_get_symcount (abfd) - i;
-         /* This is, essentially, local to the output section of mach-o,
-            and therefore should be safe.  */
-         abfd->symcount = i;
-       }
+  /* Sort the symbols.  */
+  qsort ((void *) symbols, (size_t) bfd_get_symcount (abfd),
+        sizeof (asymbol *), bfd_mach_o_cf_symbols);
 
-      /* Now setup the counts for each type of symbol.  */
-      for (i = 0; i < bfd_get_symcount (abfd); ++i)
-       {
-         bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
-         s->symbol.udata.i = i;  /* renumber.  */
-         if (s->n_type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT))
-           break;
-       }
-      mdata->nlocal = i;
-      for (; i < bfd_get_symcount (abfd); ++i)
-       {
-         bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
-         s->symbol.udata.i = i;  /* renumber.  */
-         if ((s->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_UNDF)
-           break;
-       }
-      mdata->ndefext = i - mdata->nlocal;
-      mdata->nundefext = bfd_get_symcount (abfd) 
-                        - mdata->ndefext 
-                        - mdata->nlocal;
-      for (; i < bfd_get_symcount (abfd); ++i)
-       {
-         bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
-         s->symbol.udata.i = i;  /* renumber.  */
-       }
+  for (i = 0; i < bfd_get_symcount (abfd); ++i)
+    {
+      bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
+      s->symbol.udata.i = i;  /* renumber.  */
     }
 
   return TRUE;
@@ -2179,43 +2087,58 @@ bfd_mach_o_build_dysymtab_command (bfd *abfd,
     }
 
   dsym->ilocalsym = 0;
-  dsym->nlocalsym = mdata->nlocal;
-  dsym->iextdefsym = dsym->nlocalsym;
-  dsym->nextdefsym = mdata->ndefext;
-  dsym->iundefsym = dsym->nextdefsym + dsym->iextdefsym;
-  dsym->nundefsym = mdata->nundefext;
 
-  if (mdata->nindirect > 0)
+  if (bfd_get_symcount (abfd) > 0)
+    {
+      asymbol **symbols = bfd_get_outsymbols (abfd);
+      unsigned long i;
+
+       /* Count the number of each kind of symbol.  */
+      for (i = 0; i < bfd_get_symcount (abfd); ++i)
+       {
+         bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
+         if (s->n_type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT))
+           break;
+       }
+      dsym->nlocalsym = i;
+      dsym->iextdefsym = i;
+      for (; i < bfd_get_symcount (abfd); ++i)
+       {
+         bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
+         if ((s->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_UNDF)
+           break;
+       }
+      dsym->nextdefsym = i - dsym->nlocalsym;
+      dsym->iundefsym = dsym->nextdefsym + dsym->iextdefsym;
+      dsym->nundefsym = bfd_get_symcount (abfd) 
+                       - dsym->nlocalsym 
+                       - dsym->nextdefsym;
+    }
+  else
+    {
+      dsym->nlocalsym = 0;
+      dsym->iextdefsym = 0;
+      dsym->nextdefsym = 0;
+      dsym->iundefsym = 0;
+      dsym->nundefsym = 0;
+    }
+
+  if (dsym->nindirectsyms > 0)
     {
-      unsigned i, sect;
+      unsigned i;
 
       mdata->filelen = FILE_ALIGN (mdata->filelen, 2);
       dsym->indirectsymoff = mdata->filelen;
-      mdata->filelen += mdata->nindirect * 4;
+      mdata->filelen += dsym->nindirectsyms * 4;
       
-      dsym->indirect_syms = bfd_zalloc (abfd, mdata->nindirect * 4);
+      dsym->indirect_syms = bfd_zalloc (abfd, dsym->nindirectsyms * 4);
       if (dsym->indirect_syms == NULL)
         return FALSE;
-      dsym->nindirectsyms = mdata->nindirect;
       
-      /* So fill in the indices, and point the section reserved1 fields
-        at the right one.  */
-      sect = (unsigned) -1;
-      for (i = 0; i < mdata->nindirect; ++i)
+      /* So fill in the indices.  */
+      for (i = 0; i < dsym->nindirectsyms; ++i)
        {
-         bfd_mach_o_asymbol *s = 
-                       (bfd_mach_o_asymbol *) mdata->indirect_syms[i];
-         /* Lookup the index of the referenced symbol.  */
-         dsym->indirect_syms[i] = 
-               ((bfd_mach_o_asymbol *) s->symbol.udata.p)->symbol.udata.i;
-         if (s->n_sect != sect)
-           {
-             /* Mach-o sections are 1-based, but the section table
-                is 0-based.  */
-             bfd_mach_o_section *sc = mdata->sections[s->n_sect-1];
-             sc->reserved1 = i;
-             sect = s->n_sect;
-           }
+         /* TODO: fill in the table.  */
        }
     }
 
@@ -2261,7 +2184,7 @@ bfd_mach_o_build_commands (bfd *abfd)
 
   /* Order the symbol table, fill-in/check mach-o specific fields and
      partition out any indirect symbols.  */
-  if (!bfd_mach_o_mangle_symbols (abfd, mdata))
+  if (!bfd_mach_o_mangle_symbols (abfd))
     return FALSE;
 
   /* It's valid to have a file with only absolute symbols...  */
@@ -2423,7 +2346,7 @@ bfd_mach_o_make_empty_symbol (bfd *abfd)
   if (new_symbol == NULL)
     return new_symbol;
   new_symbol->the_bfd = abfd;
-  new_symbol->udata.i = 0;
+  new_symbol->udata.i = SYM_MACHO_FIELDS_UNSET;
   return new_symbol;
 }
 
@@ -2751,7 +2674,7 @@ bfd_mach_o_read_symtab_symbol (bfd *abfd,
   s->symbol.name = sym->strtab + stroff;
   s->symbol.value = value;
   s->symbol.flags = 0x0;
-  s->symbol.udata.i = 0;
+  s->symbol.udata.i = i;
   s->n_type = type;
   s->n_sect = section;
   s->n_desc = desc;
@@ -2782,13 +2705,9 @@ bfd_mach_o_read_symtab_symbol (bfd *abfd,
     }
   else
     {
-      if (type & BFD_MACH_O_N_PEXT)
+      if (type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT))
        s->symbol.flags |= BSF_GLOBAL;
-
-      if (type & BFD_MACH_O_N_EXT)
-       s->symbol.flags |= BSF_GLOBAL;
-
-      if (!(type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT)))
+      else
        s->symbol.flags |= BSF_LOCAL;
 
       switch (symtype)
@@ -3989,6 +3908,7 @@ bfd_mach_o_header_p (bfd *abfd,
       if (header.cputype != cputype)
         goto wrong;
     }
+
   if (filetype)
     {
       if (header.filetype != filetype)
index 123eddafef9cdef8f3dadb105e1978d9a2bdf3f2..ca810a03f37f737248bce0ad6d74e9a87065592e 100644 (file)
@@ -549,18 +549,6 @@ typedef struct mach_o_data_struct
   bfd_mach_o_symtab_command *symtab;
   bfd_mach_o_dysymtab_command *dysymtab;
 
-  /* Base values used for building the dysymtab for a single-module object.  */  
-  unsigned long nlocal;
-  unsigned long ndefext;
-  unsigned long nundefext;
-
-  /* If this is non-zero, then the pointer below is populated.  */
-  unsigned long nindirect;
-  /* A set of synthetic symbols representing the 'indirect' ones in the file.
-     These should be sorted (a) by the section they represent and (b) by the
-     order that they appear within each section.  */
-  asymbol **indirect_syms;
-
   /* A place to stash dwarf2 info for this bfd.  */
   void *dwarf2_find_line_info;
 
@@ -691,8 +679,10 @@ typedef struct bfd_mach_o_backend_data
 }
 bfd_mach_o_backend_data;
 
-/* Symbol type tests.  */
+/* Values used in symbol.udata.i, to signal that the mach-o-specific data in the
+   symbol are not yet set, or need validation (where this is possible).  */
 
-#define IS_MACHO_INDIRECT(x) (((x) & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_INDR)
+#define SYM_MACHO_FIELDS_UNSET ((bfd_vma) -1)
+#define SYM_MACHO_FIELDS_NOT_VALIDATED ((bfd_vma) -2)
 
 #endif /* _BFD_MACH_O_H_ */
index c90543977b172049b045f5199afcb4f19909f71a..1d72c39c8d1f0147ab26633cc15317ed1d62d624 100644 (file)
@@ -1,3 +1,20 @@
+2012-01-09  Iain Sandoe  <idsandoe@googlemail.com>
+
+       * config/obj-macho.c (obj_mach_o_weak): Remove.
+       (obj_mach_o_common_parse): Set symbol qualifiers.
+       (LAZY, REFE): New macros.
+       (obj_mach_o_symbol_type): New enum.
+       (obj_mach_o_set_symbol_qualifier): New.
+       (obj_mach_o_sym_qual): New.
+       (mach_o_pseudo_table): Add symbol qualifiers, set indirect_symbol to
+       a dummy function.
+       (obj_mach_o_type_for_symbol): New.
+       (obj_macho_frob_label): New.
+       (obj_macho_frob_symbol): New.
+       * config/obj-macho.h (S_SET_ALIGN): Amend temorary var name.
+       (obj_frob_label, obj_macho_frob_label): Declare.
+       (obj_frob_symbol, obj_macho_frob_symbol): Declare.
+
 2012-01-08  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * config/tc-mips.c (s_tls_rel_directive): Call mips_clear_insn_labels.
index b5237678ab3a8d617b94caf416c02e756a0588f6..43f4fba658ebaef14995a342cdbbfe93b9317f15 100644 (file)
@@ -82,33 +82,8 @@ mach_o_begin (void)
 
 /* Remember the subsections_by_symbols state in case we need to reset
    the file flags.  */
-static int obj_mach_o_subsections_by_symbols;
 
-static void
-obj_mach_o_weak (int ignore ATTRIBUTE_UNUSED)
-{
-  char *name;
-  int c;
-  symbolS *symbolP;
-
-  do
-    {
-      /* Get symbol name.  */
-      name = input_line_pointer;
-      c = get_symbol_end ();
-      symbolP = symbol_find_or_make (name);
-      S_SET_WEAK (symbolP);
-      *input_line_pointer = c;
-      SKIP_WHITESPACE ();
-
-      if (c != ',')
-        break;
-      input_line_pointer++;
-      SKIP_WHITESPACE ();
-    }
-  while (*input_line_pointer != '\n');
-  demand_empty_rest_of_line ();
-}
+static int obj_mach_o_subsections_by_symbols;
 
 /* This will put at most 16 characters (terminated by a ',' or newline) from
    the input stream into dest.  If there are more than 16 chars before the
@@ -901,6 +876,7 @@ obj_mach_o_common_parse (int is_local, symbolS *symbolP,
                         addressT size)
 {
   addressT align = 0;
+  bfd_mach_o_asymbol *s;
 
   SKIP_WHITESPACE ();  
 
@@ -920,6 +896,7 @@ obj_mach_o_common_parse (int is_local, symbolS *symbolP,
        }
     }
 
+  s = (bfd_mach_o_asymbol *) symbol_get_bfdsym (symbolP);
   if (is_local)
     {
       /* Create the BSS section on demand.  */
@@ -929,6 +906,7 @@ obj_mach_o_common_parse (int is_local, symbolS *symbolP,
          seg_info (bss_section)->bss = 1;        
        }
       bss_alloc (symbolP, size, align);
+      s->n_type = BFD_MACH_O_N_SECT;
       S_CLEAR_EXTERNAL (symbolP);
     }
   else
@@ -937,9 +915,14 @@ obj_mach_o_common_parse (int is_local, symbolS *symbolP,
       S_SET_ALIGN (symbolP, align);
       S_SET_EXTERNAL (symbolP);
       S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
+      s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
     }
 
-  symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
+  /* This is a data object (whatever we choose that to mean).  */
+  s->symbol.flags |= BSF_OBJECT;
+
+  /* We've set symbol qualifiers, so validate if you can.  */
+  s->symbol.udata.i = SYM_MACHO_FIELDS_NOT_VALIDATED;
 
   return symbolP;
 }
@@ -979,6 +962,175 @@ obj_mach_o_fileprop (int prop)
     }
 }
 
+/* Temporary markers for symbol reference data.  
+   Lazy will remain in place.  */
+#define LAZY 0x01
+#define REFE 0x02
+
+/* We have a bunch of qualifiers that may be applied to symbols.
+   .globl is handled here so that we might make sure that conflicting qualifiers
+   are caught where possible.  */
+
+typedef enum obj_mach_o_symbol_type {
+  OBJ_MACH_O_SYM_UNK = 0,
+  OBJ_MACH_O_SYM_LOCAL = 1,
+  OBJ_MACH_O_SYM_GLOBL = 2,
+  OBJ_MACH_O_SYM_REFERENCE = 3,
+  OBJ_MACH_O_SYM_WEAK_REF = 4,
+  OBJ_MACH_O_SYM_LAZY_REF = 5,
+  OBJ_MACH_O_SYM_WEAK_DEF = 6,
+  OBJ_MACH_O_SYM_PRIV_EXT = 7,
+  OBJ_MACH_O_SYM_NO_DEAD_STRIP = 8,
+  OBJ_MACH_O_SYM_WEAK = 9
+} obj_mach_o_symbol_type;
+
+/* Set Mach-O-specific symbol qualifiers. */
+
+static int
+obj_mach_o_set_symbol_qualifier (symbolS *sym, int type)
+{
+  int is_defined;
+  bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *) symbol_get_bfdsym (sym);
+  bfd_mach_o_section *sec;
+  int sectype = -1;
+  int err = 0;
+
+  /* If the symbol is defined, then we can do more rigorous checking on
+     the validity of the qualifiers.  Otherwise, we are stuck with waiting 
+     until it's defined - or until write the file.
+     
+     In certain cases (e.g. when a symbol qualifier is intended to introduce
+     an undefined symbol in a stubs section) we should check that the current
+     section is appropriate to the qualifier.  */
+
+  is_defined = s->symbol.section != bfd_und_section_ptr;
+  if (is_defined)
+    sec = bfd_mach_o_get_mach_o_section (s->symbol.section) ;
+  else
+    sec = bfd_mach_o_get_mach_o_section (now_seg) ;
+
+  if (sec != NULL)
+    sectype = sec->flags & BFD_MACH_O_SECTION_TYPE_MASK;
+
+  switch ((obj_mach_o_symbol_type) type)
+    {
+      case OBJ_MACH_O_SYM_LOCAL:
+       /* This is an extension over the system tools.  */
+        if (s->n_type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT))
+         {
+           as_bad (_("'%s' previously declared as '%s'."), s->symbol.name,
+                     (s->n_type & BFD_MACH_O_N_PEXT) ? "private extern"
+                                                     : "global" );
+           err = 1;
+         }
+       else
+         {
+           s->n_type &= ~BFD_MACH_O_N_EXT;
+           S_CLEAR_EXTERNAL (sym);
+         }
+       break;
+
+      case OBJ_MACH_O_SYM_PRIV_EXT:
+       s->n_type |= BFD_MACH_O_N_PEXT ;
+       /* We follow the system tools in marking PEXT as also global.  */
+       /* Fall through.  */
+
+      case OBJ_MACH_O_SYM_GLOBL:
+       /* It's not an error to define a symbol and then make it global.  */
+       s->n_type |= BFD_MACH_O_N_EXT;
+       S_SET_EXTERNAL (sym);
+       break;
+
+      case OBJ_MACH_O_SYM_REFERENCE:
+        if (is_defined)
+          s->n_desc |= BFD_MACH_O_N_NO_DEAD_STRIP;
+        else
+          s->n_desc |= (REFE | BFD_MACH_O_N_NO_DEAD_STRIP);
+       break;
+
+      case OBJ_MACH_O_SYM_LAZY_REF:
+        if (is_defined)
+          s->n_desc |= BFD_MACH_O_N_NO_DEAD_STRIP;
+        else
+          s->n_desc |= (REFE | LAZY | BFD_MACH_O_N_NO_DEAD_STRIP);
+       break;
+
+      /* Force ld to retain the symbol - even if it appears unused.  */
+      case OBJ_MACH_O_SYM_NO_DEAD_STRIP:
+       s->n_desc |= BFD_MACH_O_N_NO_DEAD_STRIP ;
+       break;
+
+      /* Mach-O's idea of weak ...  */
+      case OBJ_MACH_O_SYM_WEAK_REF:
+       s->n_desc |= BFD_MACH_O_N_WEAK_REF ;
+       break;
+
+      case OBJ_MACH_O_SYM_WEAK_DEF:
+       if (is_defined && sectype != BFD_MACH_O_S_COALESCED)
+         {
+           as_bad (_("'%s' can't be a weak_definition (currently only"
+                     " supported in sections of type coalesced)"),
+                     s->symbol.name);
+           err = 1;
+         }
+       else
+         s->n_desc |= BFD_MACH_O_N_WEAK_DEF;
+       break;
+
+      case OBJ_MACH_O_SYM_WEAK:
+        /* A generic 'weak' - we try to figure out what it means at
+          symbol frob time.  */
+       S_SET_WEAK (sym);
+       break;
+
+      default:
+       break;
+    }
+
+    /* We've seen some kind of qualifier - check validity if or when the entity
+     is defined.  */
+  s->symbol.udata.i = SYM_MACHO_FIELDS_NOT_VALIDATED;
+  return err;
+}
+
+/* Respond to symbol qualifiers.
+   All of the form:
+   .<qualifier> symbol [, symbol]*
+   a list of symbols is an extension over the Darwin system as.  */
+
+static void
+obj_mach_o_sym_qual (int ntype)
+{
+  char *name;
+  char c;
+  symbolS *symbolP;
+
+#ifdef md_flush_pending_output
+  md_flush_pending_output ();
+#endif
+
+  do
+    {
+      name = input_line_pointer;
+      c = get_symbol_end ();
+      symbolP = symbol_find_or_make (name);
+      obj_mach_o_set_symbol_qualifier (symbolP, ntype);
+      *input_line_pointer = c;
+      SKIP_WHITESPACE ();
+      c = *input_line_pointer;
+      if (c == ',')
+       {
+         input_line_pointer++;
+         SKIP_WHITESPACE ();
+         if (is_end_of_line[(unsigned char) *input_line_pointer])
+           c = '\n';
+       }
+    }
+  while (c == ',');
+
+  demand_empty_rest_of_line ();
+}
+
 /* Dummy function to allow test-code to work while we are working
    on things.  */
 
@@ -1068,11 +1220,18 @@ const pseudo_typeS mach_o_pseudo_table[] =
   { "section", obj_mach_o_section, 0},
   { "zerofill", obj_mach_o_zerofill, 0},
 
-  /* Symbol-related.  */
-  { "indirect_symbol", obj_mach_o_placeholder, 0},
-  { "weak_definition", obj_mach_o_placeholder, 0},
-  { "private_extern", obj_mach_o_placeholder, 0},
-  { "weak", obj_mach_o_weak, 0},   /* extension */
+  /* Symbol qualifiers.  */
+  {"local",            obj_mach_o_sym_qual, OBJ_MACH_O_SYM_LOCAL},
+  {"globl",            obj_mach_o_sym_qual, OBJ_MACH_O_SYM_GLOBL},
+  {"reference",                obj_mach_o_sym_qual, OBJ_MACH_O_SYM_REFERENCE},
+  {"weak_reference",   obj_mach_o_sym_qual, OBJ_MACH_O_SYM_WEAK_REF},
+  {"lazy_reference",   obj_mach_o_sym_qual, OBJ_MACH_O_SYM_LAZY_REF},
+  {"weak_definition",  obj_mach_o_sym_qual, OBJ_MACH_O_SYM_WEAK_DEF},
+  {"private_extern",   obj_mach_o_sym_qual, OBJ_MACH_O_SYM_PRIV_EXT},
+  {"no_dead_strip",    obj_mach_o_sym_qual, OBJ_MACH_O_SYM_NO_DEAD_STRIP},
+  {"weak",             obj_mach_o_sym_qual, OBJ_MACH_O_SYM_WEAK}, /* ext */
+
+  {"indirect_symbol",  obj_mach_o_placeholder, 0},
 
   /* File flags.  */
   { "subsections_via_symbols", obj_mach_o_fileprop, 
@@ -1081,6 +1240,154 @@ const pseudo_typeS mach_o_pseudo_table[] =
   {NULL, NULL, 0}
 };
 
+/* Determine the default n_type value for a symbol from its section.  */
+
+static unsigned
+obj_mach_o_type_for_symbol (bfd_mach_o_asymbol *s)
+{
+  if (s->symbol.section == bfd_abs_section_ptr)
+    return BFD_MACH_O_N_ABS;
+  else if (s->symbol.section == bfd_com_section_ptr
+          || s->symbol.section == bfd_und_section_ptr)
+    return BFD_MACH_O_N_UNDF;
+  else
+    return BFD_MACH_O_N_SECT;
+}
+
+/* We need to check the correspondence between some kinds of symbols and their
+   sections.  Common and BSS vars will seen via the obj_macho_comm() function.
+   
+   The earlier we can pick up a problem, the better the diagnostics will be.
+   
+   However, when symbol type information is attached, the symbol section will
+   quite possibly be unknown.  So we are stuck with checking (most of the)
+   validity at the time the file is written (unfortunately, then one doesn't
+   get line number information in the diagnostic).  */
+
+/* Here we pick up the case where symbol qualifiers have been applied that
+   are possibly incompatible with the section etc. that the symbol is defined
+   in.  */
+
+void obj_macho_frob_label (struct symbol *sp)
+{
+  bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *) symbol_get_bfdsym (sp);
+  /* This is the base symbol type, that we mask in.  */
+  unsigned base_type = obj_mach_o_type_for_symbol (s);
+  bfd_mach_o_section *sec = bfd_mach_o_get_mach_o_section (s->symbol.section);
+  int sectype = -1;
+
+  if ((s->n_type & BFD_MACH_O_N_STAB) != 0)
+    return; /* Leave alone.  */
+  
+  if (sec != NULL)
+    sectype = sec->flags & BFD_MACH_O_SECTION_TYPE_MASK;
+
+  /* If there is a pre-existing qualifier, we can make some checks about
+     validity now.  */
+
+  if(s->symbol.udata.i == SYM_MACHO_FIELDS_NOT_VALIDATED)
+    {
+      if ((s->n_desc & BFD_MACH_O_N_WEAK_DEF)
+         && sectype != BFD_MACH_O_S_COALESCED)
+       as_bad (_("'%s' can't be a weak_definition (currently only supported"
+                 " in sections of type coalesced)"), s->symbol.name);
+
+      /* Have we changed from an undefined to defined ref? */
+      s->n_desc &= ~(REFE | LAZY);
+    }
+
+  s->n_type &= ~BFD_MACH_O_N_TYPE;
+  s->n_type |= base_type;
+}
+
+/* This is the fall-back, we come here when we get to the end of the file and
+   the symbol is not defined - or there are combinations of qualifiers required
+   (e.g. global + weak_def).  */
+
+int
+obj_macho_frob_symbol (struct symbol *sp)
+{
+  bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *) symbol_get_bfdsym (sp);
+  unsigned base_type = obj_mach_o_type_for_symbol (s);
+  bfd_mach_o_section *sec = bfd_mach_o_get_mach_o_section (s->symbol.section);
+  int sectype = -1;
+  
+  if (sec != NULL)
+    sectype = sec->flags & BFD_MACH_O_SECTION_TYPE_MASK;
+
+  if ((s->n_type & BFD_MACH_O_N_STAB) != 0)
+    return 0; /* Leave alone.  */
+  else if (s->symbol.section == bfd_und_section_ptr)
+    {
+      /* ??? Do we really gain much from implementing this as well as the
+        mach-o specific ones?  */
+      if (s->symbol.flags & BSF_WEAK)
+       s->n_desc |= BFD_MACH_O_N_WEAK_REF;
+
+      /* Undefined references, become extern.  */
+      if (s->n_desc & REFE)
+       {
+         s->n_desc &= ~REFE;
+         s->n_type |= BFD_MACH_O_N_EXT;
+       }
+
+      /* So do undefined 'no_dead_strip's.  */
+      if (s->n_desc & BFD_MACH_O_N_NO_DEAD_STRIP)
+       s->n_type |= BFD_MACH_O_N_EXT;
+
+    }
+  else
+    {
+      if ((s->symbol.flags & BSF_WEAK)
+          && (sectype == BFD_MACH_O_S_COALESCED)
+          && (s->n_type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT)))
+       s->n_desc |= BFD_MACH_O_N_WEAK_DEF;
+/* ??? we should do this - but then that reveals that the semantics of weak
+       are different from what's supported in mach-o object files.
+      else
+       as_bad (_("'%s' can't be a weak_definition."),
+               s->symbol.name); */
+    }
+
+  if (s->symbol.udata.i == SYM_MACHO_FIELDS_UNSET)
+    {
+      /* Anything here that should be added that is non-standard.  */
+      s->n_desc &= ~BFD_MACH_O_REFERENCE_MASK;
+    }    
+  else if (s->symbol.udata.i == SYM_MACHO_FIELDS_NOT_VALIDATED)
+    {
+      /* Try to validate any combinations.  */
+      if (s->n_desc & BFD_MACH_O_N_WEAK_DEF)
+       {
+         if (s->symbol.section == bfd_und_section_ptr)
+           as_bad (_("'%s' can't be a weak_definition (since it is"
+                     " undefined)"), s->symbol.name);
+         else if (sectype != BFD_MACH_O_S_COALESCED)
+           as_bad (_("'%s' can't be a weak_definition (currently only supported"
+                     " in sections of type coalesced)"), s->symbol.name);
+         else if (! (s->n_type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT)))
+           as_bad (_("Non-global symbol: '%s' can't be a weak_definition."),
+                   s->symbol.name);
+       }
+
+    }
+  else
+    as_bad (_("internal error: [%s] unexpected code [%lx] in frob symbol"),
+           s->symbol.name, (unsigned long)s->symbol.udata.i);
+
+  s->n_type &= ~BFD_MACH_O_N_TYPE;
+  s->n_type |= base_type;
+
+  if (s->symbol.flags & BSF_GLOBAL)
+    s->n_type |= BFD_MACH_O_N_EXT;
+
+  /* This cuts both ways - we promote some things to external above.  */
+  if (s->n_type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT))
+    S_SET_EXTERNAL (sp);
+
+  return 0;
+}
+
 /* Support stabs for mach-o.  */
 
 void
index b2acd17c63c0b5de43707a9e7781d659851fcb0b..cbc3a4fce538bcf1d336ea00edd1cbdb37c0abe8 100644 (file)
@@ -40,8 +40,8 @@ extern void mach_o_begin (void);
 /* Common symbols can carry alignment information.  */
 #ifndef S_SET_ALIGN
 #define S_SET_ALIGN(S,V) do {\
-  bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *) symbol_get_bfdsym (S);\
-  s->n_desc = (s->n_desc & 0xf0ff) | (((V) & 0x0f) << 8);\
+  bfd_mach_o_asymbol *___s = (bfd_mach_o_asymbol *) symbol_get_bfdsym (S);\
+  ___s->n_desc = (___s->n_desc & 0xf0ff) | (((V) & 0x0f) << 8);\
 } while (0)
 #endif
 
@@ -56,6 +56,12 @@ extern const pseudo_typeS mach_o_pseudo_table[];
 #define obj_read_begin_hook()  {;}
 #define obj_symbol_new_hook(s) {;}
 
+#define obj_frob_label(s) obj_macho_frob_label(s)
+extern void obj_macho_frob_label (struct symbol *);
+
+#define obj_frob_symbol(s, punt) punt = obj_macho_frob_symbol(s)
+extern int obj_macho_frob_symbol (struct symbol *);
+
 #define EMIT_SECTION_SYMBOLS           0
 
 #define OBJ_PROCESS_STAB(SEG,W,S,T,O,D)        obj_mach_o_process_stab(W,S,T,O,D)
index c638cdc19a5e023f45408a80c5e11dbd1619903a..3176c0c1af9b83d2c1b97e3a3feb60935ba3f668 100644 (file)
@@ -1,3 +1,15 @@
+2012-01-09  Iain Sandoe  <idsandoe@googlemail.com>
+
+       * gas/mach-o/err-syms-1.s: New.
+       * gas/mach-o/err-syms-2.s: New.
+       * gas/mach-o/err-syms-3.s: New.
+       * gas/mach-o/symbols-2.d: New.
+       * gas/mach-o/symbols-2.s: New.
+       * gas/mach-o/symbols-3.s: New.
+       * gas/mach-o/symbols-4.s: New.
+       * gas/mach-o/symbols-5.d: New.
+       * gas/mach-o/symbols-5.s: New.
+
 2012-01-08  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * gas/mips/tls-relw.s, gas/mips/tls-relw.d: New test.
diff --git a/gas/testsuite/gas/mach-o/err-syms-1.s b/gas/testsuite/gas/mach-o/err-syms-1.s
new file mode 100644 (file)
index 0000000..84146c7
--- /dev/null
@@ -0,0 +1,12 @@
+# { dg-do assemble }
+
+       .globl a
+a:     .space 1
+       .local a
+
+       .private_extern b
+b:     .space 1
+       .local b
+
+# { dg-error ".a. previously declared as .global." "" { target *-*-darwin*} 5 }
+# { dg-error ".b. previously declared as .private extern." "" { target *-*-darwin*} 9 }
diff --git a/gas/testsuite/gas/mach-o/err-syms-2.s b/gas/testsuite/gas/mach-o/err-syms-2.s
new file mode 100644 (file)
index 0000000..ad4a692
--- /dev/null
@@ -0,0 +1,15 @@
+# { dg-do assemble }
+
+       .section __weak, __weak, coalesced
+
+a:     .space 1
+       .weak_definition a
+
+       .weak_definition b
+b:     .space 1
+       
+       .weak_definition c
+
+# { dg-error "Non-global symbol: .a. can.t be a weak_definition." "" { target *-*-darwin*} 0 }
+# { dg-error "Non-global symbol: .b. can.t be a weak_definition." "" { target *-*-darwin*} 0 }
+# { dg-error ".c. can.t be a weak_definition .since it is undefined." "" { target *-*-darwin*} 0 }
diff --git a/gas/testsuite/gas/mach-o/err-syms-3.s b/gas/testsuite/gas/mach-o/err-syms-3.s
new file mode 100644 (file)
index 0000000..8315d86
--- /dev/null
@@ -0,0 +1,10 @@
+# { dg-do assemble }
+
+       .weak_definition a
+a:     .space 1
+
+b:     .space 1
+       .weak_definition b
+
+# { dg-error ".a. can.t be a weak_definition .currently only supported in sections of type coalesced." "" { target *-*-darwin*} 4 }
+# { dg-error ".b. can.t be a weak_definition .currently only supported in sections of type coalesced." "" { target *-*-darwin*} 7 }
diff --git a/gas/testsuite/gas/mach-o/symbols-2.d b/gas/testsuite/gas/mach-o/symbols-2.d
new file mode 100644 (file)
index 0000000..c4bfcbd
--- /dev/null
@@ -0,0 +1,7 @@
+#objdump: -t
+# weak_definitions.
+.*: +file format mach-o.*
+#...
+SYMBOL TABLE:
+(00000000)?00000000 g.*1f SECT.*02 0080 \[__weak.__weak\] a
+(00000000)?00000001 g.*0f SECT.*02 0080 \[__weak.__weak\] b
diff --git a/gas/testsuite/gas/mach-o/symbols-2.s b/gas/testsuite/gas/mach-o/symbols-2.s
new file mode 100644 (file)
index 0000000..2ba36d1
--- /dev/null
@@ -0,0 +1,9 @@
+       .section __weak, __weak, coalesced
+
+       .private_extern a
+       .weak_definition a
+a:     .space 1
+
+       .globl b
+       .weak_definition b
+b:     .space 1
diff --git a/gas/testsuite/gas/mach-o/symbols-3.s b/gas/testsuite/gas/mach-o/symbols-3.s
new file mode 100644 (file)
index 0000000..054fdf6
--- /dev/null
@@ -0,0 +1,111 @@
+# indirect references, stubs and {non,}_lazy_symbol_pointer sections.
+# not applicable to x86_64 mach-o.
+
+       .text
+       .globl c
+       .globl c1
+       .globl c2
+c:     nop
+c1:    nop
+c2:    nop
+
+e:     nop
+e1:    nop
+e2:    nop
+
+       .data
+d:     .space 8
+d1:    .space 8
+d2:    .space 8
+
+       .private_extern f
+       .private_extern f1
+       .private_extern f2
+f:     .space 8
+f1:    .space 8
+f2:    .space 8
+
+       .section __dummy, __dummy, symbol_stubs,strip_static_syms,8
+
+       .indirect_symbol a
+La:    .space 8
+
+       .indirect_symbol b
+Lb:    .space 8
+
+       .indirect_symbol c
+Lc:    .space 8
+
+       .indirect_symbol d
+Ld:    .space 8
+
+       .indirect_symbol e
+Le:    .space 8
+
+       .indirect_symbol f
+Lf:    .space 8
+
+       .private_extern g
+       .indirect_symbol g
+Lg:    .space 8
+
+       .lazy_symbol_pointer
+
+       .indirect_symbol a1
+La1:   .space 4
+
+       .indirect_symbol b1
+Lb1:   .space 4
+
+       .indirect_symbol c1
+Lc1:   .space 4
+
+       .indirect_symbol d1
+Ld1:   .space 4
+
+       .indirect_symbol e1
+Le1:   .space 4
+
+       .indirect_symbol f1
+Lf1:   .space 4
+
+       .private_extern g1
+       .indirect_symbol g1
+Lg1:   .space 4
+
+       .non_lazy_symbol_pointer
+
+       .indirect_symbol a2
+La2:   .space 4
+
+       .indirect_symbol b2
+Lb2:   .space 4
+
+       .indirect_symbol c2
+Lc2:   .space 4
+
+       .indirect_symbol d2
+Ld2:   .space 4
+
+       .indirect_symbol e2
+Le2:   .space 4
+
+       .indirect_symbol f2
+Lf2:   .space 4
+
+       .private_extern g2
+       .indirect_symbol g2
+Lg2:   .space 4
+
+       .indirect_symbol f1
+Lf11:  .space 4
+
+       .private_extern g1
+       .indirect_symbol g1
+Lg11:  .space 4
+
+       .indirect_symbol a2
+La12:  .space 4
+
+       .indirect_symbol b2
+Lb12:  .space 4
diff --git a/gas/testsuite/gas/mach-o/symbols-4.s b/gas/testsuite/gas/mach-o/symbols-4.s
new file mode 100644 (file)
index 0000000..8800806
--- /dev/null
@@ -0,0 +1,65 @@
+# Reference & dead strip permutations.
+
+       .text
+       
+       .reference ua
+       .lazy_reference ub
+       
+       .reference ua1
+       .private_extern ua1
+
+       .private_extern ub1
+       .lazy_reference ub1
+       
+c:     .space 1
+       .reference c
+
+d:     .space 1
+       .lazy_reference d
+
+       .reference c1
+c1:    .space 1
+
+       .lazy_reference d1
+d1:    .space 1
+
+       .private_extern e
+       .reference e
+       
+       .private_extern f
+       .lazy_reference f
+
+g:     .space 1
+       .private_extern g
+       .reference g
+
+h:     .space 1
+       .private_extern h
+       .lazy_reference h
+
+       .private_extern g1
+       .reference g1
+g1:    .space 1
+
+       .private_extern h1
+       .lazy_reference h1
+h1:    .space 1
+
+       .no_dead_strip n
+       
+       .globl m
+       .no_dead_strip m
+
+       .private_extern p
+       .no_dead_strip p
+
+n1:    .space 1
+       .no_dead_strip n1
+       
+m1:    .space 1
+       .globl m1
+       .no_dead_strip m1
+
+p1:    .space 1
+       .private_extern p1
+       .no_dead_strip p1
diff --git a/gas/testsuite/gas/mach-o/symbols-5.d b/gas/testsuite/gas/mach-o/symbols-5.d
new file mode 100644 (file)
index 0000000..7f87e74
--- /dev/null
@@ -0,0 +1,11 @@
+#objdump: -t
+# globals and private_externs
+.*: +file format mach-o.*
+#...
+SYMBOL TABLE:
+(00000000)?00000000 g.*1f SECT.*01 0000 \[.text\] a
+(00000000)?00000001 g.*0f SECT.*01 0000 \[.text\] b
+(00000000)?00000002 g.*1f SECT.*01 0000 \[.text\] c
+(00000000)?00000000 g.*11 UND.*00 0000 d
+(00000000)?00000000 g.*01 UND.*00 0000 e
+(00000000)?00000000 g.*11 UND.*00 0000 f
diff --git a/gas/testsuite/gas/mach-o/symbols-5.s b/gas/testsuite/gas/mach-o/symbols-5.s
new file mode 100644 (file)
index 0000000..a43266d
--- /dev/null
@@ -0,0 +1,17 @@
+
+       .private_extern a
+a:     .space 1
+
+       .globl b
+b:     .space 1
+
+       .private_extern c
+       .globl c
+c:     .space 1
+
+       .private_extern d
+       
+       .globl e
+       
+       .globl f
+       .private_extern f