/[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 by rlbrk, Mon Feb 23 07:00:50 2004 UTC revision 1.4 by camm, Fri Sep 9 23:32:14 2005 UTC
# Line 1  Line 1 
1  /* Mach-O support for BFD.  /* Mach-O support for BFD.
2     Copyright 1999, 2000, 2001, 2002     Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005
3     Free Software Foundation, Inc.     Free Software Foundation, Inc.
4    
5     This file is part of BFD, the Binary File Descriptor library.     This file is part of BFD, the Binary File Descriptor library.
# Line 20  Line 20 
20    
21  #include "mach-o.h"  #include "mach-o.h"
22  #include "bfd.h"  #include "bfd.h"
 #include "bfdlink.h"  
23  #include "sysdep.h"  #include "sysdep.h"
24  #include "libbfd.h"  #include "libbfd.h"
25  #include "libiberty.h"  #include "libiberty.h"
# Line 45  Line 44 
44  #define bfd_mach_o_new_section_hook _bfd_generic_new_section_hook  #define bfd_mach_o_new_section_hook _bfd_generic_new_section_hook
45  #define bfd_mach_o_get_section_contents_in_window _bfd_generic_get_section_contents_in_window  #define bfd_mach_o_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
46  #define bfd_mach_o_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name  #define bfd_mach_o_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
47    #define bfd_mach_o_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
48    #define bfd_mach_o_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
49  #define bfd_mach_o_get_lineno _bfd_nosymbols_get_lineno  #define bfd_mach_o_get_lineno _bfd_nosymbols_get_lineno
50  #define bfd_mach_o_find_nearest_line _bfd_nosymbols_find_nearest_line  #define bfd_mach_o_find_nearest_line _bfd_nosymbols_find_nearest_line
51  #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
52  #define bfd_mach_o_read_minisymbols _bfd_generic_read_minisymbols  #define bfd_mach_o_read_minisymbols _bfd_generic_read_minisymbols
53  #define bfd_mach_o_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol  #define bfd_mach_o_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
54  /*#define bfd_mach_o_get_reloc_upper_bound _bfd_norelocs_get_reloc_upper_bound*/  #define bfd_mach_o_get_reloc_upper_bound _bfd_norelocs_get_reloc_upper_bound
55  /*#define bfd_mach_o_canonicalize_reloc _bfd_norelocs_canonicalize_reloc*/  #define bfd_mach_o_canonicalize_reloc _bfd_norelocs_canonicalize_reloc
56  /*#define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup*/  #define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
57  /*#define bfd_mach_o_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents*/  #define bfd_mach_o_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
58  #define bfd_mach_o_bfd_relax_section bfd_generic_relax_section  #define bfd_mach_o_bfd_relax_section bfd_generic_relax_section
59  #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
60  #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
61  /*#define bfd_mach_o_bfd_link_add_symbols _bfd_generic_link_add_symbols*/  #define bfd_mach_o_bfd_link_add_symbols _bfd_generic_link_add_symbols
62  #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
63  #define bfd_mach_o_bfd_final_link _bfd_generic_final_link  #define bfd_mach_o_bfd_final_link _bfd_generic_final_link
64  #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 69  Line 70 
70  #define bfd_mach_o_set_section_contents _bfd_generic_set_section_contents  #define bfd_mach_o_set_section_contents _bfd_generic_set_section_contents
71  #define bfd_mach_o_bfd_gc_sections bfd_generic_gc_sections  #define bfd_mach_o_bfd_gc_sections bfd_generic_gc_sections
72  #define bfd_mach_o_bfd_merge_sections bfd_generic_merge_sections  #define bfd_mach_o_bfd_merge_sections bfd_generic_merge_sections
73    #define bfd_mach_o_bfd_is_group_section bfd_generic_is_group_section
74  #define bfd_mach_o_bfd_discard_group bfd_generic_discard_group  #define bfd_mach_o_bfd_discard_group bfd_generic_discard_group
75    #define bfd_mach_o_section_already_linked \
76      _bfd_generic_section_already_linked
77    #define bfd_mach_o_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
78    
79  static boolean bfd_mach_o_bfd_copy_private_symbol_data  static bfd_boolean bfd_mach_o_bfd_copy_private_symbol_data
80    PARAMS ((bfd *, asymbol *, bfd *, asymbol *));    PARAMS ((bfd *, asymbol *, bfd *, asymbol *));
81  static boolean bfd_mach_o_bfd_copy_private_section_data  static bfd_boolean bfd_mach_o_bfd_copy_private_section_data
82    PARAMS ((bfd *, asection *, bfd *, asection *));    PARAMS ((bfd *, asection *, bfd *, asection *));
83  static boolean bfd_mach_o_bfd_copy_private_bfd_data  static bfd_boolean bfd_mach_o_bfd_copy_private_bfd_data
84    PARAMS ((bfd *, bfd *));    PARAMS ((bfd *, bfd *));
85  static long bfd_mach_o_count_symbols  static long bfd_mach_o_count_symbols
86    PARAMS ((bfd *));    PARAMS ((bfd *));
87  static long bfd_mach_o_get_symtab_upper_bound  static long bfd_mach_o_get_symtab_upper_bound
88    PARAMS ((bfd *));    PARAMS ((bfd *));
89  static long bfd_mach_o_get_symtab  static long bfd_mach_o_canonicalize_symtab
90    PARAMS ((bfd *, asymbol **));    PARAMS ((bfd *, asymbol **));
91  static void bfd_mach_o_get_symbol_info  static void bfd_mach_o_get_symbol_info
92    PARAMS ((bfd *, asymbol *, symbol_info *));    PARAMS ((bfd *, asymbol *, symbol_info *));
# Line 90  static void bfd_mach_o_print_symbol Line 95  static void bfd_mach_o_print_symbol
95  static void bfd_mach_o_convert_architecture  static void bfd_mach_o_convert_architecture
96    PARAMS ((bfd_mach_o_cpu_type, bfd_mach_o_cpu_subtype,    PARAMS ((bfd_mach_o_cpu_type, bfd_mach_o_cpu_subtype,
97             enum bfd_architecture *, unsigned long *));             enum bfd_architecture *, unsigned long *));
98  static boolean bfd_mach_o_write_contents  static bfd_boolean bfd_mach_o_write_contents
99    PARAMS ((bfd *));    PARAMS ((bfd *));
100  static int bfd_mach_o_sizeof_headers  static int bfd_mach_o_sizeof_headers
101    PARAMS ((bfd *, boolean));    PARAMS ((bfd *, bfd_boolean));
102  static asymbol * bfd_mach_o_make_empty_symbol  static asymbol * bfd_mach_o_make_empty_symbol
103    PARAMS ((bfd *));    PARAMS ((bfd *));
104  static int bfd_mach_o_write_header  static int bfd_mach_o_write_header
# Line 137  static const char * bfd_mach_o_i386_flav Line 142  static const char * bfd_mach_o_i386_flav
142  static const char * bfd_mach_o_ppc_flavour_string  static const char * bfd_mach_o_ppc_flavour_string
143    PARAMS ((unsigned int));    PARAMS ((unsigned int));
144    
 static int bfd_mach_o_compar_st_idx  
   PARAMS ((const void *, const void *));  
 static void bfd_mach_o_dump_ist_aux  
   PARAMS ((bfd *, bfd_mach_o_symtab_command *, bfd_mach_o_section **, unsigned long, unsigned long));  
 static void bfd_mach_o_dump_ist  
   PARAMS ((bfd *, bfd_mach_o_symtab_command *));  
 static boolean bfd_mach_o_check_ist  
   PARAMS ((bfd_mach_o_ist *));  
 static bfd_mach_o_ist * bfd_mach_o_slurp_ist  
   PARAMS ((bfd *));  
 static bfd_vma bfd_mach_o_get_lazy_symbol_stub  
   PARAMS ((bfd_mach_o_ist *, unsigned long, asection **));  
 static bfd_vma bfd_mach_o_get_non_lazy_symbol_ptr  
   PARAMS ((bfd_mach_o_ist *, unsigned long, asection **));  
 static boolean bfd_mach_o_bfd_link_add_symbols  
   PARAMS ((bfd *, struct bfd_link_info *));  
   
145  /* 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
146     type and section attributes.  The section types are mutually exclusive (it     type and section attributes.  The section types are mutually exclusive (it
147     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 165  static boolean bfd_mach_o_bfd_link_add_s Line 153  static boolean bfd_mach_o_bfd_link_add_s
153  /* Constants for the section attributes part of the flags field of a section  /* Constants for the section attributes part of the flags field of a section
154     structure.  */     structure.  */
155    
156  /* User-settable attributes.  */  #define SECTION_ATTRIBUTES_USR   0xff000000     /* User-settable attributes.  */
157  #define SECTION_ATTRIBUTES_USR   0xff000000  #define S_ATTR_PURE_INSTRUCTIONS 0x80000000     /* Section contains only true machine instructions.  */
158    #define SECTION_ATTRIBUTES_SYS   0x00ffff00     /* System setable attributes.  */
159  /* Section contains only true machine instructions.  */  #define S_ATTR_SOME_INSTRUCTIONS 0x00000400     /* Section contains some machine instructions.  */
160  #define S_ATTR_PURE_INSTRUCTIONS 0x80000000  #define S_ATTR_EXT_RELOC         0x00000200     /* Section has external relocation entries.  */
161    #define S_ATTR_LOC_RELOC         0x00000100     /* Section has local relocation entries.  */
 /* System setable attributes.  */  
 #define SECTION_ATTRIBUTES_SYS   0x00ffff00  
   
 /* Section contains some machine instructions.  */  
 #define S_ATTR_SOME_INSTRUCTIONS 0x00000400  
   
 /* Section has external relocation entries.  */  
 #define S_ATTR_EXT_RELOC         0x00000200  
   
 /* Section has local relocation entries.  */  
 #define S_ATTR_LOC_RELOC         0x00000100  
162    
163  #define N_STAB 0xe0  #define N_STAB 0xe0
164  #define N_TYPE 0x1e  #define N_TYPE 0x1e
# Line 191  static boolean bfd_mach_o_bfd_link_add_s Line 168  static boolean bfd_mach_o_bfd_link_add_s
168  #define N_SECT 0xe  #define N_SECT 0xe
169  #define N_INDR 0xa  #define N_INDR 0xa
170    
171  boolean  bfd_boolean
172  bfd_mach_o_valid (abfd)  bfd_mach_o_valid (abfd)
173       bfd *abfd;       bfd *abfd;
174  {  {
# Line 211  bfd_mach_o_valid (abfd) Line 188  bfd_mach_o_valid (abfd)
188  /* Copy any private info we understand from the input symbol  /* Copy any private info we understand from the input symbol
189     to the output symbol.  */     to the output symbol.  */
190    
191  static boolean  static bfd_boolean
192  bfd_mach_o_bfd_copy_private_symbol_data (ibfd, isymbol, obfd, osymbol)  bfd_mach_o_bfd_copy_private_symbol_data (ibfd, isymbol, obfd, osymbol)
193       bfd *ibfd ATTRIBUTE_UNUSED;       bfd *ibfd ATTRIBUTE_UNUSED;
194       asymbol *isymbol ATTRIBUTE_UNUSED;       asymbol *isymbol ATTRIBUTE_UNUSED;
195       bfd *obfd ATTRIBUTE_UNUSED;       bfd *obfd ATTRIBUTE_UNUSED;
196       asymbol *osymbol ATTRIBUTE_UNUSED;       asymbol *osymbol ATTRIBUTE_UNUSED;
197  {  {
198    return true;    return TRUE;
199  }  }
200    
201  /* Copy any private info we understand from the input section  /* Copy any private info we understand from the input section
202     to the output section.  */     to the output section.  */
203    
204  static boolean  static bfd_boolean
205  bfd_mach_o_bfd_copy_private_section_data (ibfd, isection, obfd, osection)  bfd_mach_o_bfd_copy_private_section_data (ibfd, isection, obfd, osection)
206       bfd *ibfd ATTRIBUTE_UNUSED;       bfd *ibfd ATTRIBUTE_UNUSED;
207       asection *isection ATTRIBUTE_UNUSED;       asection *isection ATTRIBUTE_UNUSED;
208       bfd *obfd ATTRIBUTE_UNUSED;       bfd *obfd ATTRIBUTE_UNUSED;
209       asection *osection ATTRIBUTE_UNUSED;       asection *osection ATTRIBUTE_UNUSED;
210  {  {
211    return true;    return TRUE;
212  }  }
213    
214  /* Copy any private info we understand from the input bfd  /* Copy any private info we understand from the input bfd
215     to the output bfd.  */     to the output bfd.  */
216    
217  static boolean  static bfd_boolean
218  bfd_mach_o_bfd_copy_private_bfd_data (ibfd, obfd)  bfd_mach_o_bfd_copy_private_bfd_data (ibfd, obfd)
219       bfd *ibfd;       bfd *ibfd;
220       bfd *obfd;       bfd *obfd;
# Line 247  bfd_mach_o_bfd_copy_private_bfd_data (ib Line 224  bfd_mach_o_bfd_copy_private_bfd_data (ib
224    
225    obfd->tdata.mach_o_data = ibfd->tdata.mach_o_data;    obfd->tdata.mach_o_data = ibfd->tdata.mach_o_data;
226    obfd->tdata.mach_o_data->ibfd = ibfd;    obfd->tdata.mach_o_data->ibfd = ibfd;
227    return true;    return TRUE;
228  }  }
229    
230  static long  static long
# Line 284  bfd_mach_o_get_symtab_upper_bound (abfd) Line 261  bfd_mach_o_get_symtab_upper_bound (abfd)
261  }  }
262    
263  static long  static long
264  bfd_mach_o_get_symtab (abfd, alocation)  bfd_mach_o_canonicalize_symtab (abfd, alocation)
265       bfd *abfd;       bfd *abfd;
266       asymbol **alocation;       asymbol **alocation;
267  {  {
# Line 302  bfd_mach_o_get_symtab (abfd, alocation) Line 279  bfd_mach_o_get_symtab (abfd, alocation)
279          {          {
280            bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;            bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
281    
282            if (bfd_mach_o_scan_read_symtab_symbols (abfd, sym) != 0)            if (bfd_mach_o_scan_read_symtab_symbols (abfd, &mdata->commands[i].command.symtab) != 0)
283              {              {
284                fprintf (stderr, "bfd_mach_o_get_symtab: "                fprintf (stderr, "bfd_mach_o_canonicalize_symtab: unable to load symbols for section %lu\n", i);
                        "unable to load symbols for section %lu\n", i);  
285                return 0;                return 0;
286              }              }
287    
288            BFD_ASSERT (sym->nlists != NULL);            BFD_ASSERT (sym->symbols != NULL);
289    
290            for (j = 0; j < sym->nsyms; j++)            for (j = 0; j < sym->nsyms; j++)
291              {              {
292                BFD_ASSERT (csym < (alocation + nsyms));                BFD_ASSERT (csym < (alocation + nsyms));
293                *csym++ = &(sym->nlists[j].root);                *csym++ = &sym->symbols[j];
294              }              }
295          }          }
296      }      }
297    
298    *csym++ = NULL;    *csym++ = NULL;
299      
   bfd_get_symcount (abfd) = nsyms;  
   mdata->nsymbols = nsyms;  
     
300    return nsyms;    return nsyms;
301  }  }
302    
# Line 371  bfd_mach_o_convert_architecture (mtype, Line 344  bfd_mach_o_convert_architecture (mtype,
344      case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;      case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
345      case BFD_MACH_O_CPU_TYPE_I386: *type = bfd_arch_i386; break;      case BFD_MACH_O_CPU_TYPE_I386: *type = bfd_arch_i386; break;
346      case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;      case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
347   /* I'm in a hurry : comment this out for now (Aurelien, 14-II-04). */      case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;
  /* case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break; */  
348      case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;      case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
349      case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;      case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
350      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 392  bfd_mach_o_convert_architecture (mtype, Line 364  bfd_mach_o_convert_architecture (mtype,
364      }      }
365  }  }
366    
367  /*  static bfd_boolean
 We don't need these for GCL (Aurelien, 14-II-04).  
   
 int  
 bfd_mach_o_compar_symbols (void *a, void *b)  
 {  
   static char *empty_symbol_name = "";  
   asymbol *s = (asymbol *) a;  
   asymbol *t = (asymbol *) b;  
     
   if (s->name == NULL)  
     s->name = empty_symbol_name;  
   if (t->name == NULL)  
     t->name = empty_symbol_name;  
     
   if (s->flags & BSF_DEBUGGING)  
     {  
       if (t->flags & BSF_DEBUGGING)  
         return strcmp (s->name, t->name);  
       else  
         return -1;  
     }  
   else if (s->flags & BSF_LOCAL)  
     {  
       if (t->flags & BSF_DEBUGGING)  
         return +1;  
       else if (t->flags & BSF_LOCAL)  
         return strcmp (s->name, t->name);  
       else  
         return -1;  
     }  
   else  
     {  
       asection *ssect = s->section;  
       asection *tsect = t->section;  
         
       if (!(bfd_is_und_section (ssect) || bfd_is_com_section (ssect)))  
         {  
           if (t->flags & BSF_LOCAL)  
             return +1;  
           else if (!(bfd_is_und_section (tsect) || bfd_is_com_section (tsect)))  
             return strcmp (s->name, t->name);  
           else  
             return -1;  
         }  
       else  
         {  
           if (t->flags & BSF_LOCAL)  
             return +1;  
           else if (!(bfd_is_und_section (tsect) || bfd_is_com_section (tsect)))  
             return +1;  
           else  
             return strcmp (s->name, t->name);  
         }  
     }  
 }  
   
 boolean  
 bfd_mach_o_sort_symtab (abfd, link_info)  
      bfd *abfd;  
      struct bfd_link_info *link_info;  
 {  
   bfd_mach_o_symtab_command *st = mach_o_symtab (abfd);  
   int i, symcount = bfd_get_symcount (abfd);  
   bfd_mach_o_nlist *nlists;  
   bfd_size_type strtab_size;  
   char *strtab;  
   asymbol *sym_ptr;  
   int num_loc_syms, num_ext_syms, num_und_syms;  
   bfd_mach_o_nlist *loc_sym_ptr, *ext_sym_ptr, *und_sym_ptr;  
     
   if (st == NULL)  
     {  
       st = (bfd_mach_o_symtab_command *)  
         bfd_zalloc (abfd, sizeof (bfd_mach_o_symtab_command));  
       mach_o_symtab (abfd) = st;  
     }  
   
   if (st == NULL)  
     return false;  
   
   if (symcount == 0)  
     return true;  
     
   nlists = st->nlists;  
     
   if (nlists == NULL)  
     {  
       nlists = (bfd_mach_o_nlist *)  
         bfd_zalloc (abfd, sizeof (bfd_mach_o_nlist) * symcount);  
       st->nlists = nlists;  
     }  
   
   if (nlists == NULL)  
     return false;  
     
   strtab_size = 0;  
   sym_ptr = mach_o_tdata (abfd)->symbols;  
     
   num_loc_syms = 0;  
   num_ext_syms = 0;  
   num_und_syms = 0;  
     
   for (i=0 ; i < symcount ; i++, sym_ptr++)  
     {  
       if (sym_ptr->name != NULL)  
         strtab_size += strlen (sym_ptr->name);  
         
       if (sym_ptr->flags & BSF_GLOBAL)  
         {  
           asection *asect = sym_ptr->section;  
             
           if (bfd_is_und_section (asect) || bfd_is_com_section (asect))  
             num_und_syms++;  
           else  
             num_ext_syms++;  
         }  
       else  
         num_loc_syms++;  
     }  
   
   strtab = (char *) bfd_zalloc (abfd, strtab_size);  
   
   if (strtab == NULL)  
     return false;  
     
   sym_ptr = mach_o_tdata (abfd)->symbols;  
     
   loc_sym_ptr = nlists;  
   ext_sym_ptr = loc_sym_ptr + num_loc_syms;  
   und_sym_ptr = ext_sym_ptr + num_ext_syms;  
     
   for (i=0 ; i < symcount ; i++, sym_ptr++)  
     {  
       if (sym_ptr->flags & BSF_GLOBAL)  
         {  
           if (bfd_is_und_section (sym_ptr->section) ||  
               bfd_is_com_section (sym_ptr->section))  
             (*und_sym_ptr++).root = *sym;  
           else  
             (*ext_sym_ptr++).root = *sym;  
         }  
       else  
         (*loc_sym_ptr++).root = *sym;  
     }  
       
 }  
 */  
   
 static boolean  
368  bfd_mach_o_write_contents (abfd)  bfd_mach_o_write_contents (abfd)
369       bfd *abfd;       bfd *abfd;
370  {  {
# Line 556  bfd_mach_o_write_contents (abfd) Line 379  bfd_mach_o_write_contents (abfd)
379    for (s = abfd->sections; s != (asection *) NULL; s = s->next)    for (s = abfd->sections; s != (asection *) NULL; s = s->next)
380      ;      ;
381    
 #if 0  
   for (i = 0; i < mdata->header.ncmds; i++)  
     {  
       bfd_mach_o_load_command *cur = &mdata->commands[i];  
       if (cur->type != BFD_MACH_O_LC_SEGMENT)  
         break;  
   
       {  
         bfd_mach_o_segment_command *seg = &cur->command.segment;  
         char buf[1024];  
         bfd_vma nbytes = seg->filesize;  
         bfd_vma curoff = seg->fileoff;  
   
         while (nbytes > 0)  
           {  
             bfd_vma thisread = nbytes;  
   
             if (thisread > 1024)  
               thisread = 1024;  
   
             bfd_seek (abfd, curoff, SEEK_SET);  
             if (bfd_bread ((PTR) buf, thisread, abfd) != thisread)  
               return false;  
   
             bfd_seek (abfd, curoff, SEEK_SET);  
             if (bfd_bwrite ((PTR) buf, thisread, abfd) != thisread)  
               return false;  
   
             nbytes -= thisread;  
             curoff += thisread;  
           }  
       }  
   }  
 #endif  
   
382    /* Now write header information.  */    /* Now write header information.  */
383    if (bfd_mach_o_write_header (abfd, &mdata->header) != 0)    if (bfd_mach_o_write_header (abfd, &mdata->header) != 0)
384      return false;      return FALSE;
385    
386    for (i = 0; i < mdata->header.ncmds; i++)    for (i = 0; i < mdata->header.ncmds; i++)
387      {      {
# Line 601  bfd_mach_o_write_contents (abfd) Line 389  bfd_mach_o_write_contents (abfd)
389        bfd_mach_o_load_command *cur = &mdata->commands[i];        bfd_mach_o_load_command *cur = &mdata->commands[i];
390        unsigned long typeflag;        unsigned long typeflag;
391    
392        typeflag = cur->type_required        typeflag = cur->type_required ? cur->type & BFD_MACH_O_LC_REQ_DYLD : cur->type;
         ? cur->type & BFD_MACH_O_LC_REQ_DYLD : cur->type;  
393    
394        bfd_h_put_32 (abfd, typeflag, buf);        bfd_h_put_32 (abfd, typeflag, buf);
395        bfd_h_put_32 (abfd, cur->len, buf + 4);        bfd_h_put_32 (abfd, cur->len, buf + 4);
396    
397        bfd_seek (abfd, cur->offset, SEEK_SET);        bfd_seek (abfd, cur->offset, SEEK_SET);
398        if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)        if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
399          return false;          return FALSE;
400    
401        switch (cur->type)        switch (cur->type)
402          {          {
403          case BFD_MACH_O_LC_SEGMENT:          case BFD_MACH_O_LC_SEGMENT:
404            if (bfd_mach_o_scan_write_segment (abfd, cur) != 0)            if (bfd_mach_o_scan_write_segment (abfd, cur) != 0)
405              return false;              return FALSE;
406            break;            break;
407          case BFD_MACH_O_LC_SYMTAB:          case BFD_MACH_O_LC_SYMTAB:
408            if (bfd_mach_o_scan_write_symtab (abfd, cur) != 0)            if (bfd_mach_o_scan_write_symtab (abfd, cur) != 0)
409              return false;              return FALSE;
410            break;            break;
411          case BFD_MACH_O_LC_SYMSEG:          case BFD_MACH_O_LC_SYMSEG:
412            break;            break;
413          case BFD_MACH_O_LC_THREAD:          case BFD_MACH_O_LC_THREAD:
414          case BFD_MACH_O_LC_UNIXTHREAD:          case BFD_MACH_O_LC_UNIXTHREAD:
415            if (bfd_mach_o_scan_write_thread (abfd, cur) != 0)            if (bfd_mach_o_scan_write_thread (abfd, cur) != 0)
416              return false;              return FALSE;
417            break;            break;
418          case BFD_MACH_O_LC_LOADFVMLIB:          case BFD_MACH_O_LC_LOADFVMLIB:
419          case BFD_MACH_O_LC_IDFVMLIB:          case BFD_MACH_O_LC_IDFVMLIB:
# Line 647  bfd_mach_o_write_contents (abfd) Line 434  bfd_mach_o_write_contents (abfd)
434            fprintf (stderr,            fprintf (stderr,
435                     "unable to write unknown load command 0x%lx\n",                     "unable to write unknown load command 0x%lx\n",
436                     (long) cur->type);                     (long) cur->type);
437            return false;            return FALSE;
438          }          }
439      }      }
440    
441    return true;    return TRUE;
442  }  }
443    
444  static int  static int
445  bfd_mach_o_sizeof_headers (a, b)  bfd_mach_o_sizeof_headers (a, b)
446       bfd *a ATTRIBUTE_UNUSED;       bfd *a ATTRIBUTE_UNUSED;
447       boolean b ATTRIBUTE_UNUSED;       bfd_boolean b ATTRIBUTE_UNUSED;
448  {  {
449    return 0;    return 0;
450  }  }
# Line 706  bfd_mach_o_read_header (abfd, header) Line 493  bfd_mach_o_read_header (abfd, header)
493       bfd_mach_o_header *header;       bfd_mach_o_header *header;
494  {  {
495    unsigned char buf[28];    unsigned char buf[28];
496    bfd_vma (*get32) PARAMS ((const bfd_byte *)) = NULL;    bfd_vma (*get32) (const void *) = NULL;
497    
498    bfd_seek (abfd, 0, SEEK_SET);    bfd_seek (abfd, 0, SEEK_SET);
499    
# Line 766  bfd_mach_o_make_bfd_section (abfd, secti Line 553  bfd_mach_o_make_bfd_section (abfd, secti
553    
554    bfdsec->vma = section->addr;    bfdsec->vma = section->addr;
555    bfdsec->lma = section->addr;    bfdsec->lma = section->addr;
556    bfdsec->_raw_size = section->size;    bfdsec->size = section->size;
557    bfdsec->filepos = section->offset;    bfdsec->filepos = section->offset;
558    bfdsec->alignment_power = section->align;    bfdsec->alignment_power = section->align;
   bfdsec->rel_filepos = section->reloff;  
   bfdsec->reloc_count = section->nreloc;  
559    
   /* I suspect that bfdsec->userdata is, at most, volatile.  When we really  
      need the value of section->flags, we will have to do something else to  
      store it for good.  */  
   bfdsec->userdata = (PTR) section->flags;  
     
560    if (section->flags & BFD_MACH_O_S_ZEROFILL)    if (section->flags & BFD_MACH_O_S_ZEROFILL)
561      bfdsec->flags = SEC_ALLOC;      bfdsec->flags = SEC_ALLOC;
562    else    else
563      bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;      bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
564    
   if (section->flags & BFD_MACH_O_S_LAZY_SYMBOL_POINTERS ||  
       section->flags & BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS) {  
     /* We want to do this because client program might rely on SEC_LOAD to  
        decide whether to call bfd_get_relocated_section_contents or not.  
        Altough a (non-)lazy symbol pointer section does not, stricly speaking,  
        have associated relocation entries, it contains symbol pointers to be  
        updated based on the global linker hash table.  */  
     bfdsec->flags |= SEC_LOAD;  
   }  
   
   if (bfdsec->reloc_count > 0)  
     bfdsec->flags |= SEC_RELOC;  
   
565    return bfdsec;    return bfdsec;
566  }  }
567    
# Line 875  bfd_mach_o_scan_write_symtab_symbols (ab Line 642  bfd_mach_o_scan_write_symtab_symbols (ab
642        unsigned char nsect = 0;        unsigned char nsect = 0;
643        short ndesc = 0;        short ndesc = 0;
644    
645        /*s = &sym->symbols[i];*/        s = &sym->symbols[i];
       s = &(sym->nlists[i].root);  
   
       /* Don't set this from the symbol information; use stored values.  */  
 #if 0  
       if (s->flags & BSF_GLOBAL)  
         ntype |= N_EXT;  
       if (s->flags & BSF_DEBUGGING)  
         ntype |= N_STAB;  
   
       if (s->section == bfd_und_section_ptr)  
         ntype |= N_UNDF;  
       else if (s->section == bfd_abs_section_ptr)  
         ntype |= N_ABS;  
       else  
         ntype |= N_SECT;  
 #endif  
646    
647        /* Instead just set from the stored values.  */        /* Instead just set from the stored values.  */
648        ntype = (s->udata.i >> 24) & 0xff;        ntype = (s->udata.i >> 24) & 0xff;
# Line 907  bfd_mach_o_scan_write_symtab_symbols (ab Line 658  bfd_mach_o_scan_write_symtab_symbols (ab
658        bfd_seek (abfd, symoff, SEEK_SET);        bfd_seek (abfd, symoff, SEEK_SET);
659        if (bfd_bwrite ((PTR) buf, 12, abfd) != 12)        if (bfd_bwrite ((PTR) buf, 12, abfd) != 12)
660          {          {
661            fprintf (stderr, "bfd_mach_o_scan_write_symtab_symbols: "            fprintf (stderr, "bfd_mach_o_scan_write_symtab_symbols: unable to write %d bytes at %lu\n",
                    "unable to write %d bytes at %lu\n",  
662                     12, (unsigned long) symoff);                     12, (unsigned long) symoff);
663            return -1;            return -1;
664          }          }
# Line 918  bfd_mach_o_scan_write_symtab_symbols (ab Line 668  bfd_mach_o_scan_write_symtab_symbols (ab
668  }  }
669    
670  int  int
671  bfd_mach_o_scan_read_symtab_symbol (abfd, sym, nlist, i)  bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, i)
672       bfd *abfd;       bfd *abfd;
673       bfd_mach_o_symtab_command *sym;       bfd_mach_o_symtab_command *sym;
674       /*asymbol *s;*/       asymbol *s;
      bfd_mach_o_nlist *nlist;  
675       unsigned long i;       unsigned long i;
676  {  {
677    bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;    bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
# Line 934  bfd_mach_o_scan_read_symtab_symbol (abfd Line 683  bfd_mach_o_scan_read_symtab_symbol (abfd
683    unsigned long value = -1;    unsigned long value = -1;
684    unsigned long stroff = -1;    unsigned long stroff = -1;
685    unsigned int symtype = -1;    unsigned int symtype = -1;
686    bfd_mach_o_ist *ist = mdata->ist;  
     
687    BFD_ASSERT (sym->strtab != NULL);    BFD_ASSERT (sym->strtab != NULL);
688    
689    bfd_seek (abfd, symoff, SEEK_SET);    bfd_seek (abfd, symoff, SEEK_SET);
690    if (bfd_bread ((PTR) buf, 12, abfd) != 12)    if (bfd_bread ((PTR) buf, 12, abfd) != 12)
691      {      {
692        fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "        fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: unable to read %d bytes at %lu\n",
                "unable to read %d bytes at %lu\n",  
693                 12, (unsigned long) symoff);                 12, (unsigned long) symoff);
694        return -1;        return -1;
695      }      }
# Line 950  bfd_mach_o_scan_read_symtab_symbol (abfd Line 697  bfd_mach_o_scan_read_symtab_symbol (abfd
697    stroff = bfd_h_get_32 (abfd, buf);    stroff = bfd_h_get_32 (abfd, buf);
698    type = bfd_h_get_8 (abfd, buf + 4);    type = bfd_h_get_8 (abfd, buf + 4);
699    symtype = (type & 0x0e);    symtype = (type & 0x0e);
700    /* We dont want to substract -1 twice.  */    section = bfd_h_get_8 (abfd, buf + 5) - 1;
   section = bfd_h_get_8 (abfd, buf + 5) /* - 1 */;  
701    desc = bfd_h_get_16 (abfd, buf + 6);    desc = bfd_h_get_16 (abfd, buf + 6);
702    value = bfd_h_get_32 (abfd, buf + 8);    value = bfd_h_get_32 (abfd, buf + 8);
703    
   nlist->nlist.n_type = type;  
   nlist->nlist.n_sect = section;  
   nlist->nlist.n_desc = desc;  
   nlist->nlist.n_value = value;  
     
   nlist->input_index = i;  
   nlist->output_index = (unsigned long) -1;  
     
704    if (stroff >= sym->strsize)    if (stroff >= sym->strsize)
705      {      {
706        fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "        fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
                "symbol name out of range (%lu >= %lu)\n",  
707                 (unsigned long) stroff, (unsigned long) sym->strsize);                 (unsigned long) stroff, (unsigned long) sym->strsize);
708        return -1;        return -1;
709      }      }
710    
711    nlist->root.the_bfd = abfd;    s->the_bfd = abfd;
712    nlist->root.name = sym->strtab + stroff;    s->name = sym->strtab + stroff;
713    nlist->root.value = value;    s->value = value;
714    /* Unfortunately, this cannot be relied on.  This field is volatile.  */    s->udata.i = (type << 24) | (section << 16) | desc;
715    nlist->root.udata.i = (type << 24) | (section << 16) | desc;    s->flags = 0x0;
   nlist->root.flags = 0x0;  
716    
717    if (type & BFD_MACH_O_N_STAB)    if (type & BFD_MACH_O_N_STAB)
718      {      {
719        nlist->root.flags |= BSF_DEBUGGING;        s->flags |= BSF_DEBUGGING;
720        nlist->root.section = bfd_und_section_ptr;        s->section = bfd_und_section_ptr;
721      }      }
722    else    else
723      {      {
724        if (type & BFD_MACH_O_N_PEXT)        if (type & BFD_MACH_O_N_PEXT)
725          {          {
726            /* Why this for ? */            type &= ~BFD_MACH_O_N_PEXT;
727            /* type &= ~BFD_MACH_O_N_PEXT; */            s->flags |= BSF_GLOBAL;
           nlist->root.flags |= BSF_GLOBAL;  
728          }          }
729    
730        if (type & BFD_MACH_O_N_EXT)        if (type & BFD_MACH_O_N_EXT)
731          {          {
732            /* Why this for ? */            type &= ~BFD_MACH_O_N_EXT;
733            /* type &= ~BFD_MACH_O_N_EXT; */            s->flags |= BSF_GLOBAL;
           nlist->root.flags |= BSF_GLOBAL;  
734          }          }
735    
736        switch (symtype)        switch (symtype)
737          {          {
738          case BFD_MACH_O_N_UNDF:          case BFD_MACH_O_N_UNDF:
739            nlist->root.section = bfd_und_section_ptr;            s->section = bfd_und_section_ptr;
           if (type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT)) {  
             if (value != 0)  
               {  
                 /* This is a common symbol, actually.  */  
                 nlist->root.section = bfd_com_section_ptr;  
               }  
             else  
               {  
                 /* There's not much we can do with an undefined symbol whose  
                    value is zero.  Here, we try to find a stub or non-lazy  
                    symbol pointer corresponding to this symbol.  ELF happens  
                    to do the same thing with its undefined symbols, setting  
                    them to point to PLT or GOT entries.  The code below is  
                    rather heuristic but I can't find of any thing better for  
                    now.  */  
   
                 if (ist != NULL)  
                   {  
                     asection *indirect_section = NULL;  
   
                     /* See if we can find a stub for this symbol.  */  
                     if (ist->nstubs > 0)  
                       nlist->root.value =  
                         bfd_mach_o_get_lazy_symbol_stub (ist, i,  
                                                          &indirect_section);  
   
                     /* If no stub was found, look for a non-lazy ptr.  */  
                     if (indirect_section == NULL && ist->nnlptrs > 0)  
                       nlist->root.value =  
                         bfd_mach_o_get_non_lazy_symbol_ptr (ist, i,  
                                                             &indirect_section);  
                       
                     /* If something was found, adjust the symbol value.  */  
                     if (indirect_section != NULL)  
                       nlist->root.value +=  
                         indirect_section->vma - bfd_und_section_ptr->vma;  
                   }  
               }  
           }  
740            break;            break;
741          case BFD_MACH_O_N_PBUD:          case BFD_MACH_O_N_PBUD:
742            nlist->root.section = bfd_und_section_ptr;            s->section = bfd_und_section_ptr;
743            break;            break;
744          case BFD_MACH_O_N_ABS:          case BFD_MACH_O_N_ABS:
745            nlist->root.section = bfd_abs_section_ptr;            s->section = bfd_abs_section_ptr;
746            break;            break;
747          case BFD_MACH_O_N_SECT:          case BFD_MACH_O_N_SECT:
748            if ((section > 0) && (section <= mdata->nsects))            if ((section > 0) && (section <= mdata->nsects))
749              {              {
750                nlist->root.section = mdata->sections[section - 1]->bfdsection;                s->section = mdata->sections[section - 1]->bfdsection;
751                nlist->root.value =                s->value = s->value - mdata->sections[section - 1]->addr;
                 nlist->root.value - mdata->sections[section - 1]->addr;  
752              }              }
753            else            else
754              {              {
755                /* Mach-O uses 0 to mean "no section"; not an error.  */                /* Mach-O uses 0 to mean "no section"; not an error.  */
756                if (section != 0)                if (section != 0)
757                  fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "                  {
758                           "symbol \"%s\" specified invalid section %d (max %lu): "                    fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
759                           "setting to undefined\n",                             "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
760                           nlist->root.name, section, mdata->nsects);                             s->name, section, mdata->nsects);
761                nlist->root.section = bfd_und_section_ptr;                  }
762                  s->section = bfd_und_section_ptr;
763              }              }
764            break;            break;
765          case BFD_MACH_O_N_INDR:          case BFD_MACH_O_N_INDR:
766            fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "            fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
767                     "symbol \"%s\" is unsupported 'indirect' reference: "                     "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
768                     "setting to undefined\n",                     s->name);
769                     nlist->root.name);            s->section = bfd_und_section_ptr;
           nlist->root.section = bfd_und_section_ptr;  
770            break;            break;
771          default:          default:
772            fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "            fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
773                     "symbol \"%s\" specified invalid type field 0x%x: "                     "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
774                     "setting to undefined\n",                     s->name, symtype);
775                     nlist->root.name, symtype);            s->section = bfd_und_section_ptr;
           nlist->root.section = bfd_und_section_ptr;  
776            break;            break;
777          }          }
         
       if ((nlist->root.flags & BSF_GLOBAL) == 0)  
         nlist->root.flags |= BSF_LOCAL;  
778      }      }
779    
780    return 0;    return 0;
# Line 1095  bfd_mach_o_scan_read_symtab_strtab (abfd Line 785  bfd_mach_o_scan_read_symtab_strtab (abfd
785       bfd *abfd;       bfd *abfd;
786       bfd_mach_o_symtab_command *sym;       bfd_mach_o_symtab_command *sym;
787  {  {
788    if (sym->strtab != NULL)    BFD_ASSERT (sym->strtab == NULL);
     return 0; /* If there's not work to be done, don't do any.  */  
789    
790    if (abfd->flags & BFD_IN_MEMORY)    if (abfd->flags & BFD_IN_MEMORY)
791      {      {
# Line 1109  bfd_mach_o_scan_read_symtab_strtab (abfd Line 798  bfd_mach_o_scan_read_symtab_strtab (abfd
798            bfd_set_error (bfd_error_file_truncated);            bfd_set_error (bfd_error_file_truncated);
799            return -1;            return -1;
800          }          }
801        sym->strtab = b->buffer + sym->stroff;        sym->strtab = (char *) b->buffer + sym->stroff;
802        return 0;        return 0;
803      }      }
804    
805    sym->strtab = bfd_alloc (abfd, sym->strsize);    sym->strtab = bfd_alloc (abfd, sym->strsize);
806    if (sym->strtab == NULL && sym->strsize != 0)    if (sym->strtab == NULL)
807      return -1;      return -1;
808    
809    bfd_seek (abfd, sym->stroff, SEEK_SET);    bfd_seek (abfd, sym->stroff, SEEK_SET);
810    if (bfd_bread ((PTR) sym->strtab, sym->strsize, abfd) != sym->strsize)    if (bfd_bread ((PTR) sym->strtab, sym->strsize, abfd) != sym->strsize)
811      {      {
812        fprintf (stderr, "bfd_mach_o_scan_read_symtab_strtab: "        fprintf (stderr, "bfd_mach_o_scan_read_symtab_strtab: unable to read %lu bytes at %lu\n",
                "unable to read %lu bytes at %lu\n",  
813                 sym->strsize, sym->stroff);                 sym->strsize, sym->stroff);
814        return -1;        return -1;
815      }      }
# Line 1136  bfd_mach_o_scan_read_symtab_symbols (abf Line 824  bfd_mach_o_scan_read_symtab_symbols (abf
824  {  {
825    unsigned long i;    unsigned long i;
826    int ret;    int ret;
   bfd_mach_o_ist *ist;  
   bfd_mach_o_nlist *nlist;  
     
   if (sym->nlists != NULL)  
     return true; /* If there's not work to be done, don't do any.  */  
827    
828    sym->nlists = (bfd_mach_o_nlist *)    BFD_ASSERT (sym->symbols == NULL);
829      bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_nlist));    sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (asymbol));
830    
831    if (sym->nlists == NULL && sym->nsyms != 0)    if (sym->symbols == NULL)
832      {      {
833        fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbols: "        fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbols: unable to allocate memory for symbols\n");
                "unable to allocate memory for symbols\n");  
834        return -1;        return -1;
835      }      }
836    
# Line 1156  bfd_mach_o_scan_read_symtab_symbols (abf Line 838  bfd_mach_o_scan_read_symtab_symbols (abf
838    if (ret != 0)    if (ret != 0)
839      return ret;      return ret;
840    
841    ist = bfd_mach_o_slurp_ist (abfd);    for (i = 0; i < sym->nsyms; i++)
     
   for (nlist = sym->nlists, i = 0; i < sym->nsyms; nlist++, i++)  
842      {      {
843        ret = bfd_mach_o_scan_read_symtab_symbol (abfd, sym, nlist, i);        ret = bfd_mach_o_scan_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
844        if (ret != 0)        if (ret != 0)
845          return ret;          return ret;
846      }      }
# Line 1169  bfd_mach_o_scan_read_symtab_symbols (abf Line 849  bfd_mach_o_scan_read_symtab_symbols (abf
849  }  }
850    
851  int  int
852  bfd_mach_o_scan_read_dysymtab_symbol (abfd, dysym, sym, nlist, i)  bfd_mach_o_scan_read_dysymtab_symbol (abfd, dysym, sym, s, i)
853       bfd *abfd;       bfd *abfd;
854       bfd_mach_o_dysymtab_command *dysym;       bfd_mach_o_dysymtab_command *dysym;
855       bfd_mach_o_symtab_command *sym;       bfd_mach_o_symtab_command *sym;
856       bfd_mach_o_nlist *nlist;       asymbol *s;
857       unsigned long i;       unsigned long i;
858  {  {
859    unsigned long isymoff = dysym->indirectsymoff + (i * 4);    unsigned long isymoff = dysym->indirectsymoff + (i * 4);
# Line 1185  bfd_mach_o_scan_read_dysymtab_symbol (ab Line 865  bfd_mach_o_scan_read_dysymtab_symbol (ab
865    bfd_seek (abfd, isymoff, SEEK_SET);    bfd_seek (abfd, isymoff, SEEK_SET);
866    if (bfd_bread ((PTR) buf, 4, abfd) != 4)    if (bfd_bread ((PTR) buf, 4, abfd) != 4)
867      {      {
868        fprintf (stderr, "bfd_mach_o_scan_read_dysymtab_symbol: "        fprintf (stderr, "bfd_mach_o_scan_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
                "unable to read %lu bytes at %lu\n",  
869                 (unsigned long) 4, isymoff);                 (unsigned long) 4, isymoff);
870        return -1;        return -1;
871      }      }
872    symindex = bfd_h_get_32 (abfd, buf);    symindex = bfd_h_get_32 (abfd, buf);
873    
874    return bfd_mach_o_scan_read_symtab_symbol (abfd, sym, nlist, symindex);    return bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, symindex);
875  }  }
876    
877  static const char *  static const char *
# Line 1201  bfd_mach_o_i386_flavour_string (flavour) Line 880  bfd_mach_o_i386_flavour_string (flavour)
880  {  {
881    switch ((int) flavour)    switch ((int) flavour)
882      {      {
883      case BFD_MACH_O_i386_NEW_THREAD_STATE:      case BFD_MACH_O_i386_NEW_THREAD_STATE: return "i386_NEW_THREAD_STATE";
884        return "i386_NEW_THREAD_STATE";      case BFD_MACH_O_i386_FLOAT_STATE: return "i386_FLOAT_STATE";
885      case BFD_MACH_O_i386_FLOAT_STATE:      case BFD_MACH_O_i386_ISA_PORT_MAP_STATE: return "i386_ISA_PORT_MAP_STATE";
886        return "i386_FLOAT_STATE";      case BFD_MACH_O_i386_V86_ASSIST_STATE: return "i386_V86_ASSIST_STATE";
887      case BFD_MACH_O_i386_ISA_PORT_MAP_STATE:      case BFD_MACH_O_i386_REGS_SEGS_STATE: return "i386_REGS_SEGS_STATE";
888        return "i386_ISA_PORT_MAP_STATE";      case BFD_MACH_O_i386_THREAD_SYSCALL_STATE: return "i386_THREAD_SYSCALL_STATE";
889      case BFD_MACH_O_i386_V86_ASSIST_STATE:      case BFD_MACH_O_i386_THREAD_STATE_NONE: return "i386_THREAD_STATE_NONE";
890        return "i386_V86_ASSIST_STATE";      case BFD_MACH_O_i386_SAVED_STATE: return "i386_SAVED_STATE";
891      case BFD_MACH_O_i386_REGS_SEGS_STATE:      case BFD_MACH_O_i386_THREAD_STATE: return "i386_THREAD_STATE";
892        return "i386_REGS_SEGS_STATE";      case BFD_MACH_O_i386_THREAD_FPSTATE: return "i386_THREAD_FPSTATE";
893      case BFD_MACH_O_i386_THREAD_SYSCALL_STATE:      case BFD_MACH_O_i386_THREAD_EXCEPTSTATE: return "i386_THREAD_EXCEPTSTATE";
894        return "i386_THREAD_SYSCALL_STATE";      case BFD_MACH_O_i386_THREAD_CTHREADSTATE: return "i386_THREAD_CTHREADSTATE";
895      case BFD_MACH_O_i386_THREAD_STATE_NONE:      default: return "UNKNOWN";
       return "i386_THREAD_STATE_NONE";  
     case BFD_MACH_O_i386_SAVED_STATE:  
       return "i386_SAVED_STATE";  
     case BFD_MACH_O_i386_THREAD_STATE:  
       return "i386_THREAD_STATE";  
     case BFD_MACH_O_i386_THREAD_FPSTATE:  
       return "i386_THREAD_FPSTATE";  
     case BFD_MACH_O_i386_THREAD_EXCEPTSTATE:  
       return "i386_THREAD_EXCEPTSTATE";  
     case BFD_MACH_O_i386_THREAD_CTHREADSTATE:  
       return "i386_THREAD_CTHREADSTATE";  
     default:  
       return "UNKNOWN";  
896      }      }
897  }  }
898    
# Line 1320  bfd_mach_o_scan_read_dylinker (abfd, com Line 986  bfd_mach_o_scan_read_dylinker (abfd, com
986    
987    bfdsec->vma = 0;    bfdsec->vma = 0;
988    bfdsec->lma = 0;    bfdsec->lma = 0;
989    bfdsec->_raw_size = command->len - 8;    bfdsec->size = command->len - 8;
990    bfdsec->filepos = command->offset + 8;    bfdsec->filepos = command->offset + 8;
991    bfdsec->alignment_power = 0;    bfdsec->alignment_power = 0;
992    bfdsec->flags = SEC_HAS_CONTENTS;    bfdsec->flags = SEC_HAS_CONTENTS;
# Line 1378  bfd_mach_o_scan_read_dylib (abfd, comman Line 1044  bfd_mach_o_scan_read_dylib (abfd, comman
1044    
1045    bfdsec->vma = 0;    bfdsec->vma = 0;
1046    bfdsec->lma = 0;    bfdsec->lma = 0;
1047    bfdsec->_raw_size = command->len - 8;    bfdsec->size = command->len - 8;
1048    bfdsec->filepos = command->offset + 8;    bfdsec->filepos = command->offset + 8;
1049    bfdsec->alignment_power = 0;    bfdsec->alignment_power = 0;
1050    bfdsec->flags = SEC_HAS_CONTENTS;    bfdsec->flags = SEC_HAS_CONTENTS;
# Line 1501  bfd_mach_o_scan_read_thread (abfd, comma Line 1167  bfd_mach_o_scan_read_thread (abfd, comma
1167    
1168        bfdsec->vma = 0;        bfdsec->vma = 0;
1169        bfdsec->lma = 0;        bfdsec->lma = 0;
1170        bfdsec->_raw_size = cmd->flavours[i].size;        bfdsec->size = cmd->flavours[i].size;
1171        bfdsec->filepos = cmd->flavours[i].offset;        bfdsec->filepos = cmd->flavours[i].offset;
1172        bfdsec->alignment_power = 0x0;        bfdsec->alignment_power = 0x0;
1173        bfdsec->flags = SEC_HAS_CONTENTS /*| SEC_THREAD_LOCAL*/;        bfdsec->flags = SEC_HAS_CONTENTS;
1174    
1175        cmd->section = bfdsec;        cmd->section = bfdsec;
1176      }      }
# Line 1594  bfd_mach_o_scan_read_symtab (abfd, comma Line 1260  bfd_mach_o_scan_read_symtab (abfd, comma
1260    seg->nsyms = bfd_h_get_32 (abfd, buf + 4);    seg->nsyms = bfd_h_get_32 (abfd, buf + 4);
1261    seg->stroff = bfd_h_get_32 (abfd, buf + 8);    seg->stroff = bfd_h_get_32 (abfd, buf + 8);
1262    seg->strsize = bfd_h_get_32 (abfd, buf + 12);    seg->strsize = bfd_h_get_32 (abfd, buf + 12);
1263    /*seg->symbols = NULL;*/    seg->symbols = NULL;
   seg->nlists = NULL;  
1264    seg->strtab = NULL;    seg->strtab = NULL;
1265    
1266    sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);    sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
# Line 1609  bfd_mach_o_scan_read_symtab (abfd, comma Line 1274  bfd_mach_o_scan_read_symtab (abfd, comma
1274    
1275    bfdsec->vma = 0;    bfdsec->vma = 0;
1276    bfdsec->lma = 0;    bfdsec->lma = 0;
1277    bfdsec->_raw_size = seg->nsyms * 12;    bfdsec->size = seg->nsyms * 12;
1278    bfdsec->filepos = seg->symoff;    bfdsec->filepos = seg->symoff;
1279    bfdsec->alignment_power = 0;    bfdsec->alignment_power = 0;
1280    bfdsec->flags = SEC_HAS_CONTENTS;    bfdsec->flags = SEC_HAS_CONTENTS;
   bfdsec->reloc_count = 0;  
1281    
1282    seg->stabs_segment = bfdsec;    seg->stabs_segment = bfdsec;
1283    
# Line 1629  bfd_mach_o_scan_read_symtab (abfd, comma Line 1293  bfd_mach_o_scan_read_symtab (abfd, comma
1293    
1294    bfdsec->vma = 0;    bfdsec->vma = 0;
1295    bfdsec->lma = 0;    bfdsec->lma = 0;
1296    bfdsec->_raw_size = seg->strsize;    bfdsec->size = seg->strsize;
1297    bfdsec->filepos = seg->stroff;    bfdsec->filepos = seg->stroff;
1298    bfdsec->alignment_power = 0;    bfdsec->alignment_power = 0;
1299    bfdsec->flags = SEC_HAS_CONTENTS;    bfdsec->flags = SEC_HAS_CONTENTS;
1300    bfdsec->reloc_count = 0;  
     
1301    seg->stabstr_segment = bfdsec;    seg->stabstr_segment = bfdsec;
1302    
1303    return 0;    return 0;
# Line 1675  bfd_mach_o_scan_read_segment (abfd, comm Line 1338  bfd_mach_o_scan_read_segment (abfd, comm
1338      return -1;      return -1;
1339    sprintf (sname, "%s.%s", prefix, seg->segname);    sprintf (sname, "%s.%s", prefix, seg->segname);
1340    
 #if 0  
1341    bfdsec = bfd_make_section_anyway (abfd, sname);    bfdsec = bfd_make_section_anyway (abfd, sname);
1342    if (bfdsec == NULL)    if (bfdsec == NULL)
1343      return -1;      return -1;
1344    
1345    bfdsec->vma = seg->vmaddr;    bfdsec->vma = seg->vmaddr;
1346    bfdsec->lma = seg->vmaddr;    bfdsec->lma = seg->vmaddr;
1347    bfdsec->_raw_size = seg->filesize;    bfdsec->size = seg->filesize;
1348    bfdsec->filepos = seg->fileoff;    bfdsec->filepos = seg->fileoff;
1349    bfdsec->alignment_power = 0x0;    bfdsec->alignment_power = 0x0;
1350    bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;    bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
 #else  
   bfdsec = NULL;  
 #endif  
1351    
1352    seg->segment = bfdsec;    seg->segment = bfdsec;
1353    
# Line 1956  bfd_mach_o_scan (abfd, header, mdata) Line 1615  bfd_mach_o_scan (abfd, header, mdata)
1615    
1616    mdata->header = *header;    mdata->header = *header;
1617    mdata->symbols = NULL;    mdata->symbols = NULL;
1618    
1619    abfd->flags = (abfd->xvec->object_flags    abfd->flags = (abfd->xvec->object_flags
1620                   | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));                   | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
1621    abfd->tdata.mach_o_data = mdata;    abfd->tdata.mach_o_data = mdata;
# Line 1976  bfd_mach_o_scan (abfd, header, mdata) Line 1635  bfd_mach_o_scan (abfd, header, mdata)
1635      {      {
1636        mdata->commands =        mdata->commands =
1637          ((bfd_mach_o_load_command *)          ((bfd_mach_o_load_command *)
1638           bfd_zalloc (abfd, header->ncmds * sizeof (bfd_mach_o_load_command)));           bfd_alloc (abfd, header->ncmds * sizeof (bfd_mach_o_load_command)));
1639        if (mdata->commands == NULL)        if (mdata->commands == NULL)
1640          return -1;          return -1;
1641    
# Line 1998  bfd_mach_o_scan (abfd, header, mdata) Line 1657  bfd_mach_o_scan (abfd, header, mdata)
1657      }      }
1658    
1659    if (bfd_mach_o_scan_start_address (abfd) < 0)    if (bfd_mach_o_scan_start_address (abfd) < 0)
1660      {      return -1;
 #if 0  
       fprintf (stderr, "bfd_mach_o_scan: unable to scan start address: %s\n",  
                bfd_errmsg (bfd_get_error ()));  
       abfd->tdata.mach_o_data = NULL;  
       return -1;  
 #endif  
     }  
1661    
1662    bfd_mach_o_flatten_sections (abfd);    bfd_mach_o_flatten_sections (abfd);
   
1663    return 0;    return 0;
1664  }  }
1665    
1666  boolean  bfd_boolean
1667  bfd_mach_o_mkobject (abfd)  bfd_mach_o_mkobject (abfd)
1668       bfd *abfd;       bfd *abfd;
1669  {  {
1670    bfd_mach_o_data_struct *mdata = NULL;    bfd_mach_o_data_struct *mdata = NULL;
1671    
1672    mdata = ((bfd_mach_o_data_struct *)    mdata = ((bfd_mach_o_data_struct *)
1673             bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct)));             bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct)));
1674    if (mdata == NULL)    if (mdata == NULL)
1675      return false;      return FALSE;
1676    abfd->tdata.mach_o_data = mdata;    abfd->tdata.mach_o_data = mdata;
1677    
1678    mdata->header.magic = 0;    mdata->header.magic = 0;
# Line 2037  bfd_mach_o_mkobject (abfd) Line 1688  bfd_mach_o_mkobject (abfd)
1688    mdata->symbols = NULL;    mdata->symbols = NULL;
1689    mdata->nsects = 0;    mdata->nsects = 0;
1690    mdata->sections = NULL;    mdata->sections = NULL;
   mdata->ist = NULL;  
1691    mdata->ibfd = NULL;    mdata->ibfd = NULL;
1692    
1693    return true;    return TRUE;
1694  }  }
1695    
1696  const bfd_target *  const bfd_target *
# Line 2470  bfd_mach_o_core_file_failing_command (ab Line 2120  bfd_mach_o_core_file_failing_command (ab
2120    if (ret < 0)    if (ret < 0)
2121      return NULL;      return NULL;
2122    
2123    return buf;    return (char *) buf;
2124  }  }
2125    
2126  int  int
# Line 2480  bfd_mach_o_core_file_failing_signal (abf Line 2130  bfd_mach_o_core_file_failing_signal (abf
2130    return 0;    return 0;
2131  }  }
2132    
2133  boolean  bfd_boolean
2134  bfd_mach_o_core_file_matches_executable_p (core_bfd, exec_bfd)  bfd_mach_o_core_file_matches_executable_p (core_bfd, exec_bfd)
2135       bfd *core_bfd ATTRIBUTE_UNUSED;       bfd *core_bfd ATTRIBUTE_UNUSED;
2136       bfd *exec_bfd ATTRIBUTE_UNUSED;       bfd *exec_bfd ATTRIBUTE_UNUSED;
2137  {  {
2138    return true;    return TRUE;
 }  
   
 static int  
 bfd_mach_o_compar_st_idx (const void *a, const void *b)  
 {  
     unsigned long  x = ((bfd_mach_o_ist_entry *) a)->st_idx;  
     unsigned long  y = ((bfd_mach_o_ist_entry *) b)->st_idx;  
   
     return (int) x - (int) y;  
2139  }  }
2140    
 static void  
 bfd_mach_o_dump_ist_aux (abfd, sym, sect_array, array_length, tot)  
      bfd *abfd;  
      bfd_mach_o_symtab_command *sym;  
      bfd_mach_o_section **sect_array;  
      unsigned long array_length;  
      unsigned long tot;  
 {  
   bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;  
   bfd_mach_o_ist *ist = mdata->ist;  
   unsigned long i;  
     
   BFD_ASSERT (sym->symoff != NULL);  
   BFD_ASSERT (sym->strtab != NULL);  
     
   for (i=0 ; i < array_length ; sect_array++, i++)  
     {  
       bfd_mach_o_ist_entry *e;  
       unsigned long start;  
       unsigned long nmemb;  
       unsigned long j;  
       unsigned long atomic_size;  
         
       if ((*sect_array)->reserved2)  
         atomic_size = ((*sect_array)->reserved2);  
       else  
         atomic_size = 4;  
         
       start = (*sect_array)->reserved1;  
       nmemb = (*sect_array)->size / atomic_size;  
   
       if (nmemb + start > ist->nmemb || start >= ist->nmemb) {  
         printf ("%s: contains garbage\n\n", (*sect_array)->sectname);  
         continue;  
       }  
   
       printf ("%s (contains %ld out of %ld indirect symbols)\n",  
               (*sect_array)->sectname, nmemb, tot);  
   
       e = ist->raw_ist + start;  
         
       for (j=0 ; j < nmemb ; e++, j++)  
         {  
           file_ptr symdelta, strdelta;  
           char buf [12];  
             
           symdelta = (e->st_idx) * 12;  
             
           if (bfd_seek (abfd, sym->symoff + symdelta, SEEK_SET) != 0 ||  
               bfd_bread ((PTR) buf, 12, abfd) != 12)  
             continue;  
             
           strdelta = bfd_h_get_32 (abfd, buf);  
             
           printf ("  %5ld - %5ld %s\n",  
                   e->ist_idx, e->st_idx, sym->strtab + strdelta);  
         }  
   
       printf ("\n");  
       fflush (stdout);  
     }  
 }  
   
 static void  
 bfd_mach_o_dump_ist (abfd, sym)  
      bfd *abfd;  
      bfd_mach_o_symtab_command *sym;  
 {  
   bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;  
   bfd_mach_o_ist *ist = mdata->ist;  
     
   if (ist != NULL)  
     {  
       printf ("\nDumping indirect symbol table for file %s:\n\n",  
               abfd->filename);  
   
       bfd_mach_o_dump_ist_aux (abfd, sym, ist->stubs,  ist->nstubs,  ist->nmemb);  
     
       bfd_mach_o_dump_ist_aux (abfd, sym, ist->nlptrs, ist->nnlptrs, ist->nmemb);  
   
       bfd_mach_o_dump_ist_aux (abfd, sym, ist->laptrs, ist->nlaptrs, ist->nmemb);  
     }  
 }  
   
 static boolean  
 bfd_mach_o_check_ist (ist)  
      bfd_mach_o_ist *ist;  
 {  
   if (ist != NULL)  
     {  
       boolean retval = true;  
         
       if (ist->nmemb > 0)  
         {      
           bfd_mach_o_section **stub_sections;  
           boolean *marks;  
           unsigned long i;  
             
           stub_sections = ist->stubs;  
   
           marks = (boolean *) bfd_malloc (ist->nmemb * sizeof (boolean));  
           if (marks == NULL)  
             return false;  
             
           memset (marks, 0, ist->nmemb * sizeof (boolean));  
             
           for (i=0 ; i < ist->nstubs ; stub_sections++, i++)  
             {  
               unsigned long j, start,  nmemb;  
               bfd_mach_o_ist_entry *e;  
           
               if ((*stub_sections)->reserved2 == 0)  
                 {  
                   fprintf (stderr, "check_ist: invalid stub size in section "  
                            "%s\n", (*stub_sections)->sectname);  
                   retval = false;  
                   break;  
                 }  
                 
               start = (*stub_sections)->reserved1;  
               nmemb = (*stub_sections)->size / (*stub_sections)->reserved2;  
                 
               if (nmemb + start > ist->nmemb || start >= ist->nmemb)  
                 {  
                   fprintf (stderr, "check_ist: malformed indirect section %s\n",  
                            (*stub_sections)->sectname);  
                   retval = false;  
                   break;  
                 }  
   
               e = ist->raw_ist + start;  
                 
               for (j=0 ; j < nmemb ; j++, e++)  
                 {  
                   boolean already_there = marks[e->ist_idx];  
                     
                   if (!already_there) {  
                     marks[e->ist_idx] = true;  
                   } else {  
                     fprintf (stderr, "check_ist: multiple stubs for "  
                              "indirect symbol %ld/%ld\n",  
                              e->ist_idx, e->st_idx );  
                  /* retval = false;  This is legal, actually.  */  
                   }  
                 }  
             }  
             
           free (marks);  
             
           fflush (stderr);  
         }  
   
       return retval;  
     }  
   
   return false;  
 }  
   
 static bfd_mach_o_ist *  
 bfd_mach_o_slurp_ist (abfd)  
      bfd *abfd;  
 {  
   bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;  
   bfd_mach_o_dysymtab_command *dyst = NULL;  
   bfd_mach_o_ist *ist = NULL;  
   unsigned long nnlptrs = 0;  
   unsigned long nlaptrs = 0;  
   unsigned long nstubs = 0;  
   unsigned long i;  
       
   if (mdata->ist != NULL) {  
     /* Nothing to do.  */  
     return (mdata->ist);  
   }  
       
   for (i=0 ; i < mdata->header.ncmds ; i++) {  
     if (mdata->commands[i].type == BFD_MACH_O_LC_DYSYMTAB)  
       {  
         if (dyst != NULL) {  
           fprintf (stderr, "bfd_mach_o_slurp_ist: "  
                    "input file contains more than one LC_DYSYMTAB load cmd\n");  
           abort ();  
         }  
         dyst = &mdata->commands[i].command.dysymtab;  
       }  
   }  
     
   ist = (bfd_mach_o_ist *) bfd_zalloc (abfd, sizeof (bfd_mach_o_ist));  
   if (ist == NULL)  
     return (NULL);  
       
   /* Make sure we did find a LC_DYSYMTAB load command.  */  
   
   if (dyst != NULL)  
     {  
       bfd_size_type ist_size;  
           
       ist->command = dyst;  
       ist->nmemb = dyst->nindirectsyms;  
           
       if (ist->nmemb == 0) {  
      /* Empty indirect symbol table.  */  
         return (mdata->ist = ist);  
       }  
         
       ist_size = ist->nmemb * sizeof (bfd_mach_o_ist_entry);  
   
       ist->raw_ist = (bfd_mach_o_ist_entry *) bfd_alloc (abfd, ist_size);  
       ist->sorted_ist = (bfd_mach_o_ist_entry *) bfd_alloc (abfd, ist_size);  
   
       if (ist->raw_ist == NULL || ist->sorted_ist == NULL)  
         return (NULL);  
         
       if ((bfd_seek (abfd, dyst->indirectsymoff, SEEK_SET) != 0 ||  
            bfd_bread (ist->raw_ist, ist_size, abfd) != ist_size))  
         return (NULL);  
           
       for (i=ist->nmemb ; --i != (unsigned long) -1 ; )  
         {  
           (ist->raw_ist)[i].st_idx = ((unsigned long *) ist->raw_ist)[i];  
           (ist->raw_ist)[i].ist_idx = i;  
   
           (ist->sorted_ist)[i].ist_idx = i;  
           (ist->sorted_ist)[i].st_idx = (ist->raw_ist)[i].st_idx;  
         }  
           
       /* Loop through all sections, looking for ist related sections.  */  
   
       for (i=0 ; i < mdata->nsects ; i++)  
         {  
           bfd_mach_o_section *sectp = mdata->sections[i];  
           bfd_size_type array_size;  
           unsigned long start;  
           unsigned long nmemb;  
               
           if ((sectp->flags & SECTION_TYPE)  
               == BFD_MACH_O_S_SYMBOL_STUBS)  
             {  
               array_size = (++nstubs) * sizeof (bfd_mach_o_section *);  
                   
               ist->stubs =  
                 (bfd_mach_o_section **) bfd_realloc (ist->stubs, array_size);  
   
               if (ist->stubs == NULL)  
                 return NULL;  
                   
               ist->stubs[ist->nstubs++] = sectp;  
             }  
           else if ((sectp->flags & SECTION_TYPE)  
                    == BFD_MACH_O_S_NL_SYMBOL_POINTERS)  
             {  
               array_size = (++nnlptrs) * sizeof (bfd_mach_o_section *);  
                   
               ist->nlptrs =  
                 (bfd_mach_o_section **) bfd_realloc (ist->nlptrs, array_size);  
   
               if (ist->nlptrs == NULL)  
                 return (NULL);  
                   
               ist->nlptrs[ist->nnlptrs++] = sectp;  
             }  
           else if ((sectp->flags & SECTION_TYPE)  
                    == BFD_MACH_O_S_LA_SYMBOL_POINTERS)  
             {  
               array_size = (++nlaptrs) * sizeof (bfd_mach_o_section *);  
   
               ist->laptrs =  
                 (bfd_mach_o_section **) bfd_realloc (ist->laptrs, array_size);  
   
               if (ist->laptrs == NULL)  
                 return (NULL);  
   
               ist->laptrs[ist->nlaptrs++] = sectp;  
             }  
           else  
             {  
               continue;  
             }  
   
           start = sectp->reserved1;  
           nmemb = sectp->size / (sectp->reserved2 != 0 ? sectp->reserved2 : 4);  
   
           qsort (ist->sorted_ist + start, nmemb,  
                  sizeof (bfd_mach_o_ist_entry), bfd_mach_o_compar_st_idx);  
         }  
   
        BFD_ASSERT (bfd_mach_o_check_ist (ist));  
     }  
       
   return (mdata->ist = ist);  
 }  
   
 static bfd_vma  
 bfd_mach_o_get_lazy_symbol_stub (ist, sym_idx, asect_ptr)  
   bfd_mach_o_ist *ist;  
   unsigned long sym_idx;  
   asection **asect_ptr;  
 {  
   bfd_vma addr = 0;  
       
   if (ist != NULL)  
     {  
       bfd_mach_o_section **stub_sections;  
       unsigned long i;  
         
       stub_sections = ist->stubs;  
         
       for (i=0 ; i < ist->nstubs ; stub_sections++, i++)  
         {  
           unsigned long start, stub_size, nmemb;  
           bfd_mach_o_ist_entry *match, key;  
               
           start = (*stub_sections)->reserved1;  
           stub_size = (*stub_sections)->reserved2;  
           nmemb = (*stub_sections)->size / stub_size;  
             
           key.st_idx = sym_idx;  
               
           match = (bfd_mach_o_ist_entry *)  
             bsearch (&key, ist->sorted_ist + start, nmemb,  
                      sizeof (bfd_mach_o_ist_entry), bfd_mach_o_compar_st_idx);  
               
           if (match != NULL) {  
             if ((start <= match->ist_idx) && (match->ist_idx < (start + nmemb)))  
               {  
                 if (asect_ptr != NULL)  
                   *asect_ptr = (*stub_sections)->bfdsection;  
                 
                 /* Obey the general contract about symbol addresses,  
                    i.e. return a section relative address.  */  
                 return (addr = ((match->ist_idx - start) * stub_size));  
               }  
           }  
         }  
     }  
       
   return (addr);  
 }  
   
 static bfd_vma  
 bfd_mach_o_get_non_lazy_symbol_ptr (ist, sym_idx, asect_ptr)  
   bfd_mach_o_ist *ist;  
   unsigned long sym_idx;  
   asection **asect_ptr;  
 {  
   bfd_vma addr = 0;  
     
   if (ist != NULL)  
     {  
       bfd_mach_o_section **nlptr_sections;  
       unsigned long i;  
         
       nlptr_sections = ist->nlptrs;  
         
       for (i=0 ; i < ist->nnlptrs ; nlptr_sections++, i++)  
         {  
           unsigned long start, nmemb;  
           bfd_mach_o_ist_entry *match, key;  
               
           start = (*nlptr_sections)->reserved1;  
           nmemb = (*nlptr_sections)->size / 4;  
             
           key.st_idx = sym_idx;  
               
           match = (bfd_mach_o_ist_entry *)  
             bsearch (&key, ist->sorted_ist + start, nmemb,  
                      sizeof (bfd_mach_o_ist_entry), bfd_mach_o_compar_st_idx);  
               
           if (match != NULL) {  
             if ((start <= match->ist_idx) && (match->ist_idx < (start + nmemb)))  
               {  
                 if (asect_ptr != NULL)  
                   *asect_ptr = (*nlptr_sections)->bfdsection;  
                 
                 /* Obey the general contract about symbol addresses,  
                    i.e. return a section relative address.  */  
                 return (addr = ((match->ist_idx - start) * 4));  
               }  
           }  
         }  
     }  
       
   return (addr);  
 }  
   
 static boolean  
 bfd_mach_o_bfd_link_add_symbols (abfd,info)  
      bfd *abfd;  
      struct bfd_link_info *info;  
 {  
   bfd_mach_o_data_struct *mdata;  
   unsigned long i;  
       
   BFD_ASSERT (bfd_mach_o_valid (abfd));  
   mdata = abfd->tdata.mach_o_data;  
       
   for (i = 0; i < mdata->header.ncmds; i++)  
     {  
       if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)  
         {  
           bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;  
           unsigned long j;  
               
           if (bfd_mach_o_scan_read_symtab_strtab (abfd, sym) < 0) {  
             fprintf (stderr, "bfd_mach_o_link_add_symbols: "  
                      "error reading strtab\n");  
             return false;  
           }  
               
           BFD_ASSERT (sym->strtab != NULL);  
               
           for (j=0 ; j < sym->nsyms ; j++)  
             {  
               bfd_vma symoff = sym->symoff + (j * 12);  
                   
               unsigned char buf[12];  
               unsigned char type;  
               unsigned char sect;  
               short desc;  
               bfd_vma value;  
               unsigned long stroff;  
                   
               boolean copy = true; /* (info->keep_memory) ? false : TRUE; */  
               const char *name;  
               flagword flags;  
               asection *section;  
                   
               bfd_seek (abfd, symoff, SEEK_SET);  
               if (bfd_bread ((PTR) buf, 12, abfd) != 12) {  
                 return false;  
               }  
                   
               type = bfd_h_get_8 (abfd, buf + 4);  
                   
               if (type & BFD_MACH_O_N_STAB)  
                 continue;  
   
               stroff = bfd_h_get_32 (abfd, buf);  
               sect = bfd_h_get_8 (abfd, buf + 5);  
               desc = bfd_h_get_16 (abfd, buf + 6);  
               value = bfd_h_get_32 (abfd, buf + 8);  
   
               if (stroff >= sym->strsize) {  
                 bfd_set_error (bfd_error_file_truncated);  
                 return false;  
               }  
                   
               name = sym->strtab + stroff;  
               flags = BSF_GLOBAL;  
                   
               if (type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT))  
                 {  
                   struct bfd_link_hash_entry *hashp = NULL;  
                       
                   /* In the case of an N_INDR symbol, `string' is  
                      the name of the symbol that is referred to.  */  
                   const char *string = NULL;  
                       
                   switch (type & BFD_MACH_O_N_TYPE) {  
                   case BFD_MACH_O_N_UNDF:  
                     if (value == 0) {  
                       section = bfd_und_section_ptr;  
                       /* flags = 0; */  
                     }  
                     else  
                       section = bfd_com_section_ptr;  
                     break;  
                   case BFD_MACH_O_N_PBUD:  
                     section = bfd_und_section_ptr;  
                     break;  
                   case BFD_MACH_O_N_ABS:  
                     section = bfd_abs_section_ptr;  
                     break;  
                   case BFD_MACH_O_N_INDR:  
                     flags |= BSF_INDIRECT;  
                     section = bfd_ind_section_ptr;  
                     fprintf (stderr,  
                              "BFD_MACH_O_N_INDR symbols not yet supported\n");  
                     abort ();  
                     break;  
                   case BFD_MACH_O_N_SECT:  
                     /* section numbering starts at 1, zero means no section */  
                     if (sect > 0 && sect <= mdata->nsects) {  
                       section = mdata->sections[sect-1]->bfdsection;  
                       value -= mdata->sections[sect-1]->addr;  
                     } else {  
                       if (sect != 0) {  
                         fprintf (stderr,  
                                  "bfd_mach_o_link_add_symbols: symbol \"%s\" "  
                                  "specified invalid section %d (max %lu), "  
                                  "setting to undefined\n",  
                                  name, sect, mdata->nsects);  
                       }  
                       section = bfd_und_section_ptr;  
                       fprintf (stderr, "sect: %d %s\n", sect, name);  
                     }  
                     break;  
                   default:  
                     fprintf (stderr, "unknown N_TYPE value");  
                     abort();  
                     break;  
                   }  
                     
                   if ((flags & BSF_GLOBAL) == 0)  
                     flags |= BSF_LOCAL;  
                     
                   /* FIX-ME: Set the alignment for common symbols here.  */  
                       
                   if (!_bfd_generic_link_add_one_symbol (info, abfd, name, flags,  
                                                          section, value, string,  
                                                          copy, false, &hashp)) {  
                     return false;  
                   }  
                 }  
             }  
         }  
     }  
       
   return true;  
 }  
   
 /*  
 FUNCTION  
         bfd_preserve_save  
   
 SYNOPSIS  
         boolean bfd_preserve_save (bfd *, struct bfd_preserve *);  
   
 DESCRIPTION  
         When testing an object for compatibility with a particular  
         target back-end, the back-end object_p function needs to set  
         up certain fields in the bfd on successfully recognizing the  
         object.  This typically happens in a piecemeal fashion, with  
         failures possible at many points.  On failure, the bfd is  
         supposed to be restored to its initial state, which is  
         virtually impossible.  However, restoring a subset of the bfd  
         state works in practice.  This function stores the subset and  
         reinitializes the bfd.  
   
 */  
   
 boolean  
 bfd_preserve_save (abfd, preserve)  
      bfd *abfd;  
      struct bfd_preserve *preserve;  
 {  
   preserve->tdata = abfd->tdata.any;  
   preserve->arch_info = abfd->arch_info;  
   preserve->flags = abfd->flags;  
   preserve->sections = abfd->sections;  
   preserve->section_tail = abfd->section_tail;  
   preserve->section_count = abfd->section_count;  
   preserve->section_htab = abfd->section_htab;  
   
   if (! bfd_hash_table_init (&abfd->section_htab, bfd_section_hash_newfunc))  
     return false;  
   
   abfd->tdata.any = NULL;  
   abfd->arch_info = &bfd_default_arch_struct;  
   abfd->flags &= BFD_IN_MEMORY;  
   abfd->sections = NULL;  
   abfd->section_tail = &abfd->sections;  
   abfd->section_count = 0;  
   
   return true;  
 }  
   
 /*  
 FUNCTION  
         bfd_preserve_restore  
   
 SYNOPSIS  
         void bfd_preserve_restore (bfd *, struct bfd_preserve *);  
   
 DESCRIPTION  
         This function restores bfd state saved by bfd_preserve_save.  
         If MARKER is non-NULL in struct bfd_preserve then that block  
         and all subsequently bfd_alloc'd memory is freed.  
   
 */  
   
 void  
 bfd_preserve_restore (abfd, preserve)  
      bfd *abfd;  
      struct bfd_preserve *preserve;  
 {  
   bfd_hash_table_free (&abfd->section_htab);  
   
   abfd->tdata.any = preserve->tdata;  
   abfd->arch_info = preserve->arch_info;  
   abfd->flags = preserve->flags;  
   abfd->section_htab = preserve->section_htab;  
   abfd->sections = preserve->sections;  
   abfd->section_tail = preserve->section_tail;  
   abfd->section_count = preserve->section_count;  
   
   /* bfd_release frees all memory more recently bfd_alloc'd than  
      its arg, as well as its arg.  */  
   if (preserve->marker != NULL)  
     {  
       bfd_release (abfd, preserve->marker);  
       preserve->marker = NULL;  
     }  
 }  
   
 /*  
 FUNCTION  
         bfd_preserve_finish  
   
 SYNOPSIS  
         void bfd_preserve_finish (bfd *, struct bfd_preserve *);  
   
 DESCRIPTION  
         This function should be called when the bfd state saved by  
         bfd_preserve_save is no longer needed.  ie. when the back-end  
         object_p function returns with success.  
   
 */  
   
 void  
 bfd_preserve_finish (abfd, preserve)  
      bfd *abfd ATTRIBUTE_UNUSED;  
      struct bfd_preserve *preserve;  
 {  
   /* It would be nice to be able to free more memory here, eg. old  
      tdata, but that's not possible since these blocks are sitting  
      inside bfd_alloc'd memory.  The section hash is on a separate  
      objalloc.  */  
   bfd_hash_table_free (&preserve->section_htab);  
 }  
   
 #include "mach-o-reloc.c"  
   
2141  #define TARGET_NAME mach_o_be_vec  #define TARGET_NAME mach_o_be_vec
2142  #define TARGET_STRING "mach-o-be"  #define TARGET_STRING "mach-o-be"
2143  #define TARGET_BIG_ENDIAN 1  #define TARGET_BIG_ENDIAN 1

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

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