2009-01-14 Tristan Gingold <gingold@adacore.com>
[external/binutils.git] / gdb / machoread.c
1 /* Darwin support for GDB, the GNU debugger.
2    Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
3
4    Contributed by AdaCore.
5
6    This file is part of GDB.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include "defs.h"
23 #include "symtab.h"
24 #include "gdbtypes.h"
25 #include "bfd.h"
26 #include "symfile.h"
27 #include "objfiles.h"
28 #include "buildsym.h"
29 #include "gdbcmd.h"
30 #include "gdbcore.h"
31 #include "mach-o.h"
32 #include "gdb_assert.h"
33 #include "aout/stab_gnu.h"
34 #include "vec.h"
35
36 #include <string.h>
37
38 /* If non-zero displays debugging message.  */
39 static int mach_o_debug_level = 0;
40
41 static void
42 macho_new_init (struct objfile *objfile)
43 {
44 }
45
46 static void
47 macho_symfile_init (struct objfile *objfile)
48 {
49   objfile->flags |= OBJF_REORDERED;
50   init_entry_point_info (objfile);
51 }
52
53 /* Dwarf debugging information are never in the final executable.  They stay
54    in object files and the executable contains the list of object files read
55    during the link.
56    Each time an oso (other source) is found in the executable, the reader
57    creates such a structure.  They are read after the processing of the
58    executable.
59 */
60 typedef struct oso_el
61 {
62   /* Object file name.  */
63   const char *name;
64
65   /* Associated time stamp.  */
66   unsigned long mtime;
67
68   /* Number of sections.  This is the length of SYMBOLS and OFFSETS array.  */
69   int num_sections;
70
71   /* Each seaction of the object file is represented by a symbol and its
72      offset.  If the offset is 0, we assume that the symbol is at offset 0
73      in the OSO object file and a symbol lookup in the main file is
74      required to get the offset.  */
75   asymbol **symbols;
76   bfd_vma *offsets;
77 }
78 oso_el;
79
80 /* Vector of object files to be read after the executable.  */
81 DEF_VEC_O (oso_el);
82 static VEC (oso_el) *oso_vector;
83
84 /*  Add a new OSO to the vector.  */
85
86 static void
87 macho_add_oso (const asymbol *oso_sym, int nbr_sections,
88                asymbol **symbols, bfd_vma *offsets)
89 {
90   oso_el el;
91
92   el.name = oso_sym->name;
93   el.mtime = oso_sym->value;
94   el.num_sections = nbr_sections;
95   el.symbols = symbols;
96   el.offsets = offsets;
97   VEC_safe_push (oso_el, oso_vector, &el);
98 }
99
100 /* Build the minimal symbol table from SYMBOL_TABLE of length
101    NUMBER_OF_SYMBOLS for OBJFILE.
102    Read OSO files at the end.  */
103
104 static void
105 macho_symtab_read (struct objfile *objfile,
106                    long number_of_symbols, asymbol **symbol_table)
107 {
108   struct gdbarch *gdbarch = get_objfile_arch (objfile);
109   long storage_needed;
110   long i, j;
111   CORE_ADDR offset;
112   enum minimal_symbol_type ms_type;
113   unsigned int nbr_sections = bfd_count_sections (objfile->obfd);
114   asymbol **first_symbol = NULL;
115   bfd_vma *first_offset = NULL;
116   const asymbol *oso_file = NULL;
117
118   for (i = 0; i < number_of_symbols; i++)
119     {
120       asymbol *sym = symbol_table[i];
121       bfd_mach_o_asymbol *mach_o_sym = (bfd_mach_o_asymbol *)sym;
122
123       offset = ANOFFSET (objfile->section_offsets, sym->section->index);
124
125       if (sym->flags & BSF_DEBUGGING)
126         {
127           bfd_vma addr;
128
129           /* Debugging symbols are used to collect OSO file names as well
130              as section offsets.  */
131
132           switch (mach_o_sym->n_type)
133             {
134             case N_SO:
135               /* An empty SO entry terminates a chunk for an OSO file.  */
136               if ((sym->name == NULL || sym->name[0] == 0) && oso_file != NULL)
137                 {
138                   macho_add_oso (oso_file, nbr_sections,
139                                  first_symbol, first_offset);
140                   first_symbol = NULL;
141                   first_offset = NULL;
142                   oso_file = NULL;
143                 }
144               break;
145             case N_FUN:
146             case N_STSYM:
147               if (sym->name == NULL || sym->name[0] == '\0')
148                 break;
149               /* Fall through.  */
150             case N_BNSYM:
151               gdb_assert (oso_file != NULL);
152               addr = sym->value 
153                 + bfd_get_section_vma (sym->section->bfd, sym->section);
154               if (addr != 0
155                   && first_symbol[sym->section->index] == NULL)
156                 {
157                   /* These STAB entries can directly relocate a section.  */
158                   first_symbol[sym->section->index] = sym;
159                   first_offset[sym->section->index] = addr + offset;
160                 }
161               break;
162             case N_GSYM:
163               gdb_assert (oso_file != NULL);
164               if (first_symbol[sym->section->index] == NULL)
165                 {
166                   /* This STAB entry needs a symbol look-up to relocate
167                      the section.  */
168                   first_symbol[sym->section->index] = sym;
169                   first_offset[sym->section->index] = 0;
170                 }
171               break;
172             case N_OSO:
173               /* New OSO file.  */
174               gdb_assert (oso_file == NULL);
175               first_symbol = (asymbol **)xmalloc (nbr_sections
176                                                   * sizeof (asymbol *));
177               first_offset = (bfd_vma *)xmalloc (nbr_sections
178                                                  * sizeof (bfd_vma));
179               for (j = 0; j < nbr_sections; j++)
180                 first_symbol[j] = NULL;
181               oso_file = sym;
182               break;
183             }
184           continue;
185         }
186
187       if (sym->name == NULL || *sym->name == '\0')
188         {
189           /* Skip names that don't exist (shouldn't happen), or names
190              that are null strings (may happen). */
191           continue;
192         }
193
194       if (sym->flags & (BSF_GLOBAL | BSF_LOCAL | BSF_WEAK))
195         {
196           struct minimal_symbol *msym;
197           CORE_ADDR symaddr;
198
199           /* Bfd symbols are section relative. */
200           symaddr = sym->value + sym->section->vma;
201
202           /* Select global/local/weak symbols.  Note that bfd puts abs
203              symbols in their own section, so all symbols we are
204              interested in will have a section. */
205           /* Relocate all non-absolute and non-TLS symbols by the
206              section offset.  */
207           if (sym->section != &bfd_abs_section
208               && !(sym->section->flags & SEC_THREAD_LOCAL))
209             symaddr += offset;
210
211           if (sym->section == &bfd_abs_section)
212             ms_type = mst_abs;
213           else if (sym->section->flags & SEC_CODE)
214             {
215               if (sym->flags & (BSF_GLOBAL | BSF_WEAK))
216                 ms_type = mst_text;
217               else
218                 ms_type = mst_file_text;
219             }
220           else if (sym->section->flags & SEC_ALLOC)
221             {
222               if (sym->flags & (BSF_GLOBAL | BSF_WEAK))
223                 {
224                   if (sym->section->flags & SEC_LOAD)
225                     ms_type = mst_data;
226                   else
227                     ms_type = mst_bss;
228                 }
229               else if (sym->flags & BSF_LOCAL)
230                 {
231                   /* Not a special stabs-in-elf symbol, do regular
232                      symbol processing.  */
233                   if (sym->section->flags & SEC_LOAD)
234                     ms_type = mst_file_data;
235                   else
236                     ms_type = mst_file_bss;
237                 }
238               else
239                 ms_type = mst_unknown;
240             }
241           else
242             continue;   /* Skip this symbol. */
243
244           gdb_assert (sym->section->index < nbr_sections);
245           if (oso_file != NULL
246               && first_symbol[sym->section->index] == NULL)
247             {
248               /* Standard symbols can directly relocate sections.  */
249               first_symbol[sym->section->index] = sym;
250               first_offset[sym->section->index] = symaddr;
251             }
252
253           msym = prim_record_minimal_symbol_and_info
254             (sym->name, symaddr, ms_type, sym->section->index,
255              sym->section, objfile);
256         }
257     }
258
259   /* Just in case there is no trailing SO entry.  */
260   if (oso_file != NULL)
261     macho_add_oso (oso_file, nbr_sections, first_symbol, first_offset);
262 }
263
264 /* If NAME describes an archive member (ie: ARCHIVE '(' MEMBER ')'),
265    returns the length of the archive name.
266    Returns -1 otherwise.  */
267
268 static int
269 get_archive_prefix_len (const char *name)
270 {
271   char *lparen;
272   int name_len = strlen (name);
273
274   if (name_len == 0 || name[name_len - 1] != ')')
275     return -1;
276   
277   lparen = strrchr (name, '(');
278   if (lparen == NULL || lparen == name)
279     return -1;
280   return lparen - name;
281 }
282
283 static int
284 oso_el_compare_name (const void *vl, const void *vr)
285 {
286   const oso_el *l = (const oso_el *)vl;
287   const oso_el *r = (const oso_el *)vr;
288
289   return strcmp (l->name, r->name);
290 }
291
292 /* Add an oso file as a symbol file.  */
293
294 static void
295 macho_add_oso_symfile (oso_el *oso, bfd *abfd,
296                        struct objfile *main_objfile, int symfile_flags)
297 {
298   struct objfile *objfile;
299   struct section_addr_info *addrs;
300   int len;
301   int i;
302   char leading_char;
303
304   if (mach_o_debug_level > 0)
305     printf_unfiltered (_("Loading symbols from oso: %s\n"), oso->name);
306       
307   if (!bfd_check_format (abfd, bfd_object))
308     {
309       warning (_("`%s': can't read symbols: %s."), oso->name,
310                bfd_errmsg (bfd_get_error ()));
311       bfd_close (abfd);
312       return;
313     }
314
315   bfd_set_cacheable (abfd, 1);
316   
317   /* Compute addr length.  */
318   len = 0;
319   for (i = 0; i < oso->num_sections; i++)
320     if (oso->symbols[i] != NULL)
321       len++;
322   
323   addrs = alloc_section_addr_info (len);
324
325   leading_char = bfd_get_symbol_leading_char (main_objfile->obfd);
326
327   len = 0;
328   for (i = 0; i < oso->num_sections; i++)
329     if (oso->symbols[i] != NULL)
330       {
331         if (oso->offsets[i])
332           addrs->other[len].addr = oso->offsets[i];
333         else
334           {
335             struct minimal_symbol *msym;
336             const char *name = oso->symbols[i]->name;
337             
338             if (name[0] == leading_char)
339               ++name;
340
341             if (mach_o_debug_level > 3)
342               printf_unfiltered (_("resolve sect %s with %s\n"),
343                                  oso->symbols[i]->section->name,
344                                  oso->symbols[i]->name);
345             msym = lookup_minimal_symbol (name, NULL, main_objfile);
346             if (msym == NULL)
347               {
348                 warning (_("can't find symbol '%s' in minsymtab"),
349                          oso->symbols[i]->name);
350                 addrs->other[len].addr = 0;
351               }
352             else
353               addrs->other[len].addr = SYMBOL_VALUE_ADDRESS (msym);
354           }
355         addrs->other[len].name = (char *)oso->symbols[i]->section->name;
356         len++;
357       }
358       
359   if (mach_o_debug_level > 1)
360     {
361       int j;
362       for (j = 0; j < addrs->num_sections; j++)
363         printf_unfiltered (_("  %s: %s\n"),
364                            core_addr_to_string (addrs->other[j].addr),
365                            addrs->other[j].name);
366     }
367
368   /* Make sure that the filename was malloc'ed.  The current filename comes
369      either from an OSO symbol name or from an archive name.  Memory for both
370      is not managed by gdb.  */
371   abfd->filename = xstrdup (abfd->filename);
372
373   /* We need to clear SYMFILE_MAINLINE to avoid interractive question
374      from symfile.c:symbol_file_add_with_addrs_or_offsets.  */
375   objfile = symbol_file_add_from_bfd
376     (abfd, symfile_flags & ~SYMFILE_MAINLINE, addrs,
377      main_objfile->flags & (OBJF_REORDERED | OBJF_SHARED
378                             | OBJF_READNOW | OBJF_USERLOADED));
379   add_separate_debug_objfile (objfile, main_objfile);
380 }
381
382 /* Read symbols from the vector of oso files.  */
383
384 static void
385 macho_oso_symfile (struct objfile *main_objfile, int symfile_flags)
386 {
387   int ix;
388   VEC (oso_el) *vec;
389   oso_el *oso;
390
391   vec = oso_vector;
392   oso_vector = NULL;
393   
394   /* Sort oso by name so that files from libraries are gathered.  */
395   qsort (VEC_address (oso_el, vec), VEC_length (oso_el, vec),
396          sizeof (oso_el), oso_el_compare_name);
397
398   for (ix = 0; VEC_iterate (oso_el, vec, ix, oso);)
399     {
400       int pfx_len;
401       
402       /* Check if this is a library name.  */
403       pfx_len = get_archive_prefix_len (oso->name);
404       if (pfx_len > 0)
405         {
406           bfd *archive_bfd;
407           bfd *member_bfd;
408           char *archive_name = XNEWVEC (char, pfx_len + 1);
409           int last_ix;
410           oso_el *oso2;
411           int ix2;
412
413           memcpy (archive_name, oso->name, pfx_len);
414           archive_name[pfx_len] = '\0';
415
416           /* Compute number of oso for this archive.  */
417           for (last_ix = ix;
418                VEC_iterate (oso_el, vec, last_ix, oso2); last_ix++)
419             {
420               if (strncmp (oso2->name, archive_name, pfx_len) != 0)
421                 break;
422             }
423           
424           /* Open the archive and check the format.  */
425           archive_bfd = bfd_openr (archive_name, gnutarget);
426           if (archive_bfd == NULL)
427             {
428               warning (_("Could not open OSO archive file \"%s\""),
429                        archive_name);
430               ix = last_ix;
431               continue;
432             }
433           if (!bfd_check_format (archive_bfd, bfd_archive))
434             {
435               warning (_("OSO archive file \"%s\" not an archive."),
436                        archive_name);
437               bfd_close (archive_bfd);
438               ix = last_ix;
439               continue;
440             }
441           member_bfd = bfd_openr_next_archived_file (archive_bfd, NULL);
442           
443           if (member_bfd == NULL)
444             {
445               warning (_("Could not read archive members out of "
446                          "OSO archive \"%s\""), archive_name);
447               bfd_close (archive_bfd);
448               ix = last_ix;
449               continue;
450             }
451
452           /* Load all oso in this library.  */
453           while (member_bfd != NULL)
454             {
455               bfd *prev;
456               const char *member_name = member_bfd->filename;
457               int member_len = strlen (member_name);
458
459               /* If this member is referenced, add it as a symfile.  */
460               for (ix2 = ix; ix2 < last_ix; ix2++)
461                 {
462                   oso2 = VEC_index (oso_el, vec, ix2);
463
464                   if (oso2->name
465                       && strlen (oso2->name) == pfx_len + member_len + 2
466                       && !memcmp (member_name, oso2->name + pfx_len + 1,
467                                   member_len))
468                     {
469                       macho_add_oso_symfile (oso2, member_bfd,
470                                              main_objfile, symfile_flags);
471                       oso2->name = NULL;
472                       break;
473                     }
474                 }
475
476               prev = member_bfd;
477               member_bfd = bfd_openr_next_archived_file
478                 (archive_bfd, member_bfd);
479
480               /* Free previous member if not referenced by an oso.  */
481               if (ix2 >= last_ix)
482                 bfd_close (prev);
483             }
484           for (ix2 = ix; ix2 < last_ix; ix2++)
485             {
486               oso_el *oso2 = VEC_index (oso_el, vec, ix2);
487
488               if (oso2->name != NULL)
489                 warning (_("Could not find specified archive member "
490                            "for OSO name \"%s\""), oso->name);
491             }
492           ix = last_ix;
493         }
494       else
495         {
496           bfd *abfd;
497
498           abfd = bfd_openr (oso->name, gnutarget);
499           if (!abfd)
500             warning (_("`%s': can't open to read symbols: %s."), oso->name,
501                      bfd_errmsg (bfd_get_error ()));
502           else
503             macho_add_oso_symfile (oso, abfd, main_objfile, symfile_flags);
504
505           ix++;
506         }
507     }
508
509   for (ix = 0; VEC_iterate (oso_el, vec, ix, oso); ix++)
510     {
511       xfree (oso->symbols);
512       xfree (oso->offsets);
513     }
514   VEC_free (oso_el, vec);
515 }
516
517 /* DSYM (debug symbols) files contain the debug info of an executable.
518    This is a separate file created by dsymutil(1) and is similar to debug
519    link feature on ELF.
520    DSYM files are located in a subdirectory.  Append DSYM_SUFFIX to the
521    executable name and the executable base name to get the DSYM file name.  */
522 #define DSYM_SUFFIX ".dSYM/Contents/Resources/DWARF/"
523
524 /* Check if a dsym file exists for OBJFILE.  If so, returns a bfd for it.
525    Return NULL if no valid dsym file is found.  */
526
527 static bfd *
528 macho_check_dsym (struct objfile *objfile)
529 {
530   size_t name_len = strlen (objfile->name);
531   size_t dsym_len = strlen (DSYM_SUFFIX);
532   const char *base_name = lbasename (objfile->name);
533   size_t base_len = strlen (base_name);
534   char *dsym_filename = alloca (name_len + dsym_len + base_len + 1);
535   bfd *dsym_bfd;
536   bfd_mach_o_load_command *main_uuid;
537   bfd_mach_o_load_command *dsym_uuid;
538
539   strcpy (dsym_filename, objfile->name);
540   strcpy (dsym_filename + name_len, DSYM_SUFFIX);
541   strcpy (dsym_filename + name_len + dsym_len, base_name);
542
543   if (access (dsym_filename, R_OK) != 0)
544     return NULL;
545
546   if (bfd_mach_o_lookup_command (objfile->obfd,
547                                  BFD_MACH_O_LC_UUID, &main_uuid) == 0)
548     {
549       warning (_("can't find UUID in %s"), objfile->name);
550       return NULL;
551     }
552   dsym_filename = xstrdup (dsym_filename);
553   dsym_bfd = bfd_openr (dsym_filename, gnutarget);
554   if (dsym_bfd == NULL)
555     {
556       warning (_("can't open dsym file %s"), dsym_filename);
557       xfree (dsym_filename);
558       return NULL;
559     }
560
561   if (!bfd_check_format (dsym_bfd, bfd_object))
562     {
563       bfd_close (dsym_bfd);
564       warning (_("bad dsym file format: %s"), bfd_errmsg (bfd_get_error ()));
565       xfree (dsym_filename);
566       return NULL;
567     }
568
569   if (bfd_mach_o_lookup_command (dsym_bfd,
570                                  BFD_MACH_O_LC_UUID, &dsym_uuid) == 0)
571     {
572       warning (_("can't find UUID in %s"), dsym_filename);
573       bfd_close (dsym_bfd);
574       xfree (dsym_filename);
575       return NULL;
576     }
577   if (memcmp (dsym_uuid->command.uuid.uuid, main_uuid->command.uuid.uuid,
578               sizeof (main_uuid->command.uuid.uuid)))
579     {
580       warning (_("dsym file UUID doesn't match the one in %s"), objfile->name);
581       bfd_close (dsym_bfd);
582       xfree (dsym_filename);
583       return NULL;
584     }
585   return dsym_bfd;
586 }
587
588 static void
589 macho_symfile_read (struct objfile *objfile, int symfile_flags)
590 {
591   bfd *abfd = objfile->obfd;
592   struct cleanup *back_to;
593   CORE_ADDR offset;
594   long storage_needed;
595   bfd *dsym_bfd;
596
597   init_minimal_symbol_collection ();
598   back_to = make_cleanup_discard_minimal_symbols ();
599
600   /* Get symbols from the symbol table only if the file is an executable.
601      The symbol table of object files is not relocated and is expected to
602      be in the executable.  */
603   if (bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC))
604     {
605       /* Process the normal symbol table first.  */
606       storage_needed = bfd_get_symtab_upper_bound (objfile->obfd);
607       if (storage_needed < 0)
608         error (_("Can't read symbols from %s: %s"),
609                bfd_get_filename (objfile->obfd),
610                bfd_errmsg (bfd_get_error ()));
611
612       if (storage_needed > 0)
613         {
614           asymbol **symbol_table;
615           long symcount;
616
617           symbol_table = (asymbol **) xmalloc (storage_needed);
618           make_cleanup (xfree, symbol_table);
619           symcount = bfd_canonicalize_symtab (objfile->obfd, symbol_table);
620           
621           if (symcount < 0)
622             error (_("Can't read symbols from %s: %s"),
623                    bfd_get_filename (objfile->obfd),
624                    bfd_errmsg (bfd_get_error ()));
625           
626           macho_symtab_read (objfile, symcount, symbol_table);
627         }
628       
629       install_minimal_symbols (objfile);
630
631       /* Try to read .eh_frame / .debug_frame.  */
632       /* First, locate these sections.  We ignore the result status
633          as it only checks for debug info.  */
634       dwarf2_has_info (objfile);
635       dwarf2_build_frame_info (objfile);
636       
637       /* Check for DSYM file.  */
638       dsym_bfd = macho_check_dsym (objfile);
639       if (dsym_bfd != NULL)
640         {
641           int ix;
642           oso_el *oso;
643           struct bfd_section *asect, *dsect;
644
645           if (mach_o_debug_level > 0)
646             printf_unfiltered (_("dsym file found\n"));
647
648           /* Remove oso.  They won't be used.  */
649           for (ix = 0; VEC_iterate (oso_el, oso_vector, ix, oso); ix++)
650             {
651               xfree (oso->symbols);
652               xfree (oso->offsets);
653             }
654           VEC_free (oso_el, oso_vector);
655           oso_vector = NULL;
656
657           /* Set dsym section size.  */
658           for (asect = objfile->obfd->sections, dsect = dsym_bfd->sections;
659                asect && dsect;
660                asect = asect->next, dsect = dsect->next)
661             {
662               if (strcmp (asect->name, dsect->name) != 0)
663                 break;
664               bfd_set_section_size (dsym_bfd, dsect,
665                                     bfd_get_section_size (asect));
666             }
667
668           /* Add the dsym file as a separate file.  */
669           symbol_file_add_separate (dsym_bfd, symfile_flags, objfile);
670       
671           /* Don't try to read dwarf2 from main file or shared libraries.  */
672           return;
673         }
674     }
675
676   if (dwarf2_has_info (objfile))
677     {
678       /* DWARF 2 sections */
679       dwarf2_build_psymtabs (objfile);
680     }
681
682   /* Do not try to read .eh_frame/.debug_frame as they are not relocated
683      and dwarf2_build_frame_info cannot deal with unrelocated sections.  */
684
685   /* Then the oso.  */
686   if (oso_vector != NULL)
687     macho_oso_symfile (objfile, symfile_flags);
688 }
689
690 static void
691 macho_symfile_finish (struct objfile *objfile)
692 {
693 }
694
695 static void
696 macho_symfile_offsets (struct objfile *objfile,
697                        struct section_addr_info *addrs)
698 {
699   unsigned int i;
700   unsigned int num_sections;
701   struct obj_section *osect;
702
703   /* Allocate section_offsets.  */
704   objfile->num_sections = bfd_count_sections (objfile->obfd);
705   objfile->section_offsets = (struct section_offsets *)
706     obstack_alloc (&objfile->objfile_obstack,
707                    SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
708   memset (objfile->section_offsets, 0,
709           SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
710
711   /* This code is run when we first add the objfile with
712      symfile_add_with_addrs_or_offsets, when "addrs" not "offsets" are
713      passed in.  The place in symfile.c where the addrs are applied
714      depends on the addrs having section names.  But in the dyld code
715      we build an anonymous array of addrs, so that code is a no-op.
716      Because of that, we have to apply the addrs to the sections here.
717      N.B. if an objfile slides after we've already created it, then it
718      goes through objfile_relocate.  */
719
720   for (i = 0; i < addrs->num_sections; i++)
721     {
722       if (addrs->other[i].name == NULL)
723         continue;
724
725       ALL_OBJFILE_OSECTIONS (objfile, osect)
726         {
727           const char *bfd_sect_name = osect->the_bfd_section->name;
728
729           if (strcmp (bfd_sect_name, addrs->other[i].name) == 0)
730             {
731               obj_section_offset (osect) = addrs->other[i].addr;
732               break;
733             }
734         }
735     }
736
737   objfile->sect_index_text = 0;
738
739   ALL_OBJFILE_OSECTIONS (objfile, osect)
740     {
741       const char *bfd_sect_name = osect->the_bfd_section->name;
742       int sect_index = osect->the_bfd_section->index;
743       
744       if (strncmp (bfd_sect_name, "LC_SEGMENT.", 11) == 0)
745         bfd_sect_name += 11;
746       if (strcmp (bfd_sect_name, "__TEXT") == 0
747           || strcmp (bfd_sect_name, "__TEXT.__text") == 0)
748         objfile->sect_index_text = sect_index;
749     }
750 }
751
752 static struct sym_fns macho_sym_fns = {
753   bfd_target_mach_o_flavour,
754
755   macho_new_init,               /* sym_new_init: init anything gbl to entire symtab */
756   macho_symfile_init,           /* sym_init: read initial info, setup for sym_read() */
757   macho_symfile_read,           /* sym_read: read a symbol file into symtab */
758   macho_symfile_finish,         /* sym_finish: finished with file, cleanup */
759   macho_symfile_offsets,        /* sym_offsets:  xlate external to internal form */
760   default_symfile_segments,     /* sym_segments: Get segment information from
761                                    a file.  */
762   NULL                          /* next: pointer to next struct sym_fns */
763 };
764
765 void
766 _initialize_machoread ()
767 {
768   add_symtab_fns (&macho_sym_fns);
769
770   add_setshow_zinteger_cmd ("mach-o", class_obscure,
771                             &mach_o_debug_level, _("\
772 Set if printing Mach-O symbols processing."), _("\
773 Show if printing Mach-O symbols processing."), NULL,
774                             NULL, NULL,
775                             &setdebuglist, &showdebuglist);
776 }