From b2b620601bdb9510dd5c2900bae6a4de314aa272 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Fri, 9 Oct 2009 08:18:17 +0000 Subject: [PATCH] 2009-10-09 Tristan Gingold * mach-o.c (bfd_mach_o_section_get_entry_size): Moved. (bfd_mach_o_section_get_nbr_indirect): Ditto. (bfd_mach_o_get_synthetic_symtab): New function. (bfd_mach_o_print_private_header): Print the number of commands in decimal. * mach-o.h (bfd_mach_o_get_synthetic_symtab): Add prototype. * mach-o-target.c: Do not defined bfd_mach_o_get_synthetic_symtab. --- bfd/ChangeLog | 10 +++ bfd/mach-o-target.c | 1 - bfd/mach-o.c | 174 +++++++++++++++++++++++++++++++++++++++++----------- bfd/mach-o.h | 2 + 4 files changed, 149 insertions(+), 38 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index ca9ef5d..4197163 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2009-10-09 Tristan Gingold + + * mach-o.c (bfd_mach_o_section_get_entry_size): Moved. + (bfd_mach_o_section_get_nbr_indirect): Ditto. + (bfd_mach_o_get_synthetic_symtab): New function. + (bfd_mach_o_print_private_header): Print the number of commands + in decimal. + * mach-o.h (bfd_mach_o_get_synthetic_symtab): Add prototype. + * mach-o-target.c: Do not defined bfd_mach_o_get_synthetic_symtab. + 2009-10-08 Tristan Gingold * config.bfd: Add bfd_mach_o_i386_vec in x86_64-darwin targ_selvecs. diff --git a/bfd/mach-o-target.c b/bfd/mach-o-target.c index 5ea9412..c308467 100644 --- a/bfd/mach-o-target.c +++ b/bfd/mach-o-target.c @@ -70,7 +70,6 @@ #define bfd_mach_o_get_dynamic_symtab_upper_bound bfd_mach_o_get_symtab_upper_bound #define bfd_mach_o_canonicalize_dynamic_symtab bfd_mach_o_canonicalize_symtab -#define bfd_mach_o_get_synthetic_symtab _bfd_nodynamic_get_synthetic_symtab #define TARGET_NAME_BACKEND XCONCAT2(TARGET_NAME,_backend) diff --git a/bfd/mach-o.c b/bfd/mach-o.c index 747a637..cbffce6 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -254,6 +254,43 @@ bfd_mach_o_convert_section_name_to_mach_o (bfd *abfd ATTRIBUTE_UNUSED, section->sectname[len] = 0; } +/* Return the size of an entry for section SEC. + Must be called only for symbol pointer section and symbol stubs + sections. */ + +static unsigned int +bfd_mach_o_section_get_entry_size (bfd *abfd, bfd_mach_o_section *sec) +{ + 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: + return bfd_mach_o_wide_p (abfd) ? 8 : 4; + case BFD_MACH_O_S_SYMBOL_STUBS: + return sec->reserved2; + default: + BFD_FAIL (); + return 0; + } +} + +/* Return the number of indirect symbols for a section. + Must be called only for symbol pointer section and symbol stubs + sections. */ + +static unsigned int +bfd_mach_o_section_get_nbr_indirect (bfd *abfd, bfd_mach_o_section *sec) +{ + unsigned int elsz; + + elsz = bfd_mach_o_section_get_entry_size (abfd, sec); + if (elsz == 0) + return 0; + else + return sec->size / elsz; +} + + /* Copy any private info we understand from the input symbol to the output symbol. */ @@ -344,6 +381,105 @@ bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation) return nsyms; } +long +bfd_mach_o_get_synthetic_symtab (bfd *abfd, + long symcount ATTRIBUTE_UNUSED, + asymbol **syms ATTRIBUTE_UNUSED, + long dynsymcount ATTRIBUTE_UNUSED, + asymbol **dynsyms ATTRIBUTE_UNUSED, + asymbol **ret) +{ + bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); + bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab; + bfd_mach_o_symtab_command *symtab = mdata->symtab; + asymbol *s; + unsigned long count, i, j, n; + size_t size; + char *names; + char *nul_name; + + *ret = NULL; + + if (dysymtab == NULL || symtab == NULL || symtab->symbols == NULL) + return 0; + + if (dysymtab->nindirectsyms == 0) + return 0; + + count = dysymtab->nindirectsyms; + size = count * sizeof (asymbol) + 1; + + for (j = 0; j < count; j++) + { + unsigned int isym = dysymtab->indirect_syms[j]; + + if (isym < symtab->nsyms && symtab->symbols[isym].symbol.name) + size += strlen (symtab->symbols[isym].symbol.name) + sizeof ("$stub"); + } + + s = *ret = (asymbol *) bfd_malloc (size); + if (s == NULL) + return -1; + names = (char *) (s + count); + nul_name = names; + *names++ = 0; + + n = 0; + for (i = 0; i < mdata->nsects; i++) + { + bfd_mach_o_section *sec = mdata->sections[i]; + unsigned int j, first, last; + bfd_mach_o_symtab_command *symtab = mdata->symtab; + bfd_vma addr; + bfd_vma entry_size; + + 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: + first = sec->reserved1; + last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec); + addr = sec->addr; + entry_size = bfd_mach_o_section_get_entry_size (abfd, sec); + for (j = first; j < last; j++) + { + unsigned int isym = dysymtab->indirect_syms[j]; + + s->flags = BSF_GLOBAL | BSF_SYNTHETIC; + s->section = sec->bfdsection; + s->value = addr - sec->addr; + s->udata.p = NULL; + + if (isym < symtab->nsyms + && symtab->symbols[isym].symbol.name) + { + const char *sym = symtab->symbols[isym].symbol.name; + size_t len; + + s->name = names; + len = strlen (sym); + memcpy (names, sym, len); + names += len; + memcpy (names, "$stub", sizeof ("$stub")); + names += sizeof ("$stub"); + } + else + s->name = nul_name; + + addr += entry_size; + s++; + n++; + } + break; + default: + break; + } + } + + return n; +} + void bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED, asymbol *symbol, @@ -3231,7 +3367,7 @@ bfd_mach_o_print_private_header (bfd *abfd, FILE *file) fprintf (file, _(" filetype : %08lx (%s)\n"), h->filetype, bfd_mach_o_get_name (bfd_mach_o_filetype_name, h->filetype)); - fprintf (file, _(" ncmds : %08lx\n"), h->ncmds); + fprintf (file, _(" ncmds : %08lx (%lu)\n"), h->ncmds, h->ncmds); fprintf (file, _(" sizeofcmds: %08lx\n"), h->sizeofcmds); fprintf (file, _(" flags : %08lx ("), h->flags); bfd_mach_o_print_flags (bfd_mach_o_header_flags_name, h->flags, file); @@ -3281,42 +3417,6 @@ bfd_mach_o_print_section_map (bfd *abfd, FILE *file) } } -/* Return the size of an entry for section SEC. - Must be called only for symbol pointer section and symbol stubs - sections. */ - -static unsigned int -bfd_mach_o_section_get_entry_size (bfd *abfd, bfd_mach_o_section *sec) -{ - 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: - return bfd_mach_o_wide_p (abfd) ? 8 : 4; - case BFD_MACH_O_S_SYMBOL_STUBS: - return sec->reserved2; - default: - BFD_FAIL (); - return 0; - } -} - -/* Return the number of indirect symbols for a section. - Must be called only for symbol pointer section and symbol stubs - sections. */ - -static unsigned int -bfd_mach_o_section_get_nbr_indirect (bfd *abfd, bfd_mach_o_section *sec) -{ - unsigned int elsz; - - elsz = bfd_mach_o_section_get_entry_size (abfd, sec); - if (elsz == 0) - return 0; - else - return sec->size / elsz; -} - static void bfd_mach_o_print_section (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_section *sec, FILE *file) diff --git a/bfd/mach-o.h b/bfd/mach-o.h index b86fe07..c91080a 100644 --- a/bfd/mach-o.h +++ b/bfd/mach-o.h @@ -876,6 +876,8 @@ bfd_boolean bfd_mach_o_bfd_copy_private_section_data (bfd *, asection *, bfd_boolean bfd_mach_o_bfd_copy_private_bfd_data (bfd *, bfd *); long bfd_mach_o_get_symtab_upper_bound (bfd *); long bfd_mach_o_canonicalize_symtab (bfd *, asymbol **); +long bfd_mach_o_get_synthetic_symtab (bfd *, long, asymbol **, long, + asymbol **, asymbol **ret); long bfd_mach_o_get_reloc_upper_bound (bfd *, asection *); long bfd_mach_o_canonicalize_reloc (bfd *, asection *, arelent **, asymbol **); long bfd_mach_o_get_dynamic_reloc_upper_bound (bfd *); -- 2.7.4