add symbol qualifiers for mach-o to bfd/gas
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.
This commit is contained in:
parent
9f2f828a17
commit
b22161d698
16 changed files with 750 additions and 221 deletions
|
@ -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
|
||||
|
|
266
bfd/mach-o.c
266
bfd/mach-o.c
|
@ -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)
|
||||
{
|
||||
unsigned i, sect;
|
||||
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;
|
||||
|
||||
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)
|
||||
|
|
18
bfd/mach-o.h
18
bfd/mach-o.h
|
@ -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_ */
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -82,34 +82,9 @@ 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 ();
|
||||
}
|
||||
|
||||
/* 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
|
||||
delimiter, a warning is given and the string is truncated. On completion of
|
||||
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
12
gas/testsuite/gas/mach-o/err-syms-1.s
Normal file
12
gas/testsuite/gas/mach-o/err-syms-1.s
Normal file
|
@ -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 }
|
15
gas/testsuite/gas/mach-o/err-syms-2.s
Normal file
15
gas/testsuite/gas/mach-o/err-syms-2.s
Normal file
|
@ -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 }
|
10
gas/testsuite/gas/mach-o/err-syms-3.s
Normal file
10
gas/testsuite/gas/mach-o/err-syms-3.s
Normal file
|
@ -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 }
|
7
gas/testsuite/gas/mach-o/symbols-2.d
Normal file
7
gas/testsuite/gas/mach-o/symbols-2.d
Normal file
|
@ -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
|
9
gas/testsuite/gas/mach-o/symbols-2.s
Normal file
9
gas/testsuite/gas/mach-o/symbols-2.s
Normal file
|
@ -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
|
111
gas/testsuite/gas/mach-o/symbols-3.s
Normal file
111
gas/testsuite/gas/mach-o/symbols-3.s
Normal file
|
@ -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
|
65
gas/testsuite/gas/mach-o/symbols-4.s
Normal file
65
gas/testsuite/gas/mach-o/symbols-4.s
Normal file
|
@ -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
|
11
gas/testsuite/gas/mach-o/symbols-5.d
Normal file
11
gas/testsuite/gas/mach-o/symbols-5.d
Normal file
|
@ -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
|
17
gas/testsuite/gas/mach-o/symbols-5.s
Normal file
17
gas/testsuite/gas/mach-o/symbols-5.s
Normal file
|
@ -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
|
Loading…
Reference in a new issue