diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 7 | ||||
-rw-r--r-- | bfd/mach-o.c | 64 | ||||
-rw-r--r-- | bfd/mach-o.h | 34 |
3 files changed, 86 insertions, 19 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 55ccf7e..7e36b6d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2012-01-12 Iain Sandoe <idsandoe@googlemail.com> + + * 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 <idsandoe@googlemail.com> * 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 6913b1d..c519663 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 ca810a0..7f54961 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) */ |