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 mach-o/GAS 1/3] support mach-o symbol qualifiers.


this patch-set provides support for the mach-o symbol qualifiers (.weak_reference, .private_extern &c.).

It makes most sense to apply the patch on top of [1] which provides the necessary support for the indirect symbols (although this patch will work without - the binaries would be non-conforming).

We try to intercept error conditions as early as possible (in the qualifier or frob_label code) so that we can give a better diagnostic. However, final checks on compatibility of multiple qualifiers and defined/undefined are sometimes only feasible from frob_symbol.

The second patch in the set provides tests that work when this patch is applied in isolation.
The third patch provides tests of the indirect symbol functionality that requires [1].


One should note that with this (and [1]) we are making fairly heavy use of the udata field in the bfd symbol.

OK?
Iain

[1] http://sourceware.org/ml/binutils/2011-12/msg00319.html


bfd:


	* mach-o.c (bfd_mach_o_bfd_copy_private_symbol_data): Implement.
	(bfd_mach_o_mangle_symbols): Detect that the mach-o fields are
	unset and estimate them from the bfd equivalents.
	(bfd_mach_o_make_empty_symbol): Set udata to a distinct flag value
	signifying unset mach-o fields.
	(bfd_mach_o_read_symtab_symbol): Add the symbol sequence number.
	Minor adjustment to flags logic.

gas:

	* config/obj-macho.c (obj_mach_o_weak): Remove.
	(obj_mach_o_common_parse): Set BFD_MACH_O_N_SECT for bss values.
	Flag that symbol qualifiers are set (but not verified).
	(obj_mach_o_type_for_symbol): New.
	(LAZY, REFE): New macros.
	(obj_macho_frob_label): New.
	(obj_macho_frob_symbol): New.
	(obj_mach_o_make_indirect_symbol): New.
	(obj_mach_o_symbol_type): New enum.
	(obj_mach_o_set_symbol_qualifier): New.
	(obj_mach_o_sym_qual): New.
	(obj_mach_o_placeholder): ifdef this out for now.
	(mach_o_pseudo_table): Update with new symbol qualifiers.
	* config/obj-macho.h (S_SET_ALIGN): Use a better local var name.
	(obj_frob_label, obj_macho_frob_label): Define.
	(obj_frob_symbol, obj_macho_frob_symbol): Define.

bfd/mach-o.c | 42 +++--
gas/config/obj-macho.c | 437 +++++++++++++++++++++++++++++++++++++++ +++++----
gas/config/obj-macho.h | 10 +-
3 files changed, 438 insertions(+), 51 deletions(-)


diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index cc68d89..abcc0b4 100644
--- a/bfd/mach-o.c
+++ b/bfd/mach-o.c
@@ -529,10 +529,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;
 }

@@ -1420,8 +1427,8 @@ bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
return FALSE;
}


-/* Process the symbols and generate Mach-O specific fields.
- Number them. */
+/* Process the symbols and generate Mach-O specific fields, if they have not
+ been set by the host application. Number them. */


 static bfd_boolean
 bfd_mach_o_mangle_symbols (bfd *abfd)
@@ -1433,11 +1440,15 @@ bfd_mach_o_mangle_symbols (bfd *abfd)
     {
       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 == (bfd_vma) -1)
{
- /* 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)
@@ -1744,7 +1755,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 = (bfd_vma) -1; /* Flag unset values. */
return new_symbol;
}


@@ -2072,7 +2083,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;
@@ -2103,13 +2114,9 @@ bfd_mach_o_read_symtab_symbol (bfd *abfd,
     }
   else
     {
-      if (type & BFD_MACH_O_N_PEXT)
-	s->symbol.flags |= BSF_GLOBAL;
-
-      if (type & BFD_MACH_O_N_EXT)
+      if (type & (BFD_MACH_O_N_PEXT | 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)
diff --git a/gas/config/obj-macho.c b/gas/config/obj-macho.c
index 74fb0c9..59bd679 100644
--- a/gas/config/obj-macho.c
+++ b/gas/config/obj-macho.c
@@ -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
@@ -674,6 +649,7 @@ obj_mach_o_common_parse (int is_local, symbolS *symbolP,
addressT size)
{
addressT align = 0;
+ bfd_mach_o_asymbol *s;


/* Both comm and lcomm take an optional alignment, as a power
of two between 1 and 15. */
@@ -691,6 +667,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. */
@@ -700,6 +677,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
@@ -708,9 +686,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 = (bfd_vma) -2;

   return symbolP;
 }
@@ -750,6 +733,389 @@ obj_mach_o_fileprop (int prop)
     }
 }

+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;
+}
+
+/* Temporary markers for symbol reference data.
+ Lazy will remain in place. */
+#define LAZY 0x01
+#define REFE 0x02
+
+/* 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 (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 == (bfd_vma) -2)
+ {
+ 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);
+
+ }
+
+ if ((s->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_INDR)
+ s->n_desc &= ~LAZY;
+ else
+ {
+ 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->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->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_INDR)
+ {
+ /* If the referenced symbol is undefined, then make it extern. */
+ bfd_mach_o_asymbol *sr = (bfd_mach_o_asymbol *) s- >symbol.udata.p;
+ if (sr->symbol.section == bfd_und_section_ptr)
+ sr->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 == (bfd_vma) -1)
+ {
+ /* Anything here that should be added that is non-standard. */
+ s->n_desc &= ~BFD_MACH_O_REFERENCE_MASK;
+ }
+ else if (s->symbol.udata.i == (bfd_vma) -2)
+ {
+ /* 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 if ((s->n_type & BFD_MACH_O_N_TYPE) != BFD_MACH_O_N_INDR)
+ as_bad (_("internal error: [%s] unexpected code [%lx] in frob symbol"),
+ s->symbol.name, (unsigned long)s->symbol.udata.i);
+
+ /* Leave the indirect symbol marker in place - we will need to write the info
+ into the dynamic symbol table indirect entries. */
+ if ((s->n_type & BFD_MACH_O_N_TYPE) != BFD_MACH_O_N_INDR)
+ {
+ 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;
+}
+
+static symbolS *
+obj_mach_o_make_indirect_symbol (const char *name)
+{
+ symbolS *sym;
+ bfd_mach_o_asymbol *s;
+ char *newname;
+ int len = strlen (name) + strlen ("L$000$") + strlen ("$00$stub") + 1;
+static unsigned char serial = 0x0a;
+
+ newname = alloca (len);
+ snprintf (newname, len, "L$%03d$%s$%02x$stub", now_seg->index-3, name, (unsigned) serial);
+ serial += 3;
+ /* Define it. */
+ sym = colon (newname);
+ s = (bfd_mach_o_asymbol *) symbol_get_bfdsym (sym);
+ s->symbol.flags |= BSF_SYNTHETIC;
+ s->n_type = BFD_MACH_O_N_INDR;
+ return sym;
+}
+
+/* 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_INDIRECT = 3,
+ OBJ_MACH_O_SYM_REFERENCE = 4,
+ OBJ_MACH_O_SYM_WEAK_REF = 5,
+ OBJ_MACH_O_SYM_LAZY_REF = 6,
+ OBJ_MACH_O_SYM_WEAK_DEF = 7,
+ OBJ_MACH_O_SYM_PRIV_EXT = 8,
+ OBJ_MACH_O_SYM_NO_DEAD_STRIP = 9,
+ OBJ_MACH_O_SYM_WEAK = 10
+} 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;
+
+ /* Indirect symbols. */
+ case OBJ_MACH_O_SYM_INDIRECT:
+ sec = bfd_mach_o_get_mach_o_section (now_seg) ;
+ sectype = sec->flags & BFD_MACH_O_SECTION_TYPE_MASK;
+ if (sectype == BFD_MACH_O_S_SYMBOL_STUBS
+ || sectype == BFD_MACH_O_S_LAZY_SYMBOL_POINTERS)
+ {
+ symbolS *indsym;
+ if (! is_defined)
+ s->n_desc |= LAZY;
+ indsym = obj_mach_o_make_indirect_symbol (s->symbol.name);
+ /* Note which symbol this is a proxy for. */
+ symbol_get_bfdsym (indsym)->udata.p = (void *) s;
+ }
+ else if (sectype == BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS)
+ {
+ symbolS *indsym = obj_mach_o_make_indirect_symbol (s- >symbol.name);
+ /* Note which symbol this is a proxy for. */
+ symbol_get_bfdsym (indsym)->udata.p = (void *) s;
+ }
+ else
+ {
+ as_bad (_("an .indirect_symbol must be in a symbol pointer"
+ " or stub section."));
+ err = 1;
+ }
+ 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 ;
+ S_SET_WEAKREFR (sym);
+ 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;
+ S_SET_WEAKREFD (sym);
+ }
+ 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 = (bfd_vma) -2;
+ 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;
+ int err = 0;
+
+#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);
+ err = obj_mach_o_set_symbol_qualifier (symbolP, ntype);
+ *input_line_pointer = c;
+ if (err)
+ break;
+ 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 == ',');
+
+ if (err)
+ ignore_rest_of_line ();
+ else
+ demand_empty_rest_of_line ();
+}
+
+#if 0
/* Dummy function to allow test-code to work while we are working
on things. */


@@ -758,6 +1124,7 @@ obj_mach_o_placeholder (int arg ATTRIBUTE_UNUSED)
 {
   ignore_rest_of_line ();
 }
+#endif

 const pseudo_typeS mach_o_pseudo_table[] =
 {
@@ -838,11 +1205,17 @@ const pseudo_typeS mach_o_pseudo_table[] =

{ "section", obj_mach_o_section, 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},
+  {"indirect_symbol",	obj_mach_o_sym_qual, OBJ_MACH_O_SYM_INDIRECT},
+  {"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 */

/* File flags. */
{ "subsections_via_symbols", obj_mach_o_fileprop,
diff --git a/gas/config/obj-macho.h b/gas/config/obj-macho.h
index d9b0b33..f251edb 100644
--- a/gas/config/obj-macho.h
+++ b/gas/config/obj-macho.h
@@ -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

#endif /* _OBJ_MACH_O_H */



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