/[gcl]/gcl/binutils/bfd/mach-o.c
ViewVC logotype

Diff of /gcl/binutils/bfd/mach-o.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3.2.1.14.2 by camm, Wed Nov 30 20:25:17 2005 UTC revision 1.3.2.1.14.3 by camm, Thu Dec 1 22:07:17 2005 UTC
# Line 20  Line 20 
20    
21  #include "mach-o.h"  #include "mach-o.h"
22  #include "bfd.h"  #include "bfd.h"
23    #include "bfdlink.h"
24  #include "sysdep.h"  #include "sysdep.h"
25  #include "libbfd.h"  #include "libbfd.h"
26  #include "libiberty.h"  #include "libiberty.h"
# Line 51  Line 52 
52  #define bfd_mach_o_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol  #define bfd_mach_o_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
53  #define bfd_mach_o_read_minisymbols _bfd_generic_read_minisymbols  #define bfd_mach_o_read_minisymbols _bfd_generic_read_minisymbols
54  #define bfd_mach_o_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol  #define bfd_mach_o_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
55  #define bfd_mach_o_get_reloc_upper_bound _bfd_norelocs_get_reloc_upper_bound  /* default versions not appropriate */
56  #define bfd_mach_o_canonicalize_reloc _bfd_norelocs_canonicalize_reloc  /* #define bfd_mach_o_get_reloc_upper_bound _bfd_norelocs_get_reloc_upper_bound */
57  #define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup  /* #define bfd_mach_o_canonicalize_reloc _bfd_norelocs_canonicalize_reloc */
58  #define bfd_mach_o_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents  /* #define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup */
59    /* #define bfd_mach_o_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents */
60  #define bfd_mach_o_bfd_relax_section bfd_generic_relax_section  #define bfd_mach_o_bfd_relax_section bfd_generic_relax_section
61  #define bfd_mach_o_bfd_link_hash_table_create _bfd_generic_link_hash_table_create  #define bfd_mach_o_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
62  #define bfd_mach_o_bfd_link_hash_table_free _bfd_generic_link_hash_table_free  #define bfd_mach_o_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
63  #define bfd_mach_o_bfd_link_add_symbols _bfd_generic_link_add_symbols  /* default version not appropriate */
64    /* #define bfd_mach_o_bfd_link_add_symbols _bfd_generic_link_add_symbols */
65  #define bfd_mach_o_bfd_link_just_syms _bfd_generic_link_just_syms  #define bfd_mach_o_bfd_link_just_syms _bfd_generic_link_just_syms
66  #define bfd_mach_o_bfd_final_link _bfd_generic_final_link  #define bfd_mach_o_bfd_final_link _bfd_generic_final_link
67  #define bfd_mach_o_bfd_link_split_section _bfd_generic_link_split_section  #define bfd_mach_o_bfd_link_split_section _bfd_generic_link_split_section
# Line 142  static const char * bfd_mach_o_i386_flav Line 145  static const char * bfd_mach_o_i386_flav
145  static const char * bfd_mach_o_ppc_flavour_string  static const char * bfd_mach_o_ppc_flavour_string
146    PARAMS ((unsigned int));    PARAMS ((unsigned int));
147    
148    /* the following functions are necessary for relocation */
149    static int bfd_mach_o_compar_st_idx
150      PARAMS ((const void *, const void *));
151    static void bfd_mach_o_dump_ist_aux
152      PARAMS ((bfd *, bfd_mach_o_symtab_command *, bfd_mach_o_section **, unsigned long, unsigned long));
153    static void bfd_mach_o_dump_ist
154      PARAMS ((bfd *, bfd_mach_o_symtab_command *));
155    static bfd_boolean bfd_mach_o_check_ist
156      PARAMS ((bfd_mach_o_ist *));
157    static bfd_mach_o_ist * bfd_mach_o_slurp_ist
158      PARAMS ((bfd *));
159    static bfd_vma bfd_mach_o_get_lazy_symbol_stub
160      PARAMS ((bfd_mach_o_ist *, unsigned long, asection **));
161    static bfd_vma bfd_mach_o_get_non_lazy_symbol_ptr
162      PARAMS ((bfd_mach_o_ist *, unsigned long, asection **));
163    static bfd_boolean bfd_mach_o_bfd_link_add_symbols
164      PARAMS ((bfd *, struct bfd_link_info *));
165    
166  /* The flags field of a section structure is separated into two parts a section  /* The flags field of a section structure is separated into two parts a section
167     type and section attributes.  The section types are mutually exclusive (it     type and section attributes.  The section types are mutually exclusive (it
168     can only have one type) but the section attributes are not (it may have more     can only have one type) but the section attributes are not (it may have more
# Line 279  bfd_mach_o_canonicalize_symtab (abfd, al Line 300  bfd_mach_o_canonicalize_symtab (abfd, al
300          {          {
301            bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;            bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
302    
303            if (bfd_mach_o_scan_read_symtab_symbols (abfd, &mdata->commands[i].command.symtab) != 0)            if (bfd_mach_o_scan_read_symtab_symbols (abfd, sym) != 0)
304              {              {
305                fprintf (stderr, "bfd_mach_o_canonicalize_symtab: unable to load symbols for section %lu\n", i);                fprintf (stderr, "bfd_mach_o_canonicalize_symtab: unable to load symbols for section %lu\n", i);
306                return 0;                return 0;
307              }              }
308    
309            BFD_ASSERT (sym->symbols != NULL);            BFD_ASSERT (sym->nlists != NULL);
310    
311            for (j = 0; j < sym->nsyms; j++)            for (j = 0; j < sym->nsyms; j++)
312              {              {
313                BFD_ASSERT (csym < (alocation + nsyms));                BFD_ASSERT (csym < (alocation + nsyms));
314                *csym++ = &sym->symbols[j];                *csym++ = &(sym->nlists[j].root);
315              }              }
316          }          }
317      }      }
318    
319    *csym++ = NULL;    *csym++ = NULL;
320    
321      bfd_get_symcount (abfd) = nsyms;
322      mdata->nsymbols = nsyms;
323    
324    return nsyms;    return nsyms;
325  }  }
326    
# Line 344  bfd_mach_o_convert_architecture (mtype, Line 368  bfd_mach_o_convert_architecture (mtype,
368      case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;      case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
369      case BFD_MACH_O_CPU_TYPE_I386: *type = bfd_arch_i386; break;      case BFD_MACH_O_CPU_TYPE_I386: *type = bfd_arch_i386; break;
370      case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;      case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
371      case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;   /* I'm in a hurry : comment this out for now (Aurelien, 14-II-04). */
372     /* I can't remember why I commented this out (Aurelien, 1-XII-05). */
373     /* case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break; */
374      case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;      case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
375      case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;      case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
376      case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;      case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;
# Line 364  bfd_mach_o_convert_architecture (mtype, Line 390  bfd_mach_o_convert_architecture (mtype,
390      }      }
391  }  }
392    
393    /*
394    We don't need these for GCL (Aurelien, 14-II-04).
395    
396    int
397    bfd_mach_o_compar_symbols (void *a, void *b)
398    {
399      static char *empty_symbol_name = "";
400      asymbol *s = (asymbol *) a;
401      asymbol *t = (asymbol *) b;
402      
403      if (s->name == NULL)
404        s->name = empty_symbol_name;
405      if (t->name == NULL)
406        t->name = empty_symbol_name;
407      
408      if (s->flags & BSF_DEBUGGING)
409        {
410          if (t->flags & BSF_DEBUGGING)
411            return strcmp (s->name, t->name);
412          else
413            return -1;
414        }
415      else if (s->flags & BSF_LOCAL)
416        {
417          if (t->flags & BSF_DEBUGGING)
418            return +1;
419          else if (t->flags & BSF_LOCAL)
420            return strcmp (s->name, t->name);
421          else
422            return -1;
423        }
424      else
425        {
426          asection *ssect = s->section;
427          asection *tsect = t->section;
428          
429          if (!(bfd_is_und_section (ssect) || bfd_is_com_section (ssect)))
430            {
431              if (t->flags & BSF_LOCAL)
432                return +1;
433              else if (!(bfd_is_und_section (tsect) || bfd_is_com_section (tsect)))
434                return strcmp (s->name, t->name);
435              else
436                return -1;
437            }
438          else
439            {
440              if (t->flags & BSF_LOCAL)
441                return +1;
442              else if (!(bfd_is_und_section (tsect) || bfd_is_com_section (tsect)))
443                return +1;
444              else
445                return strcmp (s->name, t->name);
446            }
447        }
448    }
449    
450    boolean
451    bfd_mach_o_sort_symtab (abfd, link_info)
452         bfd *abfd;
453         struct bfd_link_info *link_info;
454    {
455      bfd_mach_o_symtab_command *st = mach_o_symtab (abfd);
456      int i, symcount = bfd_get_symcount (abfd);
457      bfd_mach_o_nlist *nlists;
458      bfd_size_type strtab_size;
459      char *strtab;
460      asymbol *sym_ptr;
461      int num_loc_syms, num_ext_syms, num_und_syms;
462      bfd_mach_o_nlist *loc_sym_ptr, *ext_sym_ptr, *und_sym_ptr;
463      
464      if (st == NULL)
465        {
466          st = (bfd_mach_o_symtab_command *)
467            bfd_zalloc (abfd, sizeof (bfd_mach_o_symtab_command));
468          mach_o_symtab (abfd) = st;
469        }
470    
471      if (st == NULL)
472        return false;
473    
474      if (symcount == 0)
475        return true;
476      
477      nlists = st->nlists;
478      
479      if (nlists == NULL)
480        {
481          nlists = (bfd_mach_o_nlist *)
482            bfd_zalloc (abfd, sizeof (bfd_mach_o_nlist) * symcount);
483          st->nlists = nlists;
484        }
485    
486      if (nlists == NULL)
487        return false;
488      
489      strtab_size = 0;
490      sym_ptr = mach_o_tdata (abfd)->symbols;
491      
492      num_loc_syms = 0;
493      num_ext_syms = 0;
494      num_und_syms = 0;
495      
496      for (i=0 ; i < symcount ; i++, sym_ptr++)
497        {
498          if (sym_ptr->name != NULL)
499            strtab_size += strlen (sym_ptr->name);
500          
501          if (sym_ptr->flags & BSF_GLOBAL)
502            {
503              asection *asect = sym_ptr->section;
504              
505              if (bfd_is_und_section (asect) || bfd_is_com_section (asect))
506                num_und_syms++;
507              else
508                num_ext_syms++;
509            }
510          else
511            num_loc_syms++;
512        }
513    
514      strtab = (char *) bfd_zalloc (abfd, strtab_size);
515    
516      if (strtab == NULL)
517        return false;
518      
519      sym_ptr = mach_o_tdata (abfd)->symbols;
520      
521      loc_sym_ptr = nlists;
522      ext_sym_ptr = loc_sym_ptr + num_loc_syms;
523      und_sym_ptr = ext_sym_ptr + num_ext_syms;
524      
525      for (i=0 ; i < symcount ; i++, sym_ptr++)
526        {
527          if (sym_ptr->flags & BSF_GLOBAL)
528            {
529              if (bfd_is_und_section (sym_ptr->section) ||
530                  bfd_is_com_section (sym_ptr->section))
531                (*und_sym_ptr++).root = *sym;
532              else
533                (*ext_sym_ptr++).root = *sym;
534            }
535          else
536            (*loc_sym_ptr++).root = *sym;
537        }
538        
539    }
540    */
541    
542  static bfd_boolean  static bfd_boolean
543  bfd_mach_o_write_contents (abfd)  bfd_mach_o_write_contents (abfd)
544       bfd *abfd;       bfd *abfd;
# Line 379  bfd_mach_o_write_contents (abfd) Line 554  bfd_mach_o_write_contents (abfd)
554    for (s = abfd->sections; s != (asection *) NULL; s = s->next)    for (s = abfd->sections; s != (asection *) NULL; s = s->next)
555      ;      ;
556    
557    #if 0
558      for (i = 0; i < mdata->header.ncmds; i++)
559        {
560          bfd_mach_o_load_command *cur = &mdata->commands[i];
561          if (cur->type != BFD_MACH_O_LC_SEGMENT)
562            break;
563    
564          {
565            bfd_mach_o_segment_command *seg = &cur->command.segment;
566            char buf[1024];
567            bfd_vma nbytes = seg->filesize;
568            bfd_vma curoff = seg->fileoff;
569    
570            while (nbytes > 0)
571              {
572                bfd_vma thisread = nbytes;
573    
574                if (thisread > 1024)
575                  thisread = 1024;
576    
577                bfd_seek (abfd, curoff, SEEK_SET);
578                if (bfd_bread ((PTR) buf, thisread, abfd) != thisread)
579                  return false;
580    
581                bfd_seek (abfd, curoff, SEEK_SET);
582                if (bfd_bwrite ((PTR) buf, thisread, abfd) != thisread)
583                  return false;
584    
585                nbytes -= thisread;
586                curoff += thisread;
587              }
588          }
589      }
590    #endif
591    
592    /* Now write header information.  */    /* Now write header information.  */
593    if (bfd_mach_o_write_header (abfd, &mdata->header) != 0)    if (bfd_mach_o_write_header (abfd, &mdata->header) != 0)
594      return FALSE;      return FALSE;
# Line 542  bfd_mach_o_make_bfd_section (abfd, secti Line 752  bfd_mach_o_make_bfd_section (abfd, secti
752      + strlen (section->segname) + 1      + strlen (section->segname) + 1
753      + strlen (section->sectname) + 1;      + strlen (section->sectname) + 1;
754    
755    sname = (char *) bfd_alloc (abfd, snamelen);    sname = (char *) bfd_zalloc (abfd, snamelen);
756    if (sname == NULL)    if (sname == NULL)
757      return NULL;      return NULL;
758    sprintf (sname, "%s.%s.%s", prefix, section->segname, section->sectname);    sprintf (sname, "%s.%s.%s", prefix, section->segname, section->sectname);
# Line 554  bfd_mach_o_make_bfd_section (abfd, secti Line 764  bfd_mach_o_make_bfd_section (abfd, secti
764    bfdsec->vma = section->addr;    bfdsec->vma = section->addr;
765    bfdsec->lma = section->addr;    bfdsec->lma = section->addr;
766    bfdsec->size = section->size;    bfdsec->size = section->size;
767    /*bfdsec->_raw_size = section->size;*/
768    bfdsec->filepos = section->offset;    bfdsec->filepos = section->offset;
769    bfdsec->alignment_power = section->align;    bfdsec->alignment_power = section->align;
770      bfdsec->rel_filepos = section->reloff;
771      bfdsec->reloc_count = section->nreloc;
772    
773      /* I suspect that bfdsec->userdata is, at most, volatile.  When we really
774         need the value of section->flags, we will have to do something else to
775         store it for good.  */
776      bfdsec->userdata = (PTR) section->flags;
777    
778    if (section->flags & BFD_MACH_O_S_ZEROFILL)    if (section->flags & BFD_MACH_O_S_ZEROFILL)
779      bfdsec->flags = SEC_ALLOC;      bfdsec->flags = SEC_ALLOC;
780    else    else
781      bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;      bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
782    
783      if (section->flags & BFD_MACH_O_S_LAZY_SYMBOL_POINTERS ||
784          section->flags & BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS) {
785        /* We want to do this because client program might rely on SEC_LOAD to
786           decide whether to call bfd_get_relocated_section_contents or not.
787           Altough a (non-)lazy symbol pointer section does not, stricly speaking,
788           have associated relocation entries, it contains symbol pointers to be
789           updated based on the global linker hash table.  */
790        bfdsec->flags |= SEC_LOAD;
791      }
792    
793      if (bfdsec->reloc_count > 0)
794        bfdsec->flags |= SEC_RELOC;
795    
796    return bfdsec;    return bfdsec;
797  }  }
798    
# Line 642  bfd_mach_o_scan_write_symtab_symbols (ab Line 873  bfd_mach_o_scan_write_symtab_symbols (ab
873        unsigned char nsect = 0;        unsigned char nsect = 0;
874        short ndesc = 0;        short ndesc = 0;
875    
876        s = &sym->symbols[i];        /*s = &sym->symbols[i];*/
877          s = &(sym->nlists[i].root);
878    
879          /* Don't set this from the symbol information; use stored values.  */
880    #if 0
881          if (s->flags & BSF_GLOBAL)
882            ntype |= N_EXT;
883          if (s->flags & BSF_DEBUGGING)
884            ntype |= N_STAB;
885    
886          if (s->section == bfd_und_section_ptr)
887            ntype |= N_UNDF;
888          else if (s->section == bfd_abs_section_ptr)
889            ntype |= N_ABS;
890          else
891            ntype |= N_SECT;
892    #endif
893    
894        /* Instead just set from the stored values.  */        /* Instead just set from the stored values.  */
895        ntype = (s->udata.i >> 24) & 0xff;        ntype = (s->udata.i >> 24) & 0xff;
# Line 668  bfd_mach_o_scan_write_symtab_symbols (ab Line 915  bfd_mach_o_scan_write_symtab_symbols (ab
915  }  }
916    
917  int  int
918  bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, i)  bfd_mach_o_scan_read_symtab_symbol (abfd, sym, nlist, i)
919       bfd *abfd;       bfd *abfd;
920       bfd_mach_o_symtab_command *sym;       bfd_mach_o_symtab_command *sym;
921       asymbol *s;       /*asymbol *s;*/
922         bfd_mach_o_nlist *nlist;
923       unsigned long i;       unsigned long i;
924  {  {
925    bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;    bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
# Line 683  bfd_mach_o_scan_read_symtab_symbol (abfd Line 931  bfd_mach_o_scan_read_symtab_symbol (abfd
931    unsigned long value = -1;    unsigned long value = -1;
932    unsigned long stroff = -1;    unsigned long stroff = -1;
933    unsigned int symtype = -1;    unsigned int symtype = -1;
934      bfd_mach_o_ist *ist = mdata->ist;
935    
936    BFD_ASSERT (sym->strtab != NULL);    BFD_ASSERT (sym->strtab != NULL);
937    
# Line 697  bfd_mach_o_scan_read_symtab_symbol (abfd Line 946  bfd_mach_o_scan_read_symtab_symbol (abfd
946    stroff = bfd_h_get_32 (abfd, buf);    stroff = bfd_h_get_32 (abfd, buf);
947    type = bfd_h_get_8 (abfd, buf + 4);    type = bfd_h_get_8 (abfd, buf + 4);
948    symtype = (type & 0x0e);    symtype = (type & 0x0e);
949    section = bfd_h_get_8 (abfd, buf + 5) - 1;    /* We dont want to substract -1 twice.  */
950      /* This is a bug in Apple's code (Aurelien, 1-XII-05).  */
951      section = bfd_h_get_8 (abfd, buf + 5) /* - 1 */;
952    desc = bfd_h_get_16 (abfd, buf + 6);    desc = bfd_h_get_16 (abfd, buf + 6);
953    value = bfd_h_get_32 (abfd, buf + 8);    value = bfd_h_get_32 (abfd, buf + 8);
954    
955      nlist->nlist.n_type = type;
956      nlist->nlist.n_sect = section;
957      nlist->nlist.n_desc = desc;
958      nlist->nlist.n_value = value;
959      
960      nlist->input_index = i;
961      nlist->output_index = (unsigned long) -1;
962    
963    if (stroff >= sym->strsize)    if (stroff >= sym->strsize)
964      {      {
965        fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",        fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
# Line 708  bfd_mach_o_scan_read_symtab_symbol (abfd Line 967  bfd_mach_o_scan_read_symtab_symbol (abfd
967        return -1;        return -1;
968      }      }
969    
970      /*
971    s->the_bfd = abfd;    s->the_bfd = abfd;
972    s->name = sym->strtab + stroff;    s->name = sym->strtab + stroff;
973    s->value = value;    s->value = value;
974    s->udata.i = (type << 24) | (section << 16) | desc;    s->udata.i = (type << 24) | (section << 16) | desc;
975    s->flags = 0x0;    s->flags = 0x0;
976      */
977    
978      nlist->root.the_bfd = abfd;
979      nlist->root.name = sym->strtab + stroff;
980      nlist->root.value = value;
981      /* Unfortunately, this cannot be relied on.  This field is volatile.  */
982      nlist->root.udata.i = (type << 24) | (section << 16) | desc;
983      nlist->root.flags = 0x0;
984    
985    if (type & BFD_MACH_O_N_STAB)    if (type & BFD_MACH_O_N_STAB)
986      {      {
987          /*
988        s->flags |= BSF_DEBUGGING;        s->flags |= BSF_DEBUGGING;
989        s->section = bfd_und_section_ptr;        s->section = bfd_und_section_ptr;
990          */
991          nlist->root.flags |= BSF_DEBUGGING;
992          nlist->root.section = bfd_und_section_ptr;
993      }      }
994    else    else
995      {      {
996        if (type & BFD_MACH_O_N_PEXT)        if (type & BFD_MACH_O_N_PEXT)
997          {          {
998              /* Why this for ? */
999              /* type &= ~BFD_MACH_O_N_PEXT; */
1000          /* I fail to remember why I commented this out (Aurelien, 1-XII-05).  */
1001              nlist->root.flags |= BSF_GLOBAL;
1002          /*
1003            type &= ~BFD_MACH_O_N_PEXT;            type &= ~BFD_MACH_O_N_PEXT;
1004            s->flags |= BSF_GLOBAL;            s->flags |= BSF_GLOBAL;
1005          */
1006          }          }
1007    
1008        if (type & BFD_MACH_O_N_EXT)        if (type & BFD_MACH_O_N_EXT)
1009          {          {
1010            type &= ~BFD_MACH_O_N_EXT;            type &= ~BFD_MACH_O_N_EXT;
1011            s->flags |= BSF_GLOBAL;            nlist->root.flags |= BSF_GLOBAL;
1012          }          }
1013    
1014        switch (symtype)        switch (symtype)
1015          {          {
1016          case BFD_MACH_O_N_UNDF:          case BFD_MACH_O_N_UNDF:
1017            s->section = bfd_und_section_ptr;            /* s->section = bfd_und_section_ptr; */
1018              nlist->root.section = bfd_und_section_ptr;
1019              if (type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT)) {
1020                if (value != 0)
1021                  {
1022                    /* This is a common symbol, actually.  */
1023                    nlist->root.section = bfd_com_section_ptr;
1024                  }
1025                else
1026                  {
1027                    /* There's not much we can do with an undefined symbol whose
1028                       value is zero.  Here, we try to find a stub or non-lazy
1029                       symbol pointer corresponding to this symbol.  ELF happens
1030                       to do the same thing with its undefined symbols, setting
1031                       them to point to PLT or GOT entries.  The code below is
1032                       rather heuristic but I can't find of any thing better for
1033                       now.  */
1034    
1035                    if (ist != NULL)
1036                      {
1037                        asection *indirect_section = NULL;
1038    
1039                        /* See if we can find a stub for this symbol.  */
1040                        if (ist->nstubs > 0)
1041                          nlist->root.value =
1042                            bfd_mach_o_get_lazy_symbol_stub (ist, i,
1043                                                             &indirect_section);
1044    
1045                        /* If no stub was found, look for a non-lazy ptr.  */
1046                        if (indirect_section == NULL && ist->nnlptrs > 0)
1047                          nlist->root.value =
1048                            bfd_mach_o_get_non_lazy_symbol_ptr (ist, i,
1049                                                                &indirect_section);
1050                        
1051                        /* If something was found, adjust the symbol value.  */
1052                        if (indirect_section != NULL)
1053                          nlist->root.value +=
1054                            indirect_section->vma - bfd_und_section_ptr->vma;
1055                      }
1056                  }
1057              }
1058            break;            break;
1059          case BFD_MACH_O_N_PBUD:          case BFD_MACH_O_N_PBUD:
1060            s->section = bfd_und_section_ptr;            /* s->section = bfd_und_section_ptr; */
1061              nlist->root.section = bfd_und_section_ptr;
1062            break;            break;
1063          case BFD_MACH_O_N_ABS:          case BFD_MACH_O_N_ABS:
1064            s->section = bfd_abs_section_ptr;            /* s->section = bfd_abs_section_ptr; */
1065              nlist->root.section = bfd_abs_section_ptr;
1066            break;            break;
1067          case BFD_MACH_O_N_SECT:          case BFD_MACH_O_N_SECT:
1068            if ((section > 0) && (section <= mdata->nsects))            if ((section > 0) && (section <= mdata->nsects))
1069              {              {
1070              /*
1071                s->section = mdata->sections[section - 1]->bfdsection;                s->section = mdata->sections[section - 1]->bfdsection;
1072                s->value = s->value - mdata->sections[section - 1]->addr;                s->value = s->value - mdata->sections[section - 1]->addr;
1073              */
1074                  nlist->root.section = mdata->sections[section - 1]->bfdsection;
1075                  nlist->root.value =
1076                      nlist->root.value - mdata->sections[section - 1]->addr;
1077              }              }
1078            else            else
1079              {              {
# Line 757  bfd_mach_o_scan_read_symtab_symbol (abfd Line 1082  bfd_mach_o_scan_read_symtab_symbol (abfd
1082                  {                  {
1083                    fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "                    fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
1084                             "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",                             "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
1085                             s->name, section, mdata->nsects);                             /*s->name*/ nlist->root.name, section, mdata->nsects);
1086                  }                  }
1087                s->section = bfd_und_section_ptr;                nlist->root.section = bfd_und_section_ptr;
1088              }              }
1089            break;            break;
1090          case BFD_MACH_O_N_INDR:          case BFD_MACH_O_N_INDR:
1091            fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "            fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
1092                     "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",                     "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
1093                     s->name);                     /*s->name*/ nlist->root.name);
1094            s->section = bfd_und_section_ptr;            /* s->section = bfd_und_section_ptr; */
1095              nlist->root.section = bfd_und_section_ptr;
1096            break;            break;
1097          default:          default:
1098            fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "            fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
1099                     "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",                     "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
1100                     s->name, symtype);                     /*s->name*/ nlist->root.name, symtype);
1101            s->section = bfd_und_section_ptr;            /* s->section = bfd_und_section_ptr; */
1102              nlist->root.section = bfd_und_section_ptr;
1103            break;            break;
1104          }          }
1105    
1106        if ((nlist->root.flags & BSF_GLOBAL) == 0)
1107              nlist->root.flags |= BSF_LOCAL;
1108      }      }
1109    
1110    return 0;    return 0;
# Line 785  bfd_mach_o_scan_read_symtab_strtab (abfd Line 1115  bfd_mach_o_scan_read_symtab_strtab (abfd
1115       bfd *abfd;       bfd *abfd;
1116       bfd_mach_o_symtab_command *sym;       bfd_mach_o_symtab_command *sym;
1117  {  {
1118    BFD_ASSERT (sym->strtab == NULL);    /* BFD_ASSERT (sym->strtab == NULL); */
1119      if (sym->strtab != NULL)
1120        return 0; /* If there's not work to be done, don't do any.  */
1121    
1122    if (abfd->flags & BFD_IN_MEMORY)    if (abfd->flags & BFD_IN_MEMORY)
1123      {      {
# Line 802  bfd_mach_o_scan_read_symtab_strtab (abfd Line 1134  bfd_mach_o_scan_read_symtab_strtab (abfd
1134        return 0;        return 0;
1135      }      }
1136    
1137    sym->strtab = bfd_alloc (abfd, sym->strsize);    sym->strtab = bfd_zalloc (abfd, sym->strsize);
1138    if (sym->strtab == NULL)    if (sym->strtab == NULL && sym->strsize != 0)
1139      return -1;      return -1;
1140    
1141    bfd_seek (abfd, sym->stroff, SEEK_SET);    bfd_seek (abfd, sym->stroff, SEEK_SET);
# Line 824  bfd_mach_o_scan_read_symtab_symbols (abf Line 1156  bfd_mach_o_scan_read_symtab_symbols (abf
1156  {  {
1157    unsigned long i;    unsigned long i;
1158    int ret;    int ret;
1159      bfd_mach_o_ist *ist;
1160      bfd_mach_o_nlist *nlist;
1161      
1162      if (sym->nlists != NULL)
1163        return TRUE; /* If there's not work to be done, don't do any.  */
1164    
1165      /*
1166    BFD_ASSERT (sym->symbols == NULL);    BFD_ASSERT (sym->symbols == NULL);
1167    sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (asymbol));    sym->symbols = bfd_zalloc (abfd, sym->nsyms * sizeof (asymbol));
1168      */
1169    
1170      sym->nlists = (bfd_mach_o_nlist *)
1171        bfd_zalloc (abfd, sym->nsyms * sizeof (bfd_mach_o_nlist));
1172      
1173      /*
1174    if (sym->symbols == NULL)    if (sym->symbols == NULL)
1175      {      {
1176        fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbols: unable to allocate memory for symbols\n");        fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbols: unable to allocate memory for symbols\n");
1177        return -1;        return -1;
1178      }      }
1179      */
1180      if (sym->nlists == NULL && sym->nsyms != 0)
1181        {
1182          fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbols: "
1183                   "unable to allocate memory for symbols\n");
1184          return -1;
1185        }
1186    
1187    ret = bfd_mach_o_scan_read_symtab_strtab (abfd, sym);    ret = bfd_mach_o_scan_read_symtab_strtab (abfd, sym);
1188    if (ret != 0)    if (ret != 0)
1189      return ret;      return ret;
1190    
1191    for (i = 0; i < sym->nsyms; i++)   ist = bfd_mach_o_slurp_ist (abfd);
1192      
1193      for (nlist = sym->nlists, i = 0; i < sym->nsyms; nlist++, i++)
1194      {      {
1195        ret = bfd_mach_o_scan_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);        ret = bfd_mach_o_scan_read_symtab_symbol (abfd, sym, nlist, i);
1196        if (ret != 0)        if (ret != 0)
1197          return ret;          return ret;
1198      }      }
# Line 849  bfd_mach_o_scan_read_symtab_symbols (abf Line 1201  bfd_mach_o_scan_read_symtab_symbols (abf
1201  }  }
1202    
1203  int  int
1204  bfd_mach_o_scan_read_dysymtab_symbol (abfd, dysym, sym, s, i)  bfd_mach_o_scan_read_dysymtab_symbol (abfd, dysym, sym, nlist, i)
1205       bfd *abfd;       bfd *abfd;
1206       bfd_mach_o_dysymtab_command *dysym;       bfd_mach_o_dysymtab_command *dysym;
1207       bfd_mach_o_symtab_command *sym;       bfd_mach_o_symtab_command *sym;
1208       asymbol *s;       /* asymbol *s; */
1209         bfd_mach_o_nlist *nlist;
1210       unsigned long i;       unsigned long i;
1211  {  {
1212    unsigned long isymoff = dysym->indirectsymoff + (i * 4);    unsigned long isymoff = dysym->indirectsymoff + (i * 4);
# Line 871  bfd_mach_o_scan_read_dysymtab_symbol (ab Line 1224  bfd_mach_o_scan_read_dysymtab_symbol (ab
1224      }      }
1225    symindex = bfd_h_get_32 (abfd, buf);    symindex = bfd_h_get_32 (abfd, buf);
1226    
1227    return bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, symindex);    /* return bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, symindex); */
1228      return bfd_mach_o_scan_read_symtab_symbol (abfd, sym, nlist, symindex);  
1229  }  }
1230    
1231  static const char *  static const char *
# Line 975  bfd_mach_o_scan_read_dylinker (abfd, com Line 1329  bfd_mach_o_scan_read_dylinker (abfd, com
1329    else    else
1330      abort ();      abort ();
1331    
1332    sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);    sname = (char *) bfd_zalloc (abfd, strlen (prefix) + 1);
1333    if (sname == NULL)    if (sname == NULL)
1334      return -1;      return -1;
1335    strcpy (sname, prefix);    strcpy (sname, prefix);
# Line 987  bfd_mach_o_scan_read_dylinker (abfd, com Line 1341  bfd_mach_o_scan_read_dylinker (abfd, com
1341    bfdsec->vma = 0;    bfdsec->vma = 0;
1342    bfdsec->lma = 0;    bfdsec->lma = 0;
1343    bfdsec->size = command->len - 8;    bfdsec->size = command->len - 8;
1344      /*bfdsec->_raw_size = command->len - 8;*/
1345    bfdsec->filepos = command->offset + 8;    bfdsec->filepos = command->offset + 8;
1346    bfdsec->alignment_power = 0;    bfdsec->alignment_power = 0;
1347    bfdsec->flags = SEC_HAS_CONTENTS;    bfdsec->flags = SEC_HAS_CONTENTS;
# Line 1033  bfd_mach_o_scan_read_dylib (abfd, comman Line 1388  bfd_mach_o_scan_read_dylib (abfd, comman
1388    else    else
1389      abort ();      abort ();
1390    
1391    sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);    sname = (char *) bfd_zalloc (abfd, strlen (prefix) + 1);
1392    if (sname == NULL)    if (sname == NULL)
1393      return -1;      return -1;
1394    strcpy (sname, prefix);    strcpy (sname, prefix);
# Line 1045  bfd_mach_o_scan_read_dylib (abfd, comman Line 1400  bfd_mach_o_scan_read_dylib (abfd, comman
1400    bfdsec->vma = 0;    bfdsec->vma = 0;
1401    bfdsec->lma = 0;    bfdsec->lma = 0;
1402    bfdsec->size = command->len - 8;    bfdsec->size = command->len - 8;
1403      /* bfdsec->_raw_size = command->len - 8; */
1404    bfdsec->filepos = command->offset + 8;    bfdsec->filepos = command->offset + 8;
1405    bfdsec->alignment_power = 0;    bfdsec->alignment_power = 0;
1406    bfdsec->flags = SEC_HAS_CONTENTS;    bfdsec->flags = SEC_HAS_CONTENTS;
# Line 1101  bfd_mach_o_scan_read_thread (abfd, comma Line 1457  bfd_mach_o_scan_read_thread (abfd, comma
1457    
1458    cmd->flavours =    cmd->flavours =
1459      ((bfd_mach_o_thread_flavour *)      ((bfd_mach_o_thread_flavour *)
1460       bfd_alloc (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour)));       bfd_zalloc (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour)));
1461    if (cmd->flavours == NULL)    if (cmd->flavours == NULL)
1462      return -1;      return -1;
1463    cmd->nflavours = nflavours;    cmd->nflavours = nflavours;
# Line 1151  bfd_mach_o_scan_read_thread (abfd, comma Line 1507  bfd_mach_o_scan_read_thread (abfd, comma
1507          }          }
1508    
1509        snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;        snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
1510        sname = (char *) bfd_alloc (abfd, snamelen);        sname = (char *) bfd_zalloc (abfd, snamelen);
1511        if (sname == NULL)        if (sname == NULL)
1512          return -1;          return -1;
1513    
# Line 1168  bfd_mach_o_scan_read_thread (abfd, comma Line 1524  bfd_mach_o_scan_read_thread (abfd, comma
1524        bfdsec->vma = 0;        bfdsec->vma = 0;
1525        bfdsec->lma = 0;        bfdsec->lma = 0;
1526        bfdsec->size = cmd->flavours[i].size;        bfdsec->size = cmd->flavours[i].size;
1527          /* bfdsec->_raw_size = cmd->flavours[i].size; */
1528        bfdsec->filepos = cmd->flavours[i].offset;        bfdsec->filepos = cmd->flavours[i].offset;
1529        bfdsec->alignment_power = 0x0;        bfdsec->alignment_power = 0x0;
1530        bfdsec->flags = SEC_HAS_CONTENTS;        bfdsec->flags = SEC_HAS_CONTENTS /*| SEC_THREAD_LOCAL*/;
1531    
1532        cmd->section = bfdsec;        cmd->section = bfdsec;
1533      }      }
# Line 1260  bfd_mach_o_scan_read_symtab (abfd, comma Line 1617  bfd_mach_o_scan_read_symtab (abfd, comma
1617    seg->nsyms = bfd_h_get_32 (abfd, buf + 4);    seg->nsyms = bfd_h_get_32 (abfd, buf + 4);
1618    seg->stroff = bfd_h_get_32 (abfd, buf + 8);    seg->stroff = bfd_h_get_32 (abfd, buf + 8);
1619    seg->strsize = bfd_h_get_32 (abfd, buf + 12);    seg->strsize = bfd_h_get_32 (abfd, buf + 12);
1620    seg->symbols = NULL;    /*seg->symbols = NULL;*/
1621      seg->nlists = NULL;
1622    seg->strtab = NULL;    seg->strtab = NULL;
1623    
1624    sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);    sname = (char *) bfd_zalloc (abfd, strlen (prefix) + 1);
1625    if (sname == NULL)    if (sname == NULL)
1626      return -1;      return -1;
1627    strcpy (sname, prefix);    strcpy (sname, prefix);
# Line 1275  bfd_mach_o_scan_read_symtab (abfd, comma Line 1633  bfd_mach_o_scan_read_symtab (abfd, comma
1633    bfdsec->vma = 0;    bfdsec->vma = 0;
1634    bfdsec->lma = 0;    bfdsec->lma = 0;
1635    bfdsec->size = seg->nsyms * 12;    bfdsec->size = seg->nsyms * 12;
1636      /*bfdsec->_raw_size = seg->nsyms * 12;*/
1637    bfdsec->filepos = seg->symoff;    bfdsec->filepos = seg->symoff;
1638    bfdsec->alignment_power = 0;    bfdsec->alignment_power = 0;
1639    bfdsec->flags = SEC_HAS_CONTENTS;    bfdsec->flags = SEC_HAS_CONTENTS;
1640      bfdsec->reloc_count = 0;
1641      
1642    seg->stabs_segment = bfdsec;    seg->stabs_segment = bfdsec;
1643    
1644    prefix = "LC_SYMTAB.stabstr";    prefix = "LC_SYMTAB.stabstr";
1645    sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);    sname = (char *) bfd_zalloc (abfd, strlen (prefix) + 1);
1646    if (sname == NULL)    if (sname == NULL)
1647      return -1;      return -1;
1648    strcpy (sname, prefix);    strcpy (sname, prefix);
# Line 1294  bfd_mach_o_scan_read_symtab (abfd, comma Line 1654  bfd_mach_o_scan_read_symtab (abfd, comma
1654    bfdsec->vma = 0;    bfdsec->vma = 0;
1655    bfdsec->lma = 0;    bfdsec->lma = 0;
1656    bfdsec->size = seg->strsize;    bfdsec->size = seg->strsize;
1657      /*bfdsec->_raw_size = seg->strsize;*/
1658    bfdsec->filepos = seg->stroff;    bfdsec->filepos = seg->stroff;
1659    bfdsec->alignment_power = 0;    bfdsec->alignment_power = 0;
1660    bfdsec->flags = SEC_HAS_CONTENTS;    bfdsec->flags = SEC_HAS_CONTENTS;
1661      bfdsec->reloc_count = 0;
1662    
1663    seg->stabstr_segment = bfdsec;    seg->stabstr_segment = bfdsec;
1664    
# Line 1333  bfd_mach_o_scan_read_segment (abfd, comm Line 1695  bfd_mach_o_scan_read_segment (abfd, comm
1695    seg->flags = bfd_h_get_32 (abfd, buf + 44);    seg->flags = bfd_h_get_32 (abfd, buf + 44);
1696    
1697    snamelen = strlen (prefix) + 1 + strlen (seg->segname) + 1;    snamelen = strlen (prefix) + 1 + strlen (seg->segname) + 1;
1698    sname = (char *) bfd_alloc (abfd, snamelen);    sname = (char *) bfd_zalloc (abfd, snamelen);
1699    if (sname == NULL)    if (sname == NULL)
1700      return -1;      return -1;
1701    sprintf (sname, "%s.%s", prefix, seg->segname);    sprintf (sname, "%s.%s", prefix, seg->segname);
# Line 1342  bfd_mach_o_scan_read_segment (abfd, comm Line 1704  bfd_mach_o_scan_read_segment (abfd, comm
1704    if (bfdsec == NULL)    if (bfdsec == NULL)
1705      return -1;      return -1;
1706    
1707    #if 0
1708      bfdsec = bfd_make_section_anyway (abfd, sname);
1709      if (bfdsec == NULL)
1710        return -1;
1711    
1712    bfdsec->vma = seg->vmaddr;    bfdsec->vma = seg->vmaddr;
1713    bfdsec->lma = seg->vmaddr;    bfdsec->lma = seg->vmaddr;
1714    bfdsec->size = seg->filesize;    bfdsec->_raw_size = seg->filesize;
1715    bfdsec->filepos = seg->fileoff;    bfdsec->filepos = seg->fileoff;
1716    bfdsec->alignment_power = 0x0;    bfdsec->alignment_power = 0x0;
1717    bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;    bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
1718    #else
1719      bfdsec = NULL;
1720    #endif
1721    
1722    seg->segment = bfdsec;    seg->segment = bfdsec;
1723    
# Line 1355  bfd_mach_o_scan_read_segment (abfd, comm Line 1725  bfd_mach_o_scan_read_segment (abfd, comm
1725      {      {
1726        seg->sections =        seg->sections =
1727          ((bfd_mach_o_section *)          ((bfd_mach_o_section *)
1728           bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section)));           bfd_zalloc (abfd, seg->nsects * sizeof (bfd_mach_o_section)));
1729        if (seg->sections == NULL)        if (seg->sections == NULL)
1730          return -1;          return -1;
1731    
# Line 1529  bfd_mach_o_flatten_sections (abfd) Line 1899  bfd_mach_o_flatten_sections (abfd)
1899          }          }
1900      }      }
1901    
1902    mdata->sections = bfd_alloc (abfd,    mdata->sections = bfd_zalloc (abfd,
1903                                 mdata->nsects * sizeof (bfd_mach_o_section *));                                 mdata->nsects * sizeof (bfd_mach_o_section *));
1904    csect = 0;    csect = 0;
1905    
# Line 1635  bfd_mach_o_scan (abfd, header, mdata) Line 2005  bfd_mach_o_scan (abfd, header, mdata)
2005      {      {
2006        mdata->commands =        mdata->commands =
2007          ((bfd_mach_o_load_command *)          ((bfd_mach_o_load_command *)
2008           bfd_alloc (abfd, header->ncmds * sizeof (bfd_mach_o_load_command)));           bfd_zalloc (abfd, header->ncmds * sizeof (bfd_mach_o_load_command)));
2009        if (mdata->commands == NULL)        if (mdata->commands == NULL)
2010          return -1;          return -1;
2011    
# Line 1657  bfd_mach_o_scan (abfd, header, mdata) Line 2027  bfd_mach_o_scan (abfd, header, mdata)
2027      }      }
2028    
2029    if (bfd_mach_o_scan_start_address (abfd) < 0)    if (bfd_mach_o_scan_start_address (abfd) < 0)
2030      return -1;      {
2031    #if 0
2032          fprintf (stderr, "bfd_mach_o_scan: unable to scan start address: %s\n",
2033                   bfd_errmsg (bfd_get_error ()));
2034          abfd->tdata.mach_o_data = NULL;
2035          return -1;
2036    #endif
2037        }
2038    
2039    bfd_mach_o_flatten_sections (abfd);    bfd_mach_o_flatten_sections (abfd);
2040    return 0;    return 0;
# Line 1670  bfd_mach_o_mkobject (abfd) Line 2047  bfd_mach_o_mkobject (abfd)
2047    bfd_mach_o_data_struct *mdata = NULL;    bfd_mach_o_data_struct *mdata = NULL;
2048    
2049    mdata = ((bfd_mach_o_data_struct *)    mdata = ((bfd_mach_o_data_struct *)
2050             bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct)));             bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct)));
2051    if (mdata == NULL)    if (mdata == NULL)
2052      return FALSE;      return FALSE;
2053    abfd->tdata.mach_o_data = mdata;    abfd->tdata.mach_o_data = mdata;
# Line 1688  bfd_mach_o_mkobject (abfd) Line 2065  bfd_mach_o_mkobject (abfd)
2065    mdata->symbols = NULL;    mdata->symbols = NULL;
2066    mdata->nsects = 0;    mdata->nsects = 0;
2067    mdata->sections = NULL;    mdata->sections = NULL;
2068      mdata->ist = NULL;
2069    mdata->ibfd = NULL;    mdata->ibfd = NULL;
2070    
2071    return TRUE;    return TRUE;
# Line 1822  bfd_mach_o_archive_p (abfd) Line 2200  bfd_mach_o_archive_p (abfd)
2200      goto error;      goto error;
2201    
2202    adata = (mach_o_fat_data_struct *)    adata = (mach_o_fat_data_struct *)
2203      bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));      bfd_zalloc (abfd, sizeof (mach_o_fat_data_struct));
2204    if (adata == NULL)    if (adata == NULL)
2205      goto error;      goto error;
2206    
# Line 1832  bfd_mach_o_archive_p (abfd) Line 2210  bfd_mach_o_archive_p (abfd)
2210      goto error;      goto error;
2211    
2212    adata->archentries = (mach_o_fat_archentry *)    adata->archentries = (mach_o_fat_archentry *)
2213      bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));      bfd_zalloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
2214    if (adata->archentries == NULL)    if (adata->archentries == NULL)
2215      goto error;      goto error;
2216    
# Line 2138  bfd_mach_o_core_file_matches_executable_ Line 2516  bfd_mach_o_core_file_matches_executable_
2516    return TRUE;    return TRUE;
2517  }  }
2518    
2519    static int
2520    bfd_mach_o_compar_st_idx (const void *a, const void *b)
2521    {
2522        unsigned long  x = ((bfd_mach_o_ist_entry *) a)->st_idx;
2523        unsigned long  y = ((bfd_mach_o_ist_entry *) b)->st_idx;
2524    
2525        return (int) x - (int) y;
2526    }
2527    
2528    static void
2529    bfd_mach_o_dump_ist_aux (abfd, sym, sect_array, array_length, tot)
2530         bfd *abfd;
2531         bfd_mach_o_symtab_command *sym;
2532         bfd_mach_o_section **sect_array;
2533         unsigned long array_length;
2534         unsigned long tot;
2535    {
2536      bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
2537      bfd_mach_o_ist *ist = mdata->ist;
2538      unsigned long i;
2539      
2540      BFD_ASSERT (sym->symoff != 0);
2541      BFD_ASSERT (sym->strtab != NULL);
2542      
2543      for (i=0 ; i < array_length ; sect_array++, i++)
2544        {
2545          bfd_mach_o_ist_entry *e;
2546          unsigned long start;
2547          unsigned long nmemb;
2548          unsigned long j;
2549          unsigned long atomic_size;
2550          
2551          if ((*sect_array)->reserved2)
2552            atomic_size = ((*sect_array)->reserved2);
2553          else
2554            atomic_size = 4;
2555          
2556          start = (*sect_array)->reserved1;
2557          nmemb = (*sect_array)->size / atomic_size;
2558    
2559          if (nmemb + start > ist->nmemb || start >= ist->nmemb) {
2560            printf ("%s: contains garbage\n\n", (*sect_array)->sectname);
2561            continue;
2562          }
2563    
2564          printf ("%s (contains %ld out of %ld indirect symbols)\n",
2565                  (*sect_array)->sectname, nmemb, tot);
2566    
2567          e = ist->raw_ist + start;
2568          
2569          for (j=0 ; j < nmemb ; e++, j++)
2570            {
2571              file_ptr symdelta, strdelta;
2572              char buf [12];
2573              
2574              symdelta = (e->st_idx) * 12;
2575              
2576              if (bfd_seek (abfd, sym->symoff + symdelta, SEEK_SET) != 0 ||
2577                  bfd_bread ((PTR) buf, 12, abfd) != 12)
2578                continue;
2579              
2580              strdelta = bfd_h_get_32 (abfd, buf);
2581              
2582              printf ("  %5ld - %5ld %s\n",
2583                      e->ist_idx, e->st_idx, sym->strtab + strdelta);
2584            }
2585    
2586          printf ("\n");
2587          fflush (stdout);
2588        }
2589    }
2590    
2591    static void
2592    bfd_mach_o_dump_ist (abfd, sym)
2593         bfd *abfd;
2594         bfd_mach_o_symtab_command *sym;
2595    {
2596      bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
2597      bfd_mach_o_ist *ist = mdata->ist;
2598      
2599      if (ist != NULL)
2600        {
2601          printf ("\nDumping indirect symbol table for file %s:\n\n",
2602                  abfd->filename);
2603    
2604          bfd_mach_o_dump_ist_aux (abfd, sym, ist->stubs,  ist->nstubs,  ist->nmemb);
2605      
2606          bfd_mach_o_dump_ist_aux (abfd, sym, ist->nlptrs, ist->nnlptrs, ist->nmemb);
2607    
2608          bfd_mach_o_dump_ist_aux (abfd, sym, ist->laptrs, ist->nlaptrs, ist->nmemb);
2609        }
2610    }
2611    
2612    static bfd_boolean
2613    bfd_mach_o_check_ist (ist)
2614         bfd_mach_o_ist *ist;
2615    {
2616      if (ist != NULL)
2617        {
2618          bfd_boolean retval = TRUE;
2619          
2620          if (ist->nmemb > 0)
2621            {    
2622              bfd_mach_o_section **stub_sections;
2623              bfd_boolean *marks;
2624              unsigned long i;
2625              
2626              stub_sections = ist->stubs;
2627    
2628              marks = (bfd_boolean *) bfd_malloc (ist->nmemb * sizeof (bfd_boolean));
2629              if (marks == NULL)
2630                return FALSE;
2631              
2632              memset (marks, 0, ist->nmemb * sizeof (bfd_boolean));
2633              
2634              for (i=0 ; i < ist->nstubs ; stub_sections++, i++)
2635                {
2636                  unsigned long j, start,  nmemb;
2637                  bfd_mach_o_ist_entry *e;
2638            
2639                  if ((*stub_sections)->reserved2 == 0)
2640                    {
2641                      fprintf (stderr, "check_ist: invalid stub size in section "
2642                               "%s\n", (*stub_sections)->sectname);
2643                      retval = FALSE;
2644                      break;
2645                    }
2646                  
2647                  start = (*stub_sections)->reserved1;
2648                  nmemb = (*stub_sections)->size / (*stub_sections)->reserved2;
2649                  
2650                  if (nmemb + start > ist->nmemb || start >= ist->nmemb)
2651                    {
2652                      fprintf (stderr, "check_ist: malformed indirect section %s\n",
2653                               (*stub_sections)->sectname);
2654                      retval = FALSE;
2655                      break;
2656                    }
2657    
2658                  e = ist->raw_ist + start;
2659                  
2660                  for (j=0 ; j < nmemb ; j++, e++)
2661                    {
2662                      bfd_boolean already_there = marks[e->ist_idx];
2663                      
2664                      if (!already_there) {
2665                        marks[e->ist_idx] = TRUE;
2666                      } else {
2667                        fprintf (stderr, "check_ist: multiple stubs for "
2668                                 "indirect symbol %ld/%ld\n",
2669                                 e->ist_idx, e->st_idx );
2670                     /* retval = false;  This is legal, actually.  */
2671                      }
2672                    }
2673                }
2674              
2675              free (marks);
2676              
2677              fflush (stderr);
2678            }
2679    
2680          return retval;
2681        }
2682    
2683      return FALSE;
2684    }
2685    
2686    static bfd_mach_o_ist *
2687    bfd_mach_o_slurp_ist (abfd)
2688         bfd *abfd;
2689    {
2690      bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
2691      bfd_mach_o_dysymtab_command *dyst = NULL;
2692      bfd_mach_o_ist *ist = NULL;
2693      unsigned long nnlptrs = 0;
2694      unsigned long nlaptrs = 0;
2695      unsigned long nstubs = 0;
2696      unsigned long i;
2697        
2698      if (mdata->ist != NULL) {
2699        /* Nothing to do.  */
2700        return (mdata->ist);
2701      }
2702        
2703      for (i=0 ; i < mdata->header.ncmds ; i++) {
2704        if (mdata->commands[i].type == BFD_MACH_O_LC_DYSYMTAB)
2705          {
2706            if (dyst != NULL) {
2707              fprintf (stderr, "bfd_mach_o_slurp_ist: "
2708                       "input file contains more than one LC_DYSYMTAB load cmd\n");
2709              abort ();
2710            }
2711            dyst = &mdata->commands[i].command.dysymtab;
2712          }
2713      }
2714      
2715      ist = (bfd_mach_o_ist *) bfd_zalloc (abfd, sizeof (bfd_mach_o_ist));
2716      if (ist == NULL)
2717        return (NULL);
2718        
2719      /* Make sure we did find a LC_DYSYMTAB load command.  */
2720    
2721      if (dyst != NULL)
2722        {
2723          bfd_size_type ist_size;
2724            
2725          ist->command = dyst;
2726          ist->nmemb = dyst->nindirectsyms;
2727            
2728          if (ist->nmemb == 0) {
2729         /* Empty indirect symbol table.  */
2730            return (mdata->ist = ist);
2731          }
2732          
2733          ist_size = ist->nmemb * sizeof (bfd_mach_o_ist_entry);
2734    
2735          ist->raw_ist = (bfd_mach_o_ist_entry *) bfd_alloc (abfd, ist_size);
2736          ist->sorted_ist = (bfd_mach_o_ist_entry *) bfd_alloc (abfd, ist_size);
2737    
2738          if (ist->raw_ist == NULL || ist->sorted_ist == NULL)
2739            return (NULL);
2740          
2741          if ((bfd_seek (abfd, dyst->indirectsymoff, SEEK_SET) != 0 ||
2742               bfd_bread (ist->raw_ist, ist_size, abfd) != ist_size))
2743            return (NULL);
2744            
2745          for (i=ist->nmemb ; --i != (unsigned long) -1 ; )
2746            {
2747              (ist->raw_ist)[i].st_idx = ((unsigned long *) ist->raw_ist)[i];
2748              (ist->raw_ist)[i].ist_idx = i;
2749    
2750              (ist->sorted_ist)[i].ist_idx = i;
2751              (ist->sorted_ist)[i].st_idx = (ist->raw_ist)[i].st_idx;
2752            }
2753            
2754          /* Loop through all sections, looking for ist related sections.  */
2755    
2756          for (i=0 ; i < mdata->nsects ; i++)
2757            {
2758              bfd_mach_o_section *sectp = mdata->sections[i];
2759              bfd_size_type array_size;
2760              unsigned long start;
2761              unsigned long nmemb;
2762                
2763              if ((sectp->flags & SECTION_TYPE)
2764                  == BFD_MACH_O_S_SYMBOL_STUBS)
2765                {
2766                  array_size = (++nstubs) * sizeof (bfd_mach_o_section *);
2767                    
2768                  ist->stubs =
2769                    (bfd_mach_o_section **) bfd_realloc (ist->stubs, array_size);
2770    
2771                  if (ist->stubs == NULL)
2772                    return NULL;
2773                    
2774                  ist->stubs[ist->nstubs++] = sectp;
2775                }
2776              else if ((sectp->flags & SECTION_TYPE)
2777                       == BFD_MACH_O_S_NL_SYMBOL_POINTERS)
2778                {
2779                  array_size = (++nnlptrs) * sizeof (bfd_mach_o_section *);
2780                    
2781                  ist->nlptrs =
2782                    (bfd_mach_o_section **) bfd_realloc (ist->nlptrs, array_size);
2783    
2784                  if (ist->nlptrs == NULL)
2785                    return (NULL);
2786                    
2787                  ist->nlptrs[ist->nnlptrs++] = sectp;
2788                }
2789              else if ((sectp->flags & SECTION_TYPE)
2790                       == BFD_MACH_O_S_LA_SYMBOL_POINTERS)
2791                {
2792                  array_size = (++nlaptrs) * sizeof (bfd_mach_o_section *);
2793    
2794                  ist->laptrs =
2795                    (bfd_mach_o_section **) bfd_realloc (ist->laptrs, array_size);
2796    
2797                  if (ist->laptrs == NULL)
2798                    return (NULL);
2799    
2800                  ist->laptrs[ist->nlaptrs++] = sectp;
2801                }
2802              else
2803                {
2804                  continue;
2805                }
2806    
2807              start = sectp->reserved1;
2808              nmemb = sectp->size / (sectp->reserved2 != 0 ? sectp->reserved2 : 4);
2809    
2810              qsort (ist->sorted_ist + start, nmemb,
2811                     sizeof (bfd_mach_o_ist_entry), bfd_mach_o_compar_st_idx);
2812            }
2813    
2814           BFD_ASSERT (bfd_mach_o_check_ist (ist));
2815        }
2816        
2817      return (mdata->ist = ist);
2818    }
2819    
2820    static bfd_vma
2821    bfd_mach_o_get_lazy_symbol_stub (ist, sym_idx, asect_ptr)
2822      bfd_mach_o_ist *ist;
2823      unsigned long sym_idx;
2824      asection **asect_ptr;
2825    {
2826      bfd_vma addr = 0;
2827        
2828      if (ist != NULL)
2829        {
2830          bfd_mach_o_section **stub_sections;
2831          unsigned long i;
2832          
2833          stub_sections = ist->stubs;
2834          
2835          for (i=0 ; i < ist->nstubs ; stub_sections++, i++)
2836            {
2837              unsigned long start, stub_size, nmemb;
2838              bfd_mach_o_ist_entry *match, key;
2839                
2840              start = (*stub_sections)->reserved1;
2841              stub_size = (*stub_sections)->reserved2;
2842              nmemb = (*stub_sections)->size / stub_size;
2843              
2844              key.st_idx = sym_idx;
2845                
2846              match = (bfd_mach_o_ist_entry *)
2847                bsearch (&key, ist->sorted_ist + start, nmemb,
2848                         sizeof (bfd_mach_o_ist_entry), bfd_mach_o_compar_st_idx);
2849                
2850              if (match != NULL) {
2851                if ((start <= match->ist_idx) && (match->ist_idx < (start + nmemb)))
2852                  {
2853                    if (asect_ptr != NULL)
2854                      *asect_ptr = (*stub_sections)->bfdsection;
2855                  
2856                    /* Obey the general contract about symbol addresses,
2857                       i.e. return a section relative address.  */
2858                    return (addr = ((match->ist_idx - start) * stub_size));
2859                  }
2860              }
2861            }
2862        }
2863        
2864      return (addr);
2865    }
2866    
2867    static bfd_vma
2868    bfd_mach_o_get_non_lazy_symbol_ptr (ist, sym_idx, asect_ptr)
2869      bfd_mach_o_ist *ist;
2870      unsigned long sym_idx;
2871      asection **asect_ptr;
2872    {
2873      bfd_vma addr = 0;
2874      
2875      if (ist != NULL)
2876        {
2877          bfd_mach_o_section **nlptr_sections;
2878          unsigned long i;
2879          
2880          nlptr_sections = ist->nlptrs;
2881          
2882          for (i=0 ; i < ist->nnlptrs ; nlptr_sections++, i++)
2883            {
2884              unsigned long start, nmemb;
2885              bfd_mach_o_ist_entry *match, key;
2886                
2887              start = (*nlptr_sections)->reserved1;
2888              nmemb = (*nlptr_sections)->size / 4;
2889              
2890              key.st_idx = sym_idx;
2891                
2892              match = (bfd_mach_o_ist_entry *)
2893                bsearch (&key, ist->sorted_ist + start, nmemb,
2894                         sizeof (bfd_mach_o_ist_entry), bfd_mach_o_compar_st_idx);
2895                
2896              if (match != NULL) {
2897                if ((start <= match->ist_idx) && (match->ist_idx < (start + nmemb)))
2898                  {
2899                    if (asect_ptr != NULL)
2900                      *asect_ptr = (*nlptr_sections)->bfdsection;
2901                  
2902                    /* Obey the general contract about symbol addresses,
2903                       i.e. return a section relative address.  */
2904                    return (addr = ((match->ist_idx - start) * 4));
2905                  }
2906              }
2907            }
2908        }
2909        
2910      return (addr);
2911    }
2912    
2913    static bfd_boolean
2914    bfd_mach_o_bfd_link_add_symbols (abfd,info)
2915         bfd *abfd;
2916         struct bfd_link_info *info;
2917    {
2918      bfd_mach_o_data_struct *mdata;
2919      unsigned long i;
2920        
2921      BFD_ASSERT (bfd_mach_o_valid (abfd));
2922      mdata = abfd->tdata.mach_o_data;
2923        
2924      for (i = 0; i < mdata->header.ncmds; i++)
2925        {
2926          if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
2927            {
2928              bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
2929              unsigned long j;
2930                
2931              if (bfd_mach_o_scan_read_symtab_strtab (abfd, sym) < 0) {
2932                fprintf (stderr, "bfd_mach_o_link_add_symbols: "
2933                         "error reading strtab\n");
2934                return FALSE;
2935              }
2936                
2937              BFD_ASSERT (sym->strtab != NULL);
2938                
2939              for (j=0 ; j < sym->nsyms ; j++)
2940                {
2941                  bfd_vma symoff = sym->symoff + (j * 12);
2942                    
2943                  unsigned char buf[12];
2944                  unsigned char type;
2945                  unsigned char sect;
2946                  short desc;
2947                  bfd_vma value;
2948                  unsigned long stroff;
2949                    
2950                  bfd_boolean copy = TRUE; /* (info->keep_memory) ? false : TRUE; */
2951                  const char *name;
2952                  flagword flags;
2953                  asection *section;
2954                    
2955                  bfd_seek (abfd, symoff, SEEK_SET);
2956                  if (bfd_bread ((PTR) buf, 12, abfd) != 12) {
2957                    return FALSE;
2958                  }
2959                    
2960                  type = bfd_h_get_8 (abfd, buf + 4);
2961                    
2962                  if (type & BFD_MACH_O_N_STAB)
2963                    continue;
2964    
2965                  stroff = bfd_h_get_32 (abfd, buf);
2966                  sect = bfd_h_get_8 (abfd, buf + 5);
2967                  desc = bfd_h_get_16 (abfd, buf + 6);
2968                  value = bfd_h_get_32 (abfd, buf + 8);
2969    
2970                  if (stroff >= sym->strsize) {
2971                    bfd_set_error (bfd_error_file_truncated);
2972                    return FALSE;
2973                  }
2974                    
2975                  name = sym->strtab + stroff;
2976                  flags = BSF_GLOBAL;
2977                    
2978                  if (type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT))
2979                    {
2980                      struct bfd_link_hash_entry *hashp = NULL;
2981                        
2982                      /* In the case of an N_INDR symbol, `string' is
2983                         the name of the symbol that is referred to.  */
2984                      const char *string = NULL;
2985                        
2986                      switch (type & BFD_MACH_O_N_TYPE) {
2987                      case BFD_MACH_O_N_UNDF:
2988                        if (value == 0) {
2989                          section = bfd_und_section_ptr;
2990                          /* flags = 0; */
2991                        }
2992                        else
2993                          section = bfd_com_section_ptr;
2994                        break;
2995                      case BFD_MACH_O_N_PBUD:
2996                        section = bfd_und_section_ptr;
2997                        break;
2998                      case BFD_MACH_O_N_ABS:
2999                        section = bfd_abs_section_ptr;
3000                        break;
3001                      case BFD_MACH_O_N_INDR:
3002                        flags |= BSF_INDIRECT;
3003                        section = bfd_ind_section_ptr;
3004                        fprintf (stderr,
3005                                 "BFD_MACH_O_N_INDR symbols not yet supported\n");
3006                        abort ();
3007                        break;
3008                      case BFD_MACH_O_N_SECT:
3009                        /* section numbering starts at 1, zero means no section */
3010                        if (sect > 0 && sect <= mdata->nsects) {
3011                          section = mdata->sections[sect-1]->bfdsection;
3012                          value -= mdata->sections[sect-1]->addr;
3013                        } else {
3014                          if (sect != 0) {
3015                            fprintf (stderr,
3016                                     "bfd_mach_o_link_add_symbols: symbol \"%s\" "
3017                                     "specified invalid section %d (max %lu), "
3018                                     "setting to undefined\n",
3019                                     name, sect, mdata->nsects);
3020                          }
3021                          section = bfd_und_section_ptr;
3022                          fprintf (stderr, "sect: %d %s\n", sect, name);
3023                        }
3024                        break;
3025                      default:
3026                        fprintf (stderr, "unknown N_TYPE value");
3027                        abort();
3028                        break;
3029                      }
3030                      
3031                      if ((flags & BSF_GLOBAL) == 0)
3032                        flags |= BSF_LOCAL;
3033                      
3034                      /* FIX-ME: Set the alignment for common symbols here.  */
3035                        
3036                      if (!_bfd_generic_link_add_one_symbol (info, abfd, name, flags,
3037                                                             section, value, string,
3038                                                             copy, FALSE, &hashp)) {
3039                        return FALSE;
3040                      }
3041                    }
3042                }
3043            }
3044        }
3045        
3046      return TRUE;
3047    }
3048    
3049    
3050  #include "mach-o-reloc.c"  #include "mach-o-reloc.c"
3051    
3052  #define TARGET_NAME mach_o_be_vec  #define TARGET_NAME mach_o_be_vec

Legend:
Removed from v.1.3.2.1.14.2  
changed lines
  Added in v.1.3.2.1.14.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26