From: Iain Sandoe Date: Thu, 12 Jan 2012 14:03:12 +0000 (+0000) Subject: add indirect_symbol to mach-o port. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=50d10658eef31d1c68763d556f02954b9c7c4f00;p=binutils-gdb.git add indirect_symbol to mach-o port. bfd: * mach-o.c (bfd_mach_o_count_indirect_symbols): New. (bfd_mach_o_build_dysymtab_command): Populate indirect symbol table. * mach-o.h (bfd_mach_o_asymbol): Move declaration to start of the file. (bfd_mach_o_section): Add indirect_syms field. gas: * config/obj-macho.c (obj_mach_o_set_symbol_qualifier): Switch off lazy when the symbol is private_extern. (obj_mach_o_indirect_sym): New type. (obj_mach_o_indirect_symbol): New. (mach_o_pseudo_table): Use obj_mach_o_indirect_symbol. (obj_macho_frob_label): Adjust to avoid adding bsyms for locals. (obj_macho_frob_label): Likewise. Adjust external and comm symbol tests. (obj_mach_o_set_indirect_symbols): New. (obj_mach_o_frob_file_after_relocs): New. *config/obj-macho.h (obj_frob_file_after_relocs): Define. (obj_mach_o_frob_file_after_relocs): Declare. include/mach-o: * loader.h (BFD_MACH_O_INDIRECT_SYM_LOCAL): New. (BFD_MACH_O_INDIRECT_SYM_ABS): New gas/testsuite: * gas/mach-o/dysymtab-2.d: New. * gas/mach-o/err-syms-4.s: New. * gas/mach-o/err-syms-5.s: New. * gas/mach-o/err-syms-6.s: New. * gas/mach-o/symbols-6-64.d: New. * gas/mach-o/symbols-6-64.s: New. * gas/mach-o/symbols-6.d: New. * gas/mach-o/symbols-6.s: New. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 55ccf7e5d5c..7e36b6d81df 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2012-01-12 Iain Sandoe + + * mach-o.c (bfd_mach_o_count_indirect_symbols): New. + (bfd_mach_o_build_dysymtab_command): Populate indirect symbol table. + * mach-o.h (bfd_mach_o_asymbol): Move declaration to start of the + file. (bfd_mach_o_section): Add indirect_syms field. + 2012-01-11 Iain Sandoe * mach-o.c (bfd_mach_o_build_seg_command): Separate computation of diff --git a/bfd/mach-o.c b/bfd/mach-o.c index 6913b1d929d..c5196631c4a 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -2079,6 +2079,33 @@ bfd_mach_o_build_seg_command (const char *segment, return TRUE; } +/* Count the number of indirect symbols in the image. + Requires that the sections are in their final order. */ + +static unsigned int +bfd_mach_o_count_indirect_symbols (bfd *abfd, bfd_mach_o_data_struct *mdata) +{ + unsigned int i; + unsigned int nisyms = 0; + + for (i = 0; i < mdata->nsects; ++i) + { + bfd_mach_o_section *sec = mdata->sections[i]; + + switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK) + { + case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS: + case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS: + case BFD_MACH_O_S_SYMBOL_STUBS: + nisyms += bfd_mach_o_section_get_nbr_indirect (abfd, sec); + break; + default: + break; + } + } + return nisyms; +} + static bfd_boolean bfd_mach_o_build_dysymtab_command (bfd *abfd, bfd_mach_o_data_struct *mdata, @@ -2135,9 +2162,11 @@ bfd_mach_o_build_dysymtab_command (bfd *abfd, dsym->nundefsym = 0; } + dsym->nindirectsyms = bfd_mach_o_count_indirect_symbols (abfd, mdata); if (dsym->nindirectsyms > 0) { unsigned i; + unsigned n; mdata->filelen = FILE_ALIGN (mdata->filelen, 2); dsym->indirectsymoff = mdata->filelen; @@ -2146,11 +2175,38 @@ bfd_mach_o_build_dysymtab_command (bfd *abfd, dsym->indirect_syms = bfd_zalloc (abfd, dsym->nindirectsyms * 4); if (dsym->indirect_syms == NULL) return FALSE; - - /* So fill in the indices. */ - for (i = 0; i < dsym->nindirectsyms; ++i) + + n = 0; + for (i = 0; i < mdata->nsects; ++i) { - /* TODO: fill in the table. */ + bfd_mach_o_section *sec = mdata->sections[i]; + + switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK) + { + case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS: + case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS: + case BFD_MACH_O_S_SYMBOL_STUBS: + { + unsigned j, num; + bfd_mach_o_asymbol **isyms = sec->indirect_syms; + + num = bfd_mach_o_section_get_nbr_indirect (abfd, sec); + if (isyms == NULL || num == 0) + break; + /* Record the starting index in the reserved1 field. */ + sec->reserved1 = n; + for (j = 0; j < num; j++, n++) + { + if (isyms[j] == NULL) + dsym->indirect_syms[n] = BFD_MACH_O_INDIRECT_SYM_LOCAL; + else + dsym->indirect_syms[n] = isyms[j]->symbol.udata.i; + } + } + break; + default: + break; + } } } diff --git a/bfd/mach-o.h b/bfd/mach-o.h index ca810a03f37..7f54961c7f3 100644 --- a/bfd/mach-o.h +++ b/bfd/mach-o.h @@ -42,6 +42,18 @@ typedef struct bfd_mach_o_header } bfd_mach_o_header; +typedef struct bfd_mach_o_asymbol +{ + /* The actual symbol which the rest of BFD works with. */ + asymbol symbol; + + /* Mach-O symbol fields. */ + unsigned char n_type; + unsigned char n_sect; + unsigned short n_desc; +} +bfd_mach_o_asymbol; + #define BFD_MACH_O_SEGNAME_SIZE 16 #define BFD_MACH_O_SECTNAME_SIZE 16 @@ -64,6 +76,12 @@ typedef struct bfd_mach_o_section /* Corresponding bfd section. */ asection *bfdsection; + /* An array holding the indirect symbols for this section. + NULL values indicate local symbols. + The number of symbols is determined from the section size and type. */ + + bfd_mach_o_asymbol **indirect_syms; + /* Simply linked list. */ struct bfd_mach_o_section *next; } @@ -105,26 +123,12 @@ typedef struct bfd_mach_o_reloc_info } bfd_mach_o_reloc_info; -typedef struct bfd_mach_o_asymbol -{ - /* The actual symbol which the rest of BFD works with. */ - asymbol symbol; - - /* Mach-O symbol fields. */ - unsigned char n_type; - unsigned char n_sect; - unsigned short n_desc; -} -bfd_mach_o_asymbol; - /* The symbol table is sorted like this: (1) local. (otherwise in order of generation) (2) external defined (sorted by name) - (3) external undefined - (sorted by name) - (4) common + (3) external undefined / common (sorted by name) */ diff --git a/gas/ChangeLog b/gas/ChangeLog index d4f2e7acbd4..4acdbb6fb2e 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,18 @@ +2012-01-12 Iain Sandoe + + * config/obj-macho.c (obj_mach_o_set_symbol_qualifier): Switch off + lazy when the symbol is private_extern. + (obj_mach_o_indirect_sym): New type. + (obj_mach_o_indirect_symbol): New. + (mach_o_pseudo_table): Use obj_mach_o_indirect_symbol. + (obj_macho_frob_label): Adjust to avoid adding bsyms for locals. + (obj_macho_frob_label): Likewise. Adjust external and comm + symbol tests. + (obj_mach_o_set_indirect_symbols): New. + (obj_mach_o_frob_file_after_relocs): New. + *config/obj-macho.h (obj_frob_file_after_relocs): Define. + (obj_mach_o_frob_file_after_relocs): Declare. + 2012-01-12 Tristan Gingold PR gas/13591 diff --git a/gas/config/obj-macho.c b/gas/config/obj-macho.c index 43f4fba658e..61e6771326e 100644 --- a/gas/config/obj-macho.c +++ b/gas/config/obj-macho.c @@ -1032,6 +1032,7 @@ obj_mach_o_set_symbol_qualifier (symbolS *sym, int type) case OBJ_MACH_O_SYM_PRIV_EXT: s->n_type |= BFD_MACH_O_N_PEXT ; + s->n_desc &= ~LAZY; /* The native tool switches this off too. */ /* We follow the system tools in marking PEXT as also global. */ /* Fall through. */ @@ -1131,13 +1132,77 @@ obj_mach_o_sym_qual (int ntype) demand_empty_rest_of_line (); } -/* Dummy function to allow test-code to work while we are working - on things. */ +typedef struct obj_mach_o_indirect_sym +{ + symbolS *sym; + segT sect; + struct obj_mach_o_indirect_sym *next; +} obj_mach_o_indirect_sym; + +/* We store in order an maintain a pointer to the last one - to save reversing + later. */ +obj_mach_o_indirect_sym *indirect_syms; +obj_mach_o_indirect_sym *indirect_syms_tail; static void -obj_mach_o_placeholder (int arg ATTRIBUTE_UNUSED) +obj_mach_o_indirect_symbol (int arg ATTRIBUTE_UNUSED) { - ignore_rest_of_line (); + bfd_mach_o_section *sec = bfd_mach_o_get_mach_o_section (now_seg); + +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + + if (obj_mach_o_is_static) + as_bad (_("use of .indirect_symbols requires `-dynamic'")); + + switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK) + { + case BFD_MACH_O_S_SYMBOL_STUBS: + case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS: + case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS: + { + obj_mach_o_indirect_sym *isym; + char *name = input_line_pointer; + char c = get_symbol_end (); + symbolS *sym = symbol_find_or_make (name); + unsigned int elsize = + bfd_mach_o_section_get_entry_size (stdoutput, sec); + + if (elsize == 0) + { + as_bad (_("attempt to add an indirect_symbol to a stub or" + " reference section with a zero-sized element at %s"), + name); + *input_line_pointer = c; + ignore_rest_of_line (); + return; + } + *input_line_pointer = c; + + isym = (obj_mach_o_indirect_sym *) + xmalloc (sizeof (obj_mach_o_indirect_sym)); + + /* Just record the data for now, we will validate it when we + compute the output in obj_mach_o_set_indirect_symbols. */ + isym->sym = sym; + isym->sect = now_seg; + isym->next = NULL; + if (indirect_syms == NULL) + indirect_syms = isym; + else + indirect_syms_tail->next = isym; + indirect_syms_tail = isym; + } + break; + + default: + as_bad (_("an .indirect_symbol must be in a symbol pointer" + " or stub section.")); + ignore_rest_of_line (); + return; + } + demand_empty_rest_of_line (); } const pseudo_typeS mach_o_pseudo_table[] = @@ -1231,7 +1296,7 @@ const pseudo_typeS mach_o_pseudo_table[] = {"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}, + { "indirect_symbol", obj_mach_o_indirect_symbol, 0}, /* File flags. */ { "subsections_via_symbols", obj_mach_o_fileprop, @@ -1270,15 +1335,25 @@ obj_mach_o_type_for_symbol (bfd_mach_o_asymbol *s) 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); + bfd_mach_o_asymbol *s; + unsigned base_type; + bfd_mach_o_section *sec; int sectype = -1; + /* Leave local symbols alone. */ + + if (S_IS_LOCAL (sp)) + return; + + s = (bfd_mach_o_asymbol *) symbol_get_bfdsym (sp); + /* Leave debug symbols alone. */ if ((s->n_type & BFD_MACH_O_N_STAB) != 0) - return; /* Leave alone. */ - + return; + + /* This is the base symbol type, that we mask in. */ + base_type = obj_mach_o_type_for_symbol (s); + + sec = bfd_mach_o_get_mach_o_section (s->symbol.section); if (sec != NULL) sectype = sec->flags & BFD_MACH_O_SECTION_TYPE_MASK; @@ -1307,34 +1382,41 @@ void obj_macho_frob_label (struct symbol *sp) 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); + bfd_mach_o_asymbol *s; + unsigned base_type; + bfd_mach_o_section *sec; int sectype = -1; - + + /* Leave local symbols alone. */ + if (S_IS_LOCAL (sp)) + return 0; + + s = (bfd_mach_o_asymbol *) symbol_get_bfdsym (sp); + /* Leave debug symbols alone. */ + if ((s->n_type & BFD_MACH_O_N_STAB) != 0) + return 0; + + base_type = obj_mach_o_type_for_symbol (s); + sec = bfd_mach_o_get_mach_o_section (s->symbol.section); 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) + 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; - + /* Undefined syms, become extern. */ + s->n_type |= BFD_MACH_O_N_EXT; + S_SET_EXTERNAL (sp); + } + else if (s->symbol.section == bfd_com_section_ptr) + { + /* ... so do comm. */ + s->n_type |= BFD_MACH_O_N_EXT; + S_SET_EXTERNAL (sp); } else { @@ -1353,6 +1435,7 @@ obj_macho_frob_symbol (struct symbol *sp) { /* Anything here that should be added that is non-standard. */ s->n_desc &= ~BFD_MACH_O_REFERENCE_MASK; + s->symbol.udata.i = SYM_MACHO_FIELDS_NOT_VALIDATED; } else if (s->symbol.udata.i == SYM_MACHO_FIELDS_NOT_VALIDATED) { @@ -1388,6 +1471,125 @@ obj_macho_frob_symbol (struct symbol *sp) return 0; } +static void +obj_mach_o_set_indirect_symbols (bfd *abfd, asection *sec, + void *xxx ATTRIBUTE_UNUSED) +{ + bfd_vma sect_size = bfd_section_size (abfd, sec); + bfd_mach_o_section *ms = bfd_mach_o_get_mach_o_section (sec); + unsigned lazy = 0; + + /* See if we have any indirect syms to consider. */ + if (indirect_syms == NULL) + return; + + /* Process indirect symbols. + Check for errors, if OK attach them as a flat array to the section + for which they are defined. */ + + switch (ms->flags & BFD_MACH_O_SECTION_TYPE_MASK) + { + case BFD_MACH_O_S_SYMBOL_STUBS: + case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS: + lazy = LAZY; + /* Fall through. */ + case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS: + { + unsigned int nactual = 0; + unsigned int ncalc; + obj_mach_o_indirect_sym *isym; + obj_mach_o_indirect_sym *list = NULL; + obj_mach_o_indirect_sym *list_tail = NULL; + unsigned long eltsiz = + bfd_mach_o_section_get_entry_size (abfd, ms); + + for (isym = indirect_syms; isym != NULL; isym = isym->next) + { + if (isym->sect == sec) + { + nactual++; + if (list == NULL) + list = isym; + else + list_tail->next = isym; + list_tail = isym; + } + } + + /* If none are in this section, stop here. */ + if (nactual == 0) + break; + + /* If we somehow added indirect symbols to a section with a zero + entry size, we're dead ... */ + gas_assert (eltsiz != 0); + + ncalc = (unsigned int) (sect_size / eltsiz); + if (nactual != ncalc) + as_bad (_("the number of .indirect_symbols defined in section %s" + " does not match the number expected (%d defined, %d" + " expected)"), sec->name, nactual, ncalc); + else + { + unsigned n; + bfd_mach_o_asymbol *sym; + ms->indirect_syms = + bfd_zalloc (abfd, + nactual * sizeof (bfd_mach_o_asymbol *)); + + if (ms->indirect_syms == NULL) + { + as_fatal (_("internal error: failed to allocate %d indirect" + "symbol pointers"), nactual); + } + + for (isym = list, n = 0; isym != NULL; isym = isym->next, n++) + { + /* Array is init to NULL & NULL signals a local symbol + If the section is lazy-bound, we need to keep the + reference to the symbol, since dyld can override. */ + if (S_IS_LOCAL (isym->sym) && ! lazy) + ; + else + { + sym = (bfd_mach_o_asymbol *)symbol_get_bfdsym (isym->sym); + if (sym == NULL) + ; + /* If the symbols is external ... */ + else if (S_IS_EXTERNAL (isym->sym) + || (sym->n_type & BFD_MACH_O_N_EXT) + || ! S_IS_DEFINED (isym->sym) + || lazy) + { + sym->n_desc &= ~LAZY; + /* ... it can be lazy, if not defined or hidden. */ + if ((sym->n_type & BFD_MACH_O_N_TYPE) + == BFD_MACH_O_N_UNDF + && ! (sym->n_type & BFD_MACH_O_N_PEXT) + && (sym->n_type & BFD_MACH_O_N_EXT)) + sym->n_desc |= lazy; + ms->indirect_syms[n] = sym; + } + } + } + } + } + break; + + default: + break; + } +} + +/* The process of relocation could alter what's externally visible, thus we + leave setting the indirect symbols until last. */ + +void +obj_mach_o_frob_file_after_relocs (void) +{ + bfd_map_over_sections (stdoutput, obj_mach_o_set_indirect_symbols, (char *) 0); +} + /* Support stabs for mach-o. */ void diff --git a/gas/config/obj-macho.h b/gas/config/obj-macho.h index cbc3a4fce53..9f1f3db568a 100644 --- a/gas/config/obj-macho.h +++ b/gas/config/obj-macho.h @@ -62,6 +62,9 @@ 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 obj_frob_file_after_relocs obj_mach_o_frob_file_after_relocs +extern void obj_mach_o_frob_file_after_relocs (void); + #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) diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 3176c0c1af9..4f6fa30fcdb 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2012-01-12 Iain Sandoe + + * gas/mach-o/dysymtab-2.d: New. + * gas/mach-o/err-syms-4.s: New. + * gas/mach-o/err-syms-5.s: New. + * gas/mach-o/err-syms-6.s: New. + * gas/mach-o/symbols-6-64.d: New. + * gas/mach-o/symbols-6-64.s: New. + * gas/mach-o/symbols-6.d: New. + * gas/mach-o/symbols-6.s: New. + 2012-01-09 Iain Sandoe * gas/mach-o/err-syms-1.s: New. diff --git a/gas/testsuite/gas/mach-o/dysymtab-2.d b/gas/testsuite/gas/mach-o/dysymtab-2.d new file mode 100644 index 00000000000..a1a38b57aa4 --- /dev/null +++ b/gas/testsuite/gas/mach-o/dysymtab-2.d @@ -0,0 +1,45 @@ +#as: -L -I $srcdir/$subdir +#objdump: -P dysymtab +#target: i?86-*-darwin* powerpc-*-darwin* +#source: symbols-6.s +.*: +file format mach-o.* +#... +Load command dysymtab: +( )+local symbols: idx:( )+0( )+num: 55( )+\(nxtidx: 55\) +( )+external symbols: idx:( )+55( )+num: 24( )+\(nxtidx: 79\) +( )+undefined symbols: idx:( )+79( )+num: 30( )+\(nxtidx: 109\) +( )+table of content: off: 0x00000000( )+num: 0( )+\(endoff: 0x00000000\) +( )+module table: off: 0x00000000( )+num: 0( )+\(endoff: 0x00000000\) +( )+external reference table: off: 0x00000000( )+num: 0( )+\(endoff: 0x00000000\) +( )+indirect symbol table: off: 0x000003b0( )+num: 25( )+\(endoff: 0x00000414\) +( )+external relocation table: off: 0x00000000( )+num: 0( )+\(endoff: 0x00000000\) +( )+local relocation table: off: 0x00000000( )+num: 0( )+\(endoff: 0x00000000\) +( )+indirect symbols: +( )+for section __dummy.__dummy: +( )+0000000000000000( )+0: 0x0000005e a +( )+0000000000000008( )+1: 0x00000063 b +( )+0000000000000010( )+2: 0x0000003d c +( )+0000000000000018( )+3: 0x0000001b d +( )+0000000000000020( )+4: 0x00000018 e +( )+0000000000000028( )+5: 0x00000040 f +( )+0000000000000030( )+6: 0x00000066 g +( )+for section __DATA.__la_symbol_ptr: +( )+0000000000000000( )+7: 0x0000005f a1 +( )+0000000000000004( )+8: 0x00000064 b1 +( )+0000000000000008( )+9: 0x0000003e c1 +( )+000000000000000c( )+10: 0x0000001c d1 +( )+0000000000000010( )+11: 0x00000019 e1 +( )+0000000000000014( )+12: 0x00000041 f1 +( )+0000000000000018( )+13: 0x00000067 g1 +( )+for section __DATA.__nl_symbol_ptr: +( )+0000000000000000( )+14: 0x00000060 a2 +( )+0000000000000004( )+15: 0x00000065 b2 +( )+0000000000000008( )+16: 0x0000003f c2 +( )+000000000000000c( )+17: 0x80000000 LOCAL +( )+0000000000000010( )+18: 0x80000000 LOCAL +( )+0000000000000014( )+19: 0x00000042 f2 +( )+0000000000000018( )+20: 0x00000068 g2 +( )+000000000000001c( )+21: 0x00000041 f1 +( )+0000000000000020( )+22: 0x00000067 g1 +( )+0000000000000024( )+23: 0x00000060 a2 +( )+0000000000000028( )+24: 0x00000065 b2 diff --git a/gas/testsuite/gas/mach-o/err-syms-4.s b/gas/testsuite/gas/mach-o/err-syms-4.s new file mode 100644 index 00000000000..0bb55e9eb12 --- /dev/null +++ b/gas/testsuite/gas/mach-o/err-syms-4.s @@ -0,0 +1,6 @@ +# { dg-do assemble } + + .indirect_symbol a + +# { dg-error " an .indirect_symbol must be in a symbol pointer or stub section." "" { target *-*-darwin*} 3 } + diff --git a/gas/testsuite/gas/mach-o/err-syms-5.s b/gas/testsuite/gas/mach-o/err-syms-5.s new file mode 100644 index 00000000000..684bef04c0c --- /dev/null +++ b/gas/testsuite/gas/mach-o/err-syms-5.s @@ -0,0 +1,40 @@ +# { dg-do assemble { target i?86-*-darwin* powerpc*-*-darwin* } } + +# Show that we can check that there are enough syms for the section. + +# too few. + + .section __dummy, __dummy, symbol_stubs,strip_static_syms,4 + + .indirect_symbol a + + .section __dummy, __dummy1,lazy_symbol_pointers + + .indirect_symbol b + + .section __dummy, __dummy2,non_lazy_symbol_pointers + + .indirect_symbol c + +# OK. + .section __dummy, __dummy3,non_lazy_symbol_pointers + + .indirect_symbol d + .space 4 + + .section __dummy, __dummy4,symbol_stubs,strip_static_syms,17 + + .indirect_symbol e + .space 17 + +# too many + + .section __dummy, __dummy5,lazy_symbol_pointers + + .indirect_symbol f + .space 8 + +# { dg-error "the number of .indirect_symbols defined in section __dummy.__dummy does not match the number expected .1 defined, 0 expected." "" { target *-*-darwin*} 0 } +# { dg-error "the number of .indirect_symbols defined in section __dummy.__dummy1 does not match the number expected .1 defined, 0 expected." "" { target *-*-darwin*} 0 } +# { dg-error "the number of .indirect_symbols defined in section __dummy.__dummy2 does not match the number expected .1 defined, 0 expected." "" { target *-*-darwin*} 0 } +# { dg-error "the number of .indirect_symbols defined in section __dummy.__dummy5 does not match the number expected .1 defined, 2 expected." "" { target *-*-darwin*} 0 } diff --git a/gas/testsuite/gas/mach-o/err-syms-6.s b/gas/testsuite/gas/mach-o/err-syms-6.s new file mode 100644 index 00000000000..95db793c2f8 --- /dev/null +++ b/gas/testsuite/gas/mach-o/err-syms-6.s @@ -0,0 +1,20 @@ +# { dg-do assemble { target x86_64-*-darwin* } } + + .section __dummy, __dummy, symbol_stubs,strip_static_syms,4 + + .indirect_symbol a + + .section __dummy, __dummy1,lazy_symbol_pointers + + .indirect_symbol b + + .section __dummy, __dummy2,non_lazy_symbol_pointers + + .indirect_symbol c + +# { dg-error "unknown or invalid section type .symbol_stubs." "" { target x86_64-*-darwin* } 3 } +# { dg-error "an .indirect_symbol must be in a symbol pointer or stub section" "" { target x86_64-*-darwin* } 5 } +# { dg-error "unknown or invalid section type .lazy_symbol_pointers." "" { target x86_64-*-darwin* } 7 } +# { dg-error "an .indirect_symbol must be in a symbol pointer or stub section" "" { target x86_64-*-darwin* } 9 } +# { dg-error "unknown or invalid section type .non_lazy_symbol_pointers." "" { target x86_64-*-darwin* } 11 } +# { dg-error "an .indirect_symbol must be in a symbol pointer or stub section" "" { target x86_64-*-darwin* } 13 } diff --git a/gas/testsuite/gas/mach-o/symbols-6-64.d b/gas/testsuite/gas/mach-o/symbols-6-64.d new file mode 100644 index 00000000000..77b38c4513c --- /dev/null +++ b/gas/testsuite/gas/mach-o/symbols-6-64.d @@ -0,0 +1,116 @@ +#as: -L -I $srcdir/$subdir +#objdump: -t +#target: powerpc64-*-darwin* +#source: symbols-6-64.s +.*: +file format mach-o.* +#... +SYMBOL TABLE: +0000000000000000 l.*0e SECT.*01 0000 \[.text\] Lzt0 +0000000000000002 l.*0e SECT.*01 0000 \[.text\] Lmt0 +0000000000000004 l.*0e SECT.*01 0000 \[.text\] Lat0 +0000000000000000 l.*0e SECT.*02 0000 \[.data\] Lzd0 +0000000000000002 l.*0e SECT.*02 0000 \[.data\] Lmd0 +0000000000000005 l.*0e SECT.*02 0000 \[.data\] Lad0 +0000000000000000 l.*0e SECT.*03 0000 \[.bss\] zlcomm0 +0000000000000006 l.*0e SECT.*03 0000 \[.bss\] mlcomm0 +000000000000000c l.*0e SECT.*03 0000 \[.bss\] alcomm0 +0000000000000000 l.*0e SECT.*04 0000 \[__HERE.__there\] Lzs0 +0000000000000002 l.*0e SECT.*04 0000 \[__HERE.__there\] Lms0 +0000000000000004 l.*0e SECT.*04 0000 \[__HERE.__there\] Las0 +0000000000000012 l.*0e SECT.*01 0000 \[.text\] Lzt1 +0000000000000015 l.*0e SECT.*01 0000 \[.text\] Lmt1 +0000000000000017 l.*0e SECT.*01 0000 \[.text\] Lat1 +0000000000000012 l.*0e SECT.*02 0000 \[.data\] Lzd1 +0000000000000014 l.*0e SECT.*02 0000 \[.data\] Lmd1 +0000000000000017 l.*0e SECT.*02 0000 \[.data\] Lad1 +0000000000000012 l.*0e SECT.*03 0000 \[.bss\] zlcomm1 +0000000000000018 l.*0e SECT.*03 0000 \[.bss\] mlcomm1 +000000000000001e l.*0e SECT.*03 0000 \[.bss\] alcomm1 +0000000000000016 l.*0e SECT.*04 0000 \[__HERE.__there\] Lzs1 +000000000000001e l.*0e SECT.*04 0000 \[__HERE.__there\] Lms1 +000000000000001f l.*0e SECT.*04 0000 \[__HERE.__there\] Las1 +000000000000001b l.*0e SECT.*01 0000 \[.text\] e +000000000000001c l.*0e SECT.*01 0000 \[.text\] e1 +000000000000001d l.*0e SECT.*01 0000 \[.text\] e2 +0000000000000024 l.*0e SECT.*02 0000 \[.data\] d +000000000000002c l.*0e SECT.*02 0000 \[.data\] d1 +0000000000000034 l.*0e SECT.*02 0000 \[.data\] d2 +0000000000000000 l.*0e SECT.*05 0000 \[__dummy.__dummy\] La +0000000000000008 l.*0e SECT.*05 0000 \[__dummy.__dummy\] Lb +0000000000000010 l.*0e SECT.*05 0000 \[__dummy.__dummy\] Lc +0000000000000018 l.*0e SECT.*05 0000 \[__dummy.__dummy\] Ld +0000000000000020 l.*0e SECT.*05 0000 \[__dummy.__dummy\] Le +0000000000000028 l.*0e SECT.*05 0000 \[__dummy.__dummy\] Lf +0000000000000030 l.*0e SECT.*05 0000 \[__dummy.__dummy\] Lg +0000000000000000 l.*0e SECT.*06 0000 \[.lazy_symbol_pointer\] La1 +0000000000000004 l.*0e SECT.*06 0000 \[.lazy_symbol_pointer\] Lb1 +0000000000000008 l.*0e SECT.*06 0000 \[.lazy_symbol_pointer\] Lc1 +000000000000000c l.*0e SECT.*06 0000 \[.lazy_symbol_pointer\] Ld1 +0000000000000010 l.*0e SECT.*06 0000 \[.lazy_symbol_pointer\] Le1 +0000000000000014 l.*0e SECT.*06 0000 \[.lazy_symbol_pointer\] Lf1 +0000000000000018 l.*0e SECT.*06 0000 \[.lazy_symbol_pointer\] Lg1 +0000000000000000 l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] La2 +0000000000000004 l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] Lb2 +0000000000000008 l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] Lc2 +000000000000000c l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] Ld2 +0000000000000010 l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] Le2 +0000000000000014 l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] Lf2 +0000000000000018 l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] Lg2 +000000000000001c l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] Lf11 +0000000000000020 l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] Lg11 +0000000000000024 l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] La12 +0000000000000028 l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] Lb12 +0000000000000004 g.*0f SECT.*02 0000 \[.data\] adg0 +0000000000000016 g.*0f SECT.*02 0000 \[.data\] adg1 +0000000000000005 g.*0f SECT.*04 0000 \[__HERE.__there\] asg0 +000000000000001d g.*0f SECT.*04 0000 \[__HERE.__there\] asg1 +0000000000000005 g.*0f SECT.*01 0000 \[.text\] atg0 +0000000000000016 g.*0f SECT.*01 0000 \[.text\] atg1 +0000000000000018 g.*0f SECT.*01 0000 \[.text\] c +0000000000000019 g.*0f SECT.*01 0000 \[.text\] c1 +000000000000001a g.*0f SECT.*01 0000 \[.text\] c2 +000000000000003c g.*1f SECT.*02 0000 \[.data\] f +0000000000000044 g.*1f SECT.*02 0000 \[.data\] f1 +000000000000004c g.*1f SECT.*02 0000 \[.data\] f2 +0000000000000003 g.*0f SECT.*02 0000 \[.data\] mdg0 +0000000000000015 g.*0f SECT.*02 0000 \[.data\] mdg1 +0000000000000003 g.*0f SECT.*04 0000 \[__HERE.__there\] msg0 +000000000000001c g.*0f SECT.*04 0000 \[__HERE.__there\] msg1 +0000000000000003 g.*0f SECT.*01 0000 \[.text\] mtg0 +0000000000000014 g.*0f SECT.*01 0000 \[.text\] mtg1 +0000000000000001 g.*0f SECT.*02 0000 \[.data\] zdg0 +0000000000000013 g.*0f SECT.*02 0000 \[.data\] zdg1 +0000000000000001 g.*0f SECT.*04 0000 \[__HERE.__there\] zsg0 +0000000000000017 g.*0f SECT.*04 0000 \[__HERE.__there\] zsg1 +0000000000000001 g.*0f SECT.*01 0000 \[.text\] ztg0 +0000000000000013 g.*0f SECT.*01 0000 \[.text\] ztg1 +0000000000000000 g.*01 UND.*00 0000 _aud0 +0000000000000000 g.*01 UND.*00 0000 _aud1 +0000000000000000 g.*01 UND.*00 0000 _aus0 +0000000000000000 g.*01 UND.*00 0000 _aus1 +0000000000000000 g.*01 UND.*00 0000 _aut0 +0000000000000000 g.*01 UND.*00 0000 _mud0 +0000000000000000 g.*01 UND.*00 0000 _mud1 +0000000000000000 g.*01 UND.*00 0000 _mus0 +0000000000000000 g.*01 UND.*00 0000 _mus1 +0000000000000000 g.*01 UND.*00 0000 _mut0 +0000000000000000 g.*01 UND.*00 0000 _zud0 +0000000000000000 g.*01 UND.*00 0000 _zud1 +0000000000000000 g.*01 UND.*00 0000 _zus0 +0000000000000000 g.*01 UND.*00 0000 _zus1 +0000000000000000 g.*01 UND.*00 0000 _zut0 +0000000000000000 g.*01 UND.*00 0001 a +0000000000000000 g.*01 UND.*00 0001 a1 +0000000000000000 g.*01 UND.*00 0000 a2 +000000000000000a.*01 COM.*00 0300 acommon0 +000000000000000a.*01 COM.*00 0300 acommon1 +0000000000000000 g.*01 UND.*00 0001 b +0000000000000000 g.*01 UND.*00 0001 b1 +0000000000000000 g.*01 UND.*00 0000 b2 +0000000000000000 g.*11 UND.*00 0001 g +0000000000000000 g.*11 UND.*00 0001 g1 +0000000000000000 g.*11 UND.*00 0000 g2 +000000000000000a.*01 COM.*00 0300 mcommon0 +000000000000000a.*01 COM.*00 0300 mcommon1 +000000000000000a.*01 COM.*00 0300 zcommon0 +000000000000000a.*01 COM.*00 0300 zcommon1 diff --git a/gas/testsuite/gas/mach-o/symbols-6-64.s b/gas/testsuite/gas/mach-o/symbols-6-64.s new file mode 100644 index 00000000000..255536074ed --- /dev/null +++ b/gas/testsuite/gas/mach-o/symbols-6-64.s @@ -0,0 +1,4 @@ +# now look at what happens when we append some indirects to the normal +# syms. + .include "symbols-base-64.s" + .include "symbols-3.s" diff --git a/gas/testsuite/gas/mach-o/symbols-6.d b/gas/testsuite/gas/mach-o/symbols-6.d new file mode 100644 index 00000000000..96cca411cab --- /dev/null +++ b/gas/testsuite/gas/mach-o/symbols-6.d @@ -0,0 +1,116 @@ +#as: -L -I $srcdir/$subdir +#objdump: -t +#target: i?86-*-darwin* powerpc-*-darwin* +#source: symbols-6.s +.*: +file format mach-o.* +#... +SYMBOL TABLE: +00000000 l.*0e SECT.*01 0000 \[.text\] Lzt0 +00000002 l.*0e SECT.*01 0000 \[.text\] Lmt0 +00000004 l.*0e SECT.*01 0000 \[.text\] Lat0 +00000000 l.*0e SECT.*02 0000 \[.data\] Lzd0 +00000002 l.*0e SECT.*02 0000 \[.data\] Lmd0 +00000005 l.*0e SECT.*02 0000 \[.data\] Lad0 +00000000 l.*0e SECT.*03 0000 \[.bss\] zlcomm0 +00000006 l.*0e SECT.*03 0000 \[.bss\] mlcomm0 +0000000c l.*0e SECT.*03 0000 \[.bss\] alcomm0 +00000000 l.*0e SECT.*04 0000 \[__HERE.__there\] Lzs0 +00000002 l.*0e SECT.*04 0000 \[__HERE.__there\] Lms0 +00000004 l.*0e SECT.*04 0000 \[__HERE.__there\] Las0 +00000012 l.*0e SECT.*01 0000 \[.text\] Lzt1 +00000015 l.*0e SECT.*01 0000 \[.text\] Lmt1 +00000017 l.*0e SECT.*01 0000 \[.text\] Lat1 +00000012 l.*0e SECT.*02 0000 \[.data\] Lzd1 +00000014 l.*0e SECT.*02 0000 \[.data\] Lmd1 +00000017 l.*0e SECT.*02 0000 \[.data\] Lad1 +00000012 l.*0e SECT.*03 0000 \[.bss\] zlcomm1 +00000018 l.*0e SECT.*03 0000 \[.bss\] mlcomm1 +0000001e l.*0e SECT.*03 0000 \[.bss\] alcomm1 +00000016 l.*0e SECT.*04 0000 \[__HERE.__there\] Lzs1 +0000001e l.*0e SECT.*04 0000 \[__HERE.__there\] Lms1 +0000001f l.*0e SECT.*04 0000 \[__HERE.__there\] Las1 +0000001b l.*0e SECT.*01 0000 \[.text\] e +0000001c l.*0e SECT.*01 0000 \[.text\] e1 +0000001d l.*0e SECT.*01 0000 \[.text\] e2 +00000024 l.*0e SECT.*02 0000 \[.data\] d +0000002c l.*0e SECT.*02 0000 \[.data\] d1 +00000034 l.*0e SECT.*02 0000 \[.data\] d2 +00000000 l.*0e SECT.*05 0000 \[__dummy.__dummy\] La +00000008 l.*0e SECT.*05 0000 \[__dummy.__dummy\] Lb +00000010 l.*0e SECT.*05 0000 \[__dummy.__dummy\] Lc +00000018 l.*0e SECT.*05 0000 \[__dummy.__dummy\] Ld +00000020 l.*0e SECT.*05 0000 \[__dummy.__dummy\] Le +00000028 l.*0e SECT.*05 0000 \[__dummy.__dummy\] Lf +00000030 l.*0e SECT.*05 0000 \[__dummy.__dummy\] Lg +00000000 l.*0e SECT.*06 0000 \[.lazy_symbol_pointer\] La1 +00000004 l.*0e SECT.*06 0000 \[.lazy_symbol_pointer\] Lb1 +00000008 l.*0e SECT.*06 0000 \[.lazy_symbol_pointer\] Lc1 +0000000c l.*0e SECT.*06 0000 \[.lazy_symbol_pointer\] Ld1 +00000010 l.*0e SECT.*06 0000 \[.lazy_symbol_pointer\] Le1 +00000014 l.*0e SECT.*06 0000 \[.lazy_symbol_pointer\] Lf1 +00000018 l.*0e SECT.*06 0000 \[.lazy_symbol_pointer\] Lg1 +00000000 l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] La2 +00000004 l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] Lb2 +00000008 l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] Lc2 +0000000c l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] Ld2 +00000010 l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] Le2 +00000014 l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] Lf2 +00000018 l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] Lg2 +0000001c l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] Lf11 +00000020 l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] Lg11 +00000024 l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] La12 +00000028 l.*0e SECT.*07 0000 \[.non_lazy_symbol_pointer\] Lb12 +00000004 g.*0f SECT.*02 0000 \[.data\] adg0 +00000016 g.*0f SECT.*02 0000 \[.data\] adg1 +00000005 g.*0f SECT.*04 0000 \[__HERE.__there\] asg0 +0000001d g.*0f SECT.*04 0000 \[__HERE.__there\] asg1 +00000005 g.*0f SECT.*01 0000 \[.text\] atg0 +00000016 g.*0f SECT.*01 0000 \[.text\] atg1 +00000018 g.*0f SECT.*01 0000 \[.text\] c +00000019 g.*0f SECT.*01 0000 \[.text\] c1 +0000001a g.*0f SECT.*01 0000 \[.text\] c2 +0000003c g.*1f SECT.*02 0000 \[.data\] f +00000044 g.*1f SECT.*02 0000 \[.data\] f1 +0000004c g.*1f SECT.*02 0000 \[.data\] f2 +00000003 g.*0f SECT.*02 0000 \[.data\] mdg0 +00000015 g.*0f SECT.*02 0000 \[.data\] mdg1 +00000003 g.*0f SECT.*04 0000 \[__HERE.__there\] msg0 +0000001c g.*0f SECT.*04 0000 \[__HERE.__there\] msg1 +00000003 g.*0f SECT.*01 0000 \[.text\] mtg0 +00000014 g.*0f SECT.*01 0000 \[.text\] mtg1 +00000001 g.*0f SECT.*02 0000 \[.data\] zdg0 +00000013 g.*0f SECT.*02 0000 \[.data\] zdg1 +00000001 g.*0f SECT.*04 0000 \[__HERE.__there\] zsg0 +00000017 g.*0f SECT.*04 0000 \[__HERE.__there\] zsg1 +00000001 g.*0f SECT.*01 0000 \[.text\] ztg0 +00000013 g.*0f SECT.*01 0000 \[.text\] ztg1 +00000000 g.*01 UND.*00 0000 _aud0 +00000000 g.*01 UND.*00 0000 _aud1 +00000000 g.*01 UND.*00 0000 _aus0 +00000000 g.*01 UND.*00 0000 _aus1 +00000000 g.*01 UND.*00 0000 _aut0 +00000000 g.*01 UND.*00 0000 _mud0 +00000000 g.*01 UND.*00 0000 _mud1 +00000000 g.*01 UND.*00 0000 _mus0 +00000000 g.*01 UND.*00 0000 _mus1 +00000000 g.*01 UND.*00 0000 _mut0 +00000000 g.*01 UND.*00 0000 _zud0 +00000000 g.*01 UND.*00 0000 _zud1 +00000000 g.*01 UND.*00 0000 _zus0 +00000000 g.*01 UND.*00 0000 _zus1 +00000000 g.*01 UND.*00 0000 _zut0 +00000000 g.*01 UND.*00 0001 a +00000000 g.*01 UND.*00 0001 a1 +00000000 g.*01 UND.*00 0000 a2 +0000000a.*01 COM.*00 0300 acommon0 +0000000a.*01 COM.*00 0300 acommon1 +00000000 g.*01 UND.*00 0001 b +00000000 g.*01 UND.*00 0001 b1 +00000000 g.*01 UND.*00 0000 b2 +00000000 g.*11 UND.*00 0000 g +00000000 g.*11 UND.*00 0000 g1 +00000000 g.*11 UND.*00 0000 g2 +0000000a.*01 COM.*00 0300 mcommon0 +0000000a.*01 COM.*00 0300 mcommon1 +0000000a.*01 COM.*00 0300 zcommon0 +0000000a.*01 COM.*00 0300 zcommon1 diff --git a/gas/testsuite/gas/mach-o/symbols-6.s b/gas/testsuite/gas/mach-o/symbols-6.s new file mode 100644 index 00000000000..d909fbfc8d8 --- /dev/null +++ b/gas/testsuite/gas/mach-o/symbols-6.s @@ -0,0 +1,4 @@ +# now look at what happens when we append some indirects to the normal +# syms. + .include "symbols-base.s" + .include "symbols-3.s" diff --git a/include/mach-o/ChangeLog b/include/mach-o/ChangeLog index 2cd71c963e6..ab3cc6828ab 100644 --- a/include/mach-o/ChangeLog +++ b/include/mach-o/ChangeLog @@ -1,3 +1,8 @@ +2012-01-12 Iain Sandoe + + * loader.h (BFD_MACH_O_INDIRECT_SYM_LOCAL): New. + (BFD_MACH_O_INDIRECT_SYM_ABS): New + 2012-01-04 Tristan Gingold * external.h (mach_o_fvmlib_command_external): New structure. diff --git a/include/mach-o/loader.h b/include/mach-o/loader.h index 824f7936749..1b9b15efe35 100644 --- a/include/mach-o/loader.h +++ b/include/mach-o/loader.h @@ -320,6 +320,9 @@ bfd_mach_o_section_attribute; #define BFD_MACH_O_N_NO_DEAD_STRIP 0x20 #define BFD_MACH_O_N_WEAK_REF 0x40 #define BFD_MACH_O_N_WEAK_DEF 0x80 + +#define BFD_MACH_O_INDIRECT_SYM_LOCAL 0x80000000 +#define BFD_MACH_O_INDIRECT_SYM_ABS 0x40000000 /* Thread constants. */