1*ef5ccd6cSJohn Marino /* Darwin support for GDB, the GNU debugger.
2*ef5ccd6cSJohn Marino Copyright (C) 2008-2013 Free Software Foundation, Inc.
3*ef5ccd6cSJohn Marino
4*ef5ccd6cSJohn Marino Contributed by AdaCore.
5*ef5ccd6cSJohn Marino
6*ef5ccd6cSJohn Marino This file is part of GDB.
7*ef5ccd6cSJohn Marino
8*ef5ccd6cSJohn Marino This program is free software; you can redistribute it and/or modify
9*ef5ccd6cSJohn Marino it under the terms of the GNU General Public License as published by
10*ef5ccd6cSJohn Marino the Free Software Foundation; either version 3 of the License, or
11*ef5ccd6cSJohn Marino (at your option) any later version.
12*ef5ccd6cSJohn Marino
13*ef5ccd6cSJohn Marino This program is distributed in the hope that it will be useful,
14*ef5ccd6cSJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
15*ef5ccd6cSJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16*ef5ccd6cSJohn Marino GNU General Public License for more details.
17*ef5ccd6cSJohn Marino
18*ef5ccd6cSJohn Marino You should have received a copy of the GNU General Public License
19*ef5ccd6cSJohn Marino along with this program. If not, see <http://www.gnu.org/licenses/>.
20*ef5ccd6cSJohn Marino */
21*ef5ccd6cSJohn Marino
22*ef5ccd6cSJohn Marino #include "defs.h"
23*ef5ccd6cSJohn Marino #include "symtab.h"
24*ef5ccd6cSJohn Marino #include "gdbtypes.h"
25*ef5ccd6cSJohn Marino #include "bfd.h"
26*ef5ccd6cSJohn Marino #include "symfile.h"
27*ef5ccd6cSJohn Marino #include "objfiles.h"
28*ef5ccd6cSJohn Marino #include "buildsym.h"
29*ef5ccd6cSJohn Marino #include "gdbcmd.h"
30*ef5ccd6cSJohn Marino #include "gdbcore.h"
31*ef5ccd6cSJohn Marino #include "mach-o.h"
32*ef5ccd6cSJohn Marino #include "gdb_assert.h"
33*ef5ccd6cSJohn Marino #include "aout/stab_gnu.h"
34*ef5ccd6cSJohn Marino #include "vec.h"
35*ef5ccd6cSJohn Marino #include "psympriv.h"
36*ef5ccd6cSJohn Marino #include "complaints.h"
37*ef5ccd6cSJohn Marino #include "gdb_bfd.h"
38*ef5ccd6cSJohn Marino
39*ef5ccd6cSJohn Marino #include <string.h>
40*ef5ccd6cSJohn Marino
41*ef5ccd6cSJohn Marino /* If non-zero displays debugging message. */
42*ef5ccd6cSJohn Marino static unsigned int mach_o_debug_level = 0;
43*ef5ccd6cSJohn Marino
44*ef5ccd6cSJohn Marino /* Dwarf debugging information are never in the final executable. They stay
45*ef5ccd6cSJohn Marino in object files and the executable contains the list of object files read
46*ef5ccd6cSJohn Marino during the link.
47*ef5ccd6cSJohn Marino Each time an oso (other source) is found in the executable, the reader
48*ef5ccd6cSJohn Marino creates such a structure. They are read after the processing of the
49*ef5ccd6cSJohn Marino executable. */
50*ef5ccd6cSJohn Marino
51*ef5ccd6cSJohn Marino typedef struct oso_el
52*ef5ccd6cSJohn Marino {
53*ef5ccd6cSJohn Marino /* Object file name. Can also be a member name. */
54*ef5ccd6cSJohn Marino const char *name;
55*ef5ccd6cSJohn Marino
56*ef5ccd6cSJohn Marino /* Associated time stamp. */
57*ef5ccd6cSJohn Marino unsigned long mtime;
58*ef5ccd6cSJohn Marino
59*ef5ccd6cSJohn Marino /* Stab symbols range for this OSO. */
60*ef5ccd6cSJohn Marino asymbol **oso_sym;
61*ef5ccd6cSJohn Marino asymbol **end_sym;
62*ef5ccd6cSJohn Marino
63*ef5ccd6cSJohn Marino /* Number of interesting stabs in the range. */
64*ef5ccd6cSJohn Marino unsigned int nbr_syms;
65*ef5ccd6cSJohn Marino }
66*ef5ccd6cSJohn Marino oso_el;
67*ef5ccd6cSJohn Marino
68*ef5ccd6cSJohn Marino /* Vector of object files to be read after the executable. This is one
69*ef5ccd6cSJohn Marino global variable but it's life-time is the one of macho_symfile_read. */
70*ef5ccd6cSJohn Marino DEF_VEC_O (oso_el);
VEC(oso_el)71*ef5ccd6cSJohn Marino static VEC (oso_el) *oso_vector;
72*ef5ccd6cSJohn Marino
73*ef5ccd6cSJohn Marino static void
74*ef5ccd6cSJohn Marino macho_new_init (struct objfile *objfile)
75*ef5ccd6cSJohn Marino {
76*ef5ccd6cSJohn Marino }
77*ef5ccd6cSJohn Marino
78*ef5ccd6cSJohn Marino static void
macho_symfile_init(struct objfile * objfile)79*ef5ccd6cSJohn Marino macho_symfile_init (struct objfile *objfile)
80*ef5ccd6cSJohn Marino {
81*ef5ccd6cSJohn Marino objfile->flags |= OBJF_REORDERED;
82*ef5ccd6cSJohn Marino }
83*ef5ccd6cSJohn Marino
84*ef5ccd6cSJohn Marino /* Add a new OSO to the vector of OSO to load. */
85*ef5ccd6cSJohn Marino
86*ef5ccd6cSJohn Marino static void
macho_register_oso(struct objfile * objfile,asymbol ** oso_sym,asymbol ** end_sym,unsigned int nbr_syms)87*ef5ccd6cSJohn Marino macho_register_oso (struct objfile *objfile,
88*ef5ccd6cSJohn Marino asymbol **oso_sym, asymbol **end_sym,
89*ef5ccd6cSJohn Marino unsigned int nbr_syms)
90*ef5ccd6cSJohn Marino {
91*ef5ccd6cSJohn Marino oso_el el;
92*ef5ccd6cSJohn Marino
93*ef5ccd6cSJohn Marino el.name = (*oso_sym)->name;
94*ef5ccd6cSJohn Marino el.mtime = (*oso_sym)->value;
95*ef5ccd6cSJohn Marino el.oso_sym = oso_sym;
96*ef5ccd6cSJohn Marino el.end_sym = end_sym;
97*ef5ccd6cSJohn Marino el.nbr_syms = nbr_syms;
98*ef5ccd6cSJohn Marino VEC_safe_push (oso_el, oso_vector, &el);
99*ef5ccd6cSJohn Marino }
100*ef5ccd6cSJohn Marino
101*ef5ccd6cSJohn Marino /* Add symbol SYM to the minimal symbol table of OBJFILE. */
102*ef5ccd6cSJohn Marino
103*ef5ccd6cSJohn Marino static void
macho_symtab_add_minsym(struct objfile * objfile,const asymbol * sym)104*ef5ccd6cSJohn Marino macho_symtab_add_minsym (struct objfile *objfile, const asymbol *sym)
105*ef5ccd6cSJohn Marino {
106*ef5ccd6cSJohn Marino if (sym->name == NULL || *sym->name == '\0')
107*ef5ccd6cSJohn Marino {
108*ef5ccd6cSJohn Marino /* Skip names that don't exist (shouldn't happen), or names
109*ef5ccd6cSJohn Marino that are null strings (may happen). */
110*ef5ccd6cSJohn Marino return;
111*ef5ccd6cSJohn Marino }
112*ef5ccd6cSJohn Marino
113*ef5ccd6cSJohn Marino if (sym->flags & (BSF_GLOBAL | BSF_LOCAL | BSF_WEAK))
114*ef5ccd6cSJohn Marino {
115*ef5ccd6cSJohn Marino CORE_ADDR symaddr;
116*ef5ccd6cSJohn Marino CORE_ADDR offset;
117*ef5ccd6cSJohn Marino enum minimal_symbol_type ms_type;
118*ef5ccd6cSJohn Marino
119*ef5ccd6cSJohn Marino offset = ANOFFSET (objfile->section_offsets, sym->section->index);
120*ef5ccd6cSJohn Marino
121*ef5ccd6cSJohn Marino /* Bfd symbols are section relative. */
122*ef5ccd6cSJohn Marino symaddr = sym->value + sym->section->vma;
123*ef5ccd6cSJohn Marino
124*ef5ccd6cSJohn Marino /* Select global/local/weak symbols. Note that bfd puts abs
125*ef5ccd6cSJohn Marino symbols in their own section, so all symbols we are
126*ef5ccd6cSJohn Marino interested in will have a section. */
127*ef5ccd6cSJohn Marino /* Relocate all non-absolute and non-TLS symbols by the
128*ef5ccd6cSJohn Marino section offset. */
129*ef5ccd6cSJohn Marino if (sym->section != bfd_abs_section_ptr
130*ef5ccd6cSJohn Marino && !(sym->section->flags & SEC_THREAD_LOCAL))
131*ef5ccd6cSJohn Marino symaddr += offset;
132*ef5ccd6cSJohn Marino
133*ef5ccd6cSJohn Marino if (sym->section == bfd_abs_section_ptr)
134*ef5ccd6cSJohn Marino ms_type = mst_abs;
135*ef5ccd6cSJohn Marino else if (sym->section->flags & SEC_CODE)
136*ef5ccd6cSJohn Marino {
137*ef5ccd6cSJohn Marino if (sym->flags & (BSF_GLOBAL | BSF_WEAK))
138*ef5ccd6cSJohn Marino ms_type = mst_text;
139*ef5ccd6cSJohn Marino else
140*ef5ccd6cSJohn Marino ms_type = mst_file_text;
141*ef5ccd6cSJohn Marino }
142*ef5ccd6cSJohn Marino else if (sym->section->flags & SEC_ALLOC)
143*ef5ccd6cSJohn Marino {
144*ef5ccd6cSJohn Marino if (sym->flags & (BSF_GLOBAL | BSF_WEAK))
145*ef5ccd6cSJohn Marino {
146*ef5ccd6cSJohn Marino if (sym->section->flags & SEC_LOAD)
147*ef5ccd6cSJohn Marino ms_type = mst_data;
148*ef5ccd6cSJohn Marino else
149*ef5ccd6cSJohn Marino ms_type = mst_bss;
150*ef5ccd6cSJohn Marino }
151*ef5ccd6cSJohn Marino else if (sym->flags & BSF_LOCAL)
152*ef5ccd6cSJohn Marino {
153*ef5ccd6cSJohn Marino /* Not a special stabs-in-elf symbol, do regular
154*ef5ccd6cSJohn Marino symbol processing. */
155*ef5ccd6cSJohn Marino if (sym->section->flags & SEC_LOAD)
156*ef5ccd6cSJohn Marino ms_type = mst_file_data;
157*ef5ccd6cSJohn Marino else
158*ef5ccd6cSJohn Marino ms_type = mst_file_bss;
159*ef5ccd6cSJohn Marino }
160*ef5ccd6cSJohn Marino else
161*ef5ccd6cSJohn Marino ms_type = mst_unknown;
162*ef5ccd6cSJohn Marino }
163*ef5ccd6cSJohn Marino else
164*ef5ccd6cSJohn Marino return; /* Skip this symbol. */
165*ef5ccd6cSJohn Marino
166*ef5ccd6cSJohn Marino prim_record_minimal_symbol_and_info
167*ef5ccd6cSJohn Marino (sym->name, symaddr, ms_type, sym->section->index,
168*ef5ccd6cSJohn Marino sym->section, objfile);
169*ef5ccd6cSJohn Marino }
170*ef5ccd6cSJohn Marino }
171*ef5ccd6cSJohn Marino
172*ef5ccd6cSJohn Marino /* Build the minimal symbol table from SYMBOL_TABLE of length
173*ef5ccd6cSJohn Marino NUMBER_OF_SYMBOLS for OBJFILE. Registers OSO filenames found. */
174*ef5ccd6cSJohn Marino
175*ef5ccd6cSJohn Marino static void
macho_symtab_read(struct objfile * objfile,long number_of_symbols,asymbol ** symbol_table)176*ef5ccd6cSJohn Marino macho_symtab_read (struct objfile *objfile,
177*ef5ccd6cSJohn Marino long number_of_symbols, asymbol **symbol_table)
178*ef5ccd6cSJohn Marino {
179*ef5ccd6cSJohn Marino long i;
180*ef5ccd6cSJohn Marino const asymbol *dir_so = NULL;
181*ef5ccd6cSJohn Marino const asymbol *file_so = NULL;
182*ef5ccd6cSJohn Marino asymbol **oso_file = NULL;
183*ef5ccd6cSJohn Marino unsigned int nbr_syms = 0;
184*ef5ccd6cSJohn Marino
185*ef5ccd6cSJohn Marino /* Current state while reading stabs. */
186*ef5ccd6cSJohn Marino enum
187*ef5ccd6cSJohn Marino {
188*ef5ccd6cSJohn Marino /* Not within an SO part. Only non-debugging symbols should be present,
189*ef5ccd6cSJohn Marino and will be added to the minimal symbols table. */
190*ef5ccd6cSJohn Marino S_NO_SO,
191*ef5ccd6cSJohn Marino
192*ef5ccd6cSJohn Marino /* First SO read. Introduce an SO section, and may be followed by a second
193*ef5ccd6cSJohn Marino SO. The SO section should contain onl debugging symbols. */
194*ef5ccd6cSJohn Marino S_FIRST_SO,
195*ef5ccd6cSJohn Marino
196*ef5ccd6cSJohn Marino /* Second non-null SO found, just after the first one. Means that the first
197*ef5ccd6cSJohn Marino is in fact a directory name. */
198*ef5ccd6cSJohn Marino S_SECOND_SO,
199*ef5ccd6cSJohn Marino
200*ef5ccd6cSJohn Marino /* Non-null OSO found. Debugging info are DWARF in this OSO file. */
201*ef5ccd6cSJohn Marino S_DWARF_FILE,
202*ef5ccd6cSJohn Marino
203*ef5ccd6cSJohn Marino S_STAB_FILE
204*ef5ccd6cSJohn Marino } state = S_NO_SO;
205*ef5ccd6cSJohn Marino
206*ef5ccd6cSJohn Marino for (i = 0; i < number_of_symbols; i++)
207*ef5ccd6cSJohn Marino {
208*ef5ccd6cSJohn Marino const asymbol *sym = symbol_table[i];
209*ef5ccd6cSJohn Marino bfd_mach_o_asymbol *mach_o_sym = (bfd_mach_o_asymbol *)sym;
210*ef5ccd6cSJohn Marino
211*ef5ccd6cSJohn Marino switch (state)
212*ef5ccd6cSJohn Marino {
213*ef5ccd6cSJohn Marino case S_NO_SO:
214*ef5ccd6cSJohn Marino if (mach_o_sym->n_type == N_SO)
215*ef5ccd6cSJohn Marino {
216*ef5ccd6cSJohn Marino /* Start of object stab. */
217*ef5ccd6cSJohn Marino if (sym->name == NULL || sym->name[0] == 0)
218*ef5ccd6cSJohn Marino {
219*ef5ccd6cSJohn Marino /* Unexpected empty N_SO. */
220*ef5ccd6cSJohn Marino complaint (&symfile_complaints,
221*ef5ccd6cSJohn Marino _("Unexpected empty N_SO stab"));
222*ef5ccd6cSJohn Marino }
223*ef5ccd6cSJohn Marino else
224*ef5ccd6cSJohn Marino {
225*ef5ccd6cSJohn Marino file_so = sym;
226*ef5ccd6cSJohn Marino dir_so = NULL;
227*ef5ccd6cSJohn Marino state = S_FIRST_SO;
228*ef5ccd6cSJohn Marino }
229*ef5ccd6cSJohn Marino }
230*ef5ccd6cSJohn Marino else if (sym->flags & BSF_DEBUGGING)
231*ef5ccd6cSJohn Marino {
232*ef5ccd6cSJohn Marino if (mach_o_sym->n_type == N_OPT)
233*ef5ccd6cSJohn Marino {
234*ef5ccd6cSJohn Marino /* No complaint for OPT. */
235*ef5ccd6cSJohn Marino break;
236*ef5ccd6cSJohn Marino }
237*ef5ccd6cSJohn Marino
238*ef5ccd6cSJohn Marino /* Debugging symbols are not expected here. */
239*ef5ccd6cSJohn Marino complaint (&symfile_complaints,
240*ef5ccd6cSJohn Marino _("%s: Unexpected debug stab outside SO markers"),
241*ef5ccd6cSJohn Marino objfile->name);
242*ef5ccd6cSJohn Marino }
243*ef5ccd6cSJohn Marino else
244*ef5ccd6cSJohn Marino {
245*ef5ccd6cSJohn Marino /* Non-debugging symbols go to the minimal symbol table. */
246*ef5ccd6cSJohn Marino macho_symtab_add_minsym (objfile, sym);
247*ef5ccd6cSJohn Marino }
248*ef5ccd6cSJohn Marino break;
249*ef5ccd6cSJohn Marino
250*ef5ccd6cSJohn Marino case S_FIRST_SO:
251*ef5ccd6cSJohn Marino case S_SECOND_SO:
252*ef5ccd6cSJohn Marino if (mach_o_sym->n_type == N_SO)
253*ef5ccd6cSJohn Marino {
254*ef5ccd6cSJohn Marino if (sym->name == NULL || sym->name[0] == 0)
255*ef5ccd6cSJohn Marino {
256*ef5ccd6cSJohn Marino /* Unexpected empty N_SO. */
257*ef5ccd6cSJohn Marino complaint (&symfile_complaints, _("Empty SO section"));
258*ef5ccd6cSJohn Marino state = S_NO_SO;
259*ef5ccd6cSJohn Marino }
260*ef5ccd6cSJohn Marino else if (state == S_FIRST_SO)
261*ef5ccd6cSJohn Marino {
262*ef5ccd6cSJohn Marino /* Second SO stab for the file name. */
263*ef5ccd6cSJohn Marino dir_so = file_so;
264*ef5ccd6cSJohn Marino file_so = sym;
265*ef5ccd6cSJohn Marino state = S_SECOND_SO;
266*ef5ccd6cSJohn Marino }
267*ef5ccd6cSJohn Marino else
268*ef5ccd6cSJohn Marino complaint (&symfile_complaints, _("Three SO in a raw"));
269*ef5ccd6cSJohn Marino }
270*ef5ccd6cSJohn Marino else if (mach_o_sym->n_type == N_OSO)
271*ef5ccd6cSJohn Marino {
272*ef5ccd6cSJohn Marino if (sym->name == NULL || sym->name[0] == 0)
273*ef5ccd6cSJohn Marino {
274*ef5ccd6cSJohn Marino /* Empty OSO. Means that this file was compiled with
275*ef5ccd6cSJohn Marino stabs. */
276*ef5ccd6cSJohn Marino state = S_STAB_FILE;
277*ef5ccd6cSJohn Marino warning (_("stabs debugging not supported for %s"),
278*ef5ccd6cSJohn Marino file_so->name);
279*ef5ccd6cSJohn Marino }
280*ef5ccd6cSJohn Marino else
281*ef5ccd6cSJohn Marino {
282*ef5ccd6cSJohn Marino /* Non-empty OSO for a Dwarf file. */
283*ef5ccd6cSJohn Marino oso_file = symbol_table + i;
284*ef5ccd6cSJohn Marino nbr_syms = 0;
285*ef5ccd6cSJohn Marino state = S_DWARF_FILE;
286*ef5ccd6cSJohn Marino }
287*ef5ccd6cSJohn Marino }
288*ef5ccd6cSJohn Marino else
289*ef5ccd6cSJohn Marino complaint (&symfile_complaints,
290*ef5ccd6cSJohn Marino _("Unexpected stab after SO"));
291*ef5ccd6cSJohn Marino break;
292*ef5ccd6cSJohn Marino
293*ef5ccd6cSJohn Marino case S_STAB_FILE:
294*ef5ccd6cSJohn Marino case S_DWARF_FILE:
295*ef5ccd6cSJohn Marino if (mach_o_sym->n_type == N_SO)
296*ef5ccd6cSJohn Marino {
297*ef5ccd6cSJohn Marino if (sym->name == NULL || sym->name[0] == 0)
298*ef5ccd6cSJohn Marino {
299*ef5ccd6cSJohn Marino /* End of file. */
300*ef5ccd6cSJohn Marino if (state == S_DWARF_FILE)
301*ef5ccd6cSJohn Marino macho_register_oso (objfile, oso_file, symbol_table + i,
302*ef5ccd6cSJohn Marino nbr_syms);
303*ef5ccd6cSJohn Marino state = S_NO_SO;
304*ef5ccd6cSJohn Marino }
305*ef5ccd6cSJohn Marino else
306*ef5ccd6cSJohn Marino {
307*ef5ccd6cSJohn Marino complaint (&symfile_complaints, _("Missing nul SO"));
308*ef5ccd6cSJohn Marino file_so = sym;
309*ef5ccd6cSJohn Marino dir_so = NULL;
310*ef5ccd6cSJohn Marino state = S_FIRST_SO;
311*ef5ccd6cSJohn Marino }
312*ef5ccd6cSJohn Marino }
313*ef5ccd6cSJohn Marino else if (sym->flags & BSF_DEBUGGING)
314*ef5ccd6cSJohn Marino {
315*ef5ccd6cSJohn Marino if (state == S_STAB_FILE)
316*ef5ccd6cSJohn Marino {
317*ef5ccd6cSJohn Marino /* FIXME: to be implemented. */
318*ef5ccd6cSJohn Marino }
319*ef5ccd6cSJohn Marino else
320*ef5ccd6cSJohn Marino {
321*ef5ccd6cSJohn Marino switch (mach_o_sym->n_type)
322*ef5ccd6cSJohn Marino {
323*ef5ccd6cSJohn Marino case N_FUN:
324*ef5ccd6cSJohn Marino if (sym->name == NULL || sym->name[0] == 0)
325*ef5ccd6cSJohn Marino break;
326*ef5ccd6cSJohn Marino /* Fall through. */
327*ef5ccd6cSJohn Marino case N_STSYM:
328*ef5ccd6cSJohn Marino /* Interesting symbol. */
329*ef5ccd6cSJohn Marino nbr_syms++;
330*ef5ccd6cSJohn Marino break;
331*ef5ccd6cSJohn Marino case N_ENSYM:
332*ef5ccd6cSJohn Marino case N_BNSYM:
333*ef5ccd6cSJohn Marino case N_GSYM:
334*ef5ccd6cSJohn Marino break;
335*ef5ccd6cSJohn Marino default:
336*ef5ccd6cSJohn Marino complaint (&symfile_complaints,
337*ef5ccd6cSJohn Marino _("unhandled stab for dwarf OSO file"));
338*ef5ccd6cSJohn Marino break;
339*ef5ccd6cSJohn Marino }
340*ef5ccd6cSJohn Marino }
341*ef5ccd6cSJohn Marino }
342*ef5ccd6cSJohn Marino else
343*ef5ccd6cSJohn Marino complaint (&symfile_complaints,
344*ef5ccd6cSJohn Marino _("non-debugging symbol within SO"));
345*ef5ccd6cSJohn Marino break;
346*ef5ccd6cSJohn Marino }
347*ef5ccd6cSJohn Marino }
348*ef5ccd6cSJohn Marino
349*ef5ccd6cSJohn Marino if (state != S_NO_SO)
350*ef5ccd6cSJohn Marino complaint (&symfile_complaints, _("missing nul SO"));
351*ef5ccd6cSJohn Marino }
352*ef5ccd6cSJohn Marino
353*ef5ccd6cSJohn Marino /* If NAME describes an archive member (ie: ARCHIVE '(' MEMBER ')'),
354*ef5ccd6cSJohn Marino returns the length of the archive name.
355*ef5ccd6cSJohn Marino Returns -1 otherwise. */
356*ef5ccd6cSJohn Marino
357*ef5ccd6cSJohn Marino static int
get_archive_prefix_len(const char * name)358*ef5ccd6cSJohn Marino get_archive_prefix_len (const char *name)
359*ef5ccd6cSJohn Marino {
360*ef5ccd6cSJohn Marino char *lparen;
361*ef5ccd6cSJohn Marino int name_len = strlen (name);
362*ef5ccd6cSJohn Marino
363*ef5ccd6cSJohn Marino if (name_len == 0 || name[name_len - 1] != ')')
364*ef5ccd6cSJohn Marino return -1;
365*ef5ccd6cSJohn Marino
366*ef5ccd6cSJohn Marino lparen = strrchr (name, '(');
367*ef5ccd6cSJohn Marino if (lparen == NULL || lparen == name)
368*ef5ccd6cSJohn Marino return -1;
369*ef5ccd6cSJohn Marino return lparen - name;
370*ef5ccd6cSJohn Marino }
371*ef5ccd6cSJohn Marino
372*ef5ccd6cSJohn Marino /* Compare function to qsort OSOs, so that members of a library are
373*ef5ccd6cSJohn Marino gathered. */
374*ef5ccd6cSJohn Marino
375*ef5ccd6cSJohn Marino static int
oso_el_compare_name(const void * vl,const void * vr)376*ef5ccd6cSJohn Marino oso_el_compare_name (const void *vl, const void *vr)
377*ef5ccd6cSJohn Marino {
378*ef5ccd6cSJohn Marino const oso_el *l = (const oso_el *)vl;
379*ef5ccd6cSJohn Marino const oso_el *r = (const oso_el *)vr;
380*ef5ccd6cSJohn Marino
381*ef5ccd6cSJohn Marino return strcmp (l->name, r->name);
382*ef5ccd6cSJohn Marino }
383*ef5ccd6cSJohn Marino
384*ef5ccd6cSJohn Marino /* Hash table entry structure for the stabs symbols in the main object file.
385*ef5ccd6cSJohn Marino This is used to speed up lookup for symbols in the OSO. */
386*ef5ccd6cSJohn Marino
387*ef5ccd6cSJohn Marino struct macho_sym_hash_entry
388*ef5ccd6cSJohn Marino {
389*ef5ccd6cSJohn Marino struct bfd_hash_entry base;
390*ef5ccd6cSJohn Marino const asymbol *sym;
391*ef5ccd6cSJohn Marino };
392*ef5ccd6cSJohn Marino
393*ef5ccd6cSJohn Marino /* Routine to create an entry in the hash table. */
394*ef5ccd6cSJohn Marino
395*ef5ccd6cSJohn Marino static struct bfd_hash_entry *
macho_sym_hash_newfunc(struct bfd_hash_entry * entry,struct bfd_hash_table * table,const char * string)396*ef5ccd6cSJohn Marino macho_sym_hash_newfunc (struct bfd_hash_entry *entry,
397*ef5ccd6cSJohn Marino struct bfd_hash_table *table,
398*ef5ccd6cSJohn Marino const char *string)
399*ef5ccd6cSJohn Marino {
400*ef5ccd6cSJohn Marino struct macho_sym_hash_entry *ret = (struct macho_sym_hash_entry *) entry;
401*ef5ccd6cSJohn Marino
402*ef5ccd6cSJohn Marino /* Allocate the structure if it has not already been allocated by a
403*ef5ccd6cSJohn Marino subclass. */
404*ef5ccd6cSJohn Marino if (ret == NULL)
405*ef5ccd6cSJohn Marino ret = (struct macho_sym_hash_entry *) bfd_hash_allocate (table,
406*ef5ccd6cSJohn Marino sizeof (* ret));
407*ef5ccd6cSJohn Marino if (ret == NULL)
408*ef5ccd6cSJohn Marino return NULL;
409*ef5ccd6cSJohn Marino
410*ef5ccd6cSJohn Marino /* Call the allocation method of the superclass. */
411*ef5ccd6cSJohn Marino ret = (struct macho_sym_hash_entry *)
412*ef5ccd6cSJohn Marino bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string);
413*ef5ccd6cSJohn Marino
414*ef5ccd6cSJohn Marino if (ret)
415*ef5ccd6cSJohn Marino {
416*ef5ccd6cSJohn Marino /* Initialize the local fields. */
417*ef5ccd6cSJohn Marino ret->sym = NULL;
418*ef5ccd6cSJohn Marino }
419*ef5ccd6cSJohn Marino
420*ef5ccd6cSJohn Marino return (struct bfd_hash_entry *) ret;
421*ef5ccd6cSJohn Marino }
422*ef5ccd6cSJohn Marino
423*ef5ccd6cSJohn Marino /* Get the value of SYM from the minimal symtab of MAIN_OBJFILE. This is used
424*ef5ccd6cSJohn Marino to get the value of global and common symbols. */
425*ef5ccd6cSJohn Marino
426*ef5ccd6cSJohn Marino static CORE_ADDR
macho_resolve_oso_sym_with_minsym(struct objfile * main_objfile,asymbol * sym)427*ef5ccd6cSJohn Marino macho_resolve_oso_sym_with_minsym (struct objfile *main_objfile, asymbol *sym)
428*ef5ccd6cSJohn Marino {
429*ef5ccd6cSJohn Marino /* For common symbol and global symbols, use the min symtab. */
430*ef5ccd6cSJohn Marino struct minimal_symbol *msym;
431*ef5ccd6cSJohn Marino const char *name = sym->name;
432*ef5ccd6cSJohn Marino
433*ef5ccd6cSJohn Marino if (name[0] == bfd_get_symbol_leading_char (main_objfile->obfd))
434*ef5ccd6cSJohn Marino ++name;
435*ef5ccd6cSJohn Marino msym = lookup_minimal_symbol (name, NULL, main_objfile);
436*ef5ccd6cSJohn Marino if (msym == NULL)
437*ef5ccd6cSJohn Marino {
438*ef5ccd6cSJohn Marino warning (_("can't find symbol '%s' in minsymtab"), name);
439*ef5ccd6cSJohn Marino return 0;
440*ef5ccd6cSJohn Marino }
441*ef5ccd6cSJohn Marino else
442*ef5ccd6cSJohn Marino return SYMBOL_VALUE_ADDRESS (msym);
443*ef5ccd6cSJohn Marino }
444*ef5ccd6cSJohn Marino
445*ef5ccd6cSJohn Marino /* Add oso file OSO/ABFD as a symbol file. */
446*ef5ccd6cSJohn Marino
447*ef5ccd6cSJohn Marino static void
macho_add_oso_symfile(oso_el * oso,bfd * abfd,struct objfile * main_objfile,int symfile_flags)448*ef5ccd6cSJohn Marino macho_add_oso_symfile (oso_el *oso, bfd *abfd,
449*ef5ccd6cSJohn Marino struct objfile *main_objfile, int symfile_flags)
450*ef5ccd6cSJohn Marino {
451*ef5ccd6cSJohn Marino int storage;
452*ef5ccd6cSJohn Marino int i;
453*ef5ccd6cSJohn Marino asymbol **symbol_table;
454*ef5ccd6cSJohn Marino asymbol **symp;
455*ef5ccd6cSJohn Marino struct bfd_hash_table table;
456*ef5ccd6cSJohn Marino int nbr_sections;
457*ef5ccd6cSJohn Marino struct cleanup *cleanup;
458*ef5ccd6cSJohn Marino
459*ef5ccd6cSJohn Marino /* Per section flag to mark which section have been rebased. */
460*ef5ccd6cSJohn Marino unsigned char *sections_rebased;
461*ef5ccd6cSJohn Marino
462*ef5ccd6cSJohn Marino if (mach_o_debug_level > 0)
463*ef5ccd6cSJohn Marino printf_unfiltered
464*ef5ccd6cSJohn Marino (_("Loading debugging symbols from oso: %s\n"), oso->name);
465*ef5ccd6cSJohn Marino
466*ef5ccd6cSJohn Marino if (!bfd_check_format (abfd, bfd_object))
467*ef5ccd6cSJohn Marino {
468*ef5ccd6cSJohn Marino warning (_("`%s': can't read symbols: %s."), oso->name,
469*ef5ccd6cSJohn Marino bfd_errmsg (bfd_get_error ()));
470*ef5ccd6cSJohn Marino gdb_bfd_unref (abfd);
471*ef5ccd6cSJohn Marino return;
472*ef5ccd6cSJohn Marino }
473*ef5ccd6cSJohn Marino
474*ef5ccd6cSJohn Marino if (abfd->my_archive == NULL && oso->mtime != bfd_get_mtime (abfd))
475*ef5ccd6cSJohn Marino {
476*ef5ccd6cSJohn Marino warning (_("`%s': file time stamp mismatch."), oso->name);
477*ef5ccd6cSJohn Marino gdb_bfd_unref (abfd);
478*ef5ccd6cSJohn Marino return;
479*ef5ccd6cSJohn Marino }
480*ef5ccd6cSJohn Marino
481*ef5ccd6cSJohn Marino if (!bfd_hash_table_init_n (&table, macho_sym_hash_newfunc,
482*ef5ccd6cSJohn Marino sizeof (struct macho_sym_hash_entry),
483*ef5ccd6cSJohn Marino oso->nbr_syms))
484*ef5ccd6cSJohn Marino {
485*ef5ccd6cSJohn Marino warning (_("`%s': can't create hash table"), oso->name);
486*ef5ccd6cSJohn Marino gdb_bfd_unref (abfd);
487*ef5ccd6cSJohn Marino return;
488*ef5ccd6cSJohn Marino }
489*ef5ccd6cSJohn Marino
490*ef5ccd6cSJohn Marino bfd_set_cacheable (abfd, 1);
491*ef5ccd6cSJohn Marino
492*ef5ccd6cSJohn Marino /* Read symbols table. */
493*ef5ccd6cSJohn Marino storage = bfd_get_symtab_upper_bound (abfd);
494*ef5ccd6cSJohn Marino symbol_table = (asymbol **) xmalloc (storage);
495*ef5ccd6cSJohn Marino bfd_canonicalize_symtab (abfd, symbol_table);
496*ef5ccd6cSJohn Marino
497*ef5ccd6cSJohn Marino /* Init section flags. */
498*ef5ccd6cSJohn Marino nbr_sections = bfd_count_sections (abfd);
499*ef5ccd6cSJohn Marino sections_rebased = (unsigned char *) alloca (nbr_sections);
500*ef5ccd6cSJohn Marino for (i = 0; i < nbr_sections; i++)
501*ef5ccd6cSJohn Marino sections_rebased[i] = 0;
502*ef5ccd6cSJohn Marino
503*ef5ccd6cSJohn Marino /* Put symbols for the OSO file in the hash table. */
504*ef5ccd6cSJohn Marino for (symp = oso->oso_sym; symp != oso->end_sym; symp++)
505*ef5ccd6cSJohn Marino {
506*ef5ccd6cSJohn Marino const asymbol *sym = *symp;
507*ef5ccd6cSJohn Marino bfd_mach_o_asymbol *mach_o_sym = (bfd_mach_o_asymbol *)sym;
508*ef5ccd6cSJohn Marino
509*ef5ccd6cSJohn Marino switch (mach_o_sym->n_type)
510*ef5ccd6cSJohn Marino {
511*ef5ccd6cSJohn Marino case N_ENSYM:
512*ef5ccd6cSJohn Marino case N_BNSYM:
513*ef5ccd6cSJohn Marino case N_GSYM:
514*ef5ccd6cSJohn Marino sym = NULL;
515*ef5ccd6cSJohn Marino break;
516*ef5ccd6cSJohn Marino case N_FUN:
517*ef5ccd6cSJohn Marino if (sym->name == NULL || sym->name[0] == 0)
518*ef5ccd6cSJohn Marino sym = NULL;
519*ef5ccd6cSJohn Marino break;
520*ef5ccd6cSJohn Marino case N_STSYM:
521*ef5ccd6cSJohn Marino break;
522*ef5ccd6cSJohn Marino default:
523*ef5ccd6cSJohn Marino sym = NULL;
524*ef5ccd6cSJohn Marino break;
525*ef5ccd6cSJohn Marino }
526*ef5ccd6cSJohn Marino if (sym != NULL)
527*ef5ccd6cSJohn Marino {
528*ef5ccd6cSJohn Marino struct macho_sym_hash_entry *ent;
529*ef5ccd6cSJohn Marino
530*ef5ccd6cSJohn Marino ent = (struct macho_sym_hash_entry *)
531*ef5ccd6cSJohn Marino bfd_hash_lookup (&table, sym->name, TRUE, FALSE);
532*ef5ccd6cSJohn Marino if (ent->sym != NULL)
533*ef5ccd6cSJohn Marino complaint (&symfile_complaints,
534*ef5ccd6cSJohn Marino _("Duplicated symbol %s in symbol table"), sym->name);
535*ef5ccd6cSJohn Marino else
536*ef5ccd6cSJohn Marino {
537*ef5ccd6cSJohn Marino if (mach_o_debug_level > 4)
538*ef5ccd6cSJohn Marino {
539*ef5ccd6cSJohn Marino struct gdbarch *arch = get_objfile_arch (main_objfile);
540*ef5ccd6cSJohn Marino printf_unfiltered
541*ef5ccd6cSJohn Marino (_("Adding symbol %s (addr: %s)\n"),
542*ef5ccd6cSJohn Marino sym->name, paddress (arch, sym->value));
543*ef5ccd6cSJohn Marino }
544*ef5ccd6cSJohn Marino ent->sym = sym;
545*ef5ccd6cSJohn Marino }
546*ef5ccd6cSJohn Marino }
547*ef5ccd6cSJohn Marino }
548*ef5ccd6cSJohn Marino
549*ef5ccd6cSJohn Marino /* Relocate symbols of the OSO. */
550*ef5ccd6cSJohn Marino for (i = 0; symbol_table[i]; i++)
551*ef5ccd6cSJohn Marino {
552*ef5ccd6cSJohn Marino asymbol *sym = symbol_table[i];
553*ef5ccd6cSJohn Marino bfd_mach_o_asymbol *mach_o_sym = (bfd_mach_o_asymbol *)sym;
554*ef5ccd6cSJohn Marino
555*ef5ccd6cSJohn Marino if (mach_o_sym->n_type & BFD_MACH_O_N_STAB)
556*ef5ccd6cSJohn Marino continue;
557*ef5ccd6cSJohn Marino if ((mach_o_sym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_UNDF
558*ef5ccd6cSJohn Marino && sym->value != 0)
559*ef5ccd6cSJohn Marino {
560*ef5ccd6cSJohn Marino /* For common symbol use the min symtab and modify the OSO
561*ef5ccd6cSJohn Marino symbol table. */
562*ef5ccd6cSJohn Marino CORE_ADDR res;
563*ef5ccd6cSJohn Marino
564*ef5ccd6cSJohn Marino res = macho_resolve_oso_sym_with_minsym (main_objfile, sym);
565*ef5ccd6cSJohn Marino if (res != 0)
566*ef5ccd6cSJohn Marino {
567*ef5ccd6cSJohn Marino sym->section = bfd_com_section_ptr;
568*ef5ccd6cSJohn Marino sym->value = res;
569*ef5ccd6cSJohn Marino }
570*ef5ccd6cSJohn Marino }
571*ef5ccd6cSJohn Marino else if ((mach_o_sym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_SECT)
572*ef5ccd6cSJohn Marino {
573*ef5ccd6cSJohn Marino /* Normal symbol. */
574*ef5ccd6cSJohn Marino asection *sec = sym->section;
575*ef5ccd6cSJohn Marino bfd_mach_o_section *msec;
576*ef5ccd6cSJohn Marino unsigned int sec_type;
577*ef5ccd6cSJohn Marino
578*ef5ccd6cSJohn Marino /* Skip buggy ones. */
579*ef5ccd6cSJohn Marino if (sec == NULL || sections_rebased[sec->index] != 0)
580*ef5ccd6cSJohn Marino continue;
581*ef5ccd6cSJohn Marino
582*ef5ccd6cSJohn Marino /* Only consider regular, non-debugging sections. */
583*ef5ccd6cSJohn Marino msec = bfd_mach_o_get_mach_o_section (sec);
584*ef5ccd6cSJohn Marino sec_type = msec->flags & BFD_MACH_O_SECTION_TYPE_MASK;
585*ef5ccd6cSJohn Marino if ((sec_type == BFD_MACH_O_S_REGULAR
586*ef5ccd6cSJohn Marino || sec_type == BFD_MACH_O_S_ZEROFILL)
587*ef5ccd6cSJohn Marino && (msec->flags & BFD_MACH_O_S_ATTR_DEBUG) == 0)
588*ef5ccd6cSJohn Marino {
589*ef5ccd6cSJohn Marino CORE_ADDR addr = 0;
590*ef5ccd6cSJohn Marino
591*ef5ccd6cSJohn Marino if ((mach_o_sym->n_type & BFD_MACH_O_N_EXT) != 0)
592*ef5ccd6cSJohn Marino {
593*ef5ccd6cSJohn Marino /* Use the min symtab for global symbols. */
594*ef5ccd6cSJohn Marino addr = macho_resolve_oso_sym_with_minsym (main_objfile, sym);
595*ef5ccd6cSJohn Marino }
596*ef5ccd6cSJohn Marino else
597*ef5ccd6cSJohn Marino {
598*ef5ccd6cSJohn Marino struct macho_sym_hash_entry *ent;
599*ef5ccd6cSJohn Marino
600*ef5ccd6cSJohn Marino ent = (struct macho_sym_hash_entry *)
601*ef5ccd6cSJohn Marino bfd_hash_lookup (&table, sym->name, FALSE, FALSE);
602*ef5ccd6cSJohn Marino if (ent != NULL)
603*ef5ccd6cSJohn Marino addr = bfd_asymbol_value (ent->sym);
604*ef5ccd6cSJohn Marino }
605*ef5ccd6cSJohn Marino
606*ef5ccd6cSJohn Marino /* Adjust the section. */
607*ef5ccd6cSJohn Marino if (addr != 0)
608*ef5ccd6cSJohn Marino {
609*ef5ccd6cSJohn Marino CORE_ADDR res = addr - sym->value;
610*ef5ccd6cSJohn Marino
611*ef5ccd6cSJohn Marino if (mach_o_debug_level > 3)
612*ef5ccd6cSJohn Marino {
613*ef5ccd6cSJohn Marino struct gdbarch *arch = get_objfile_arch (main_objfile);
614*ef5ccd6cSJohn Marino printf_unfiltered
615*ef5ccd6cSJohn Marino (_("resolve sect %s with %s (set to %s)\n"),
616*ef5ccd6cSJohn Marino sec->name, sym->name,
617*ef5ccd6cSJohn Marino paddress (arch, res));
618*ef5ccd6cSJohn Marino }
619*ef5ccd6cSJohn Marino bfd_set_section_vma (abfd, sec, res);
620*ef5ccd6cSJohn Marino sections_rebased[sec->index] = 1;
621*ef5ccd6cSJohn Marino }
622*ef5ccd6cSJohn Marino }
623*ef5ccd6cSJohn Marino else
624*ef5ccd6cSJohn Marino {
625*ef5ccd6cSJohn Marino /* Mark the section as never rebased. */
626*ef5ccd6cSJohn Marino sections_rebased[sec->index] = 2;
627*ef5ccd6cSJohn Marino }
628*ef5ccd6cSJohn Marino }
629*ef5ccd6cSJohn Marino }
630*ef5ccd6cSJohn Marino
631*ef5ccd6cSJohn Marino bfd_hash_table_free (&table);
632*ef5ccd6cSJohn Marino
633*ef5ccd6cSJohn Marino /* We need to clear SYMFILE_MAINLINE to avoid interractive question
634*ef5ccd6cSJohn Marino from symfile.c:symbol_file_add_with_addrs_or_offsets. */
635*ef5ccd6cSJohn Marino cleanup = make_cleanup_bfd_unref (abfd);
636*ef5ccd6cSJohn Marino symbol_file_add_from_bfd
637*ef5ccd6cSJohn Marino (abfd, symfile_flags & ~(SYMFILE_MAINLINE | SYMFILE_VERBOSE), NULL,
638*ef5ccd6cSJohn Marino main_objfile->flags & (OBJF_REORDERED | OBJF_SHARED
639*ef5ccd6cSJohn Marino | OBJF_READNOW | OBJF_USERLOADED),
640*ef5ccd6cSJohn Marino main_objfile);
641*ef5ccd6cSJohn Marino do_cleanups (cleanup);
642*ef5ccd6cSJohn Marino }
643*ef5ccd6cSJohn Marino
644*ef5ccd6cSJohn Marino /* Read symbols from the vector of oso files. */
645*ef5ccd6cSJohn Marino
646*ef5ccd6cSJohn Marino static void
macho_symfile_read_all_oso(struct objfile * main_objfile,int symfile_flags)647*ef5ccd6cSJohn Marino macho_symfile_read_all_oso (struct objfile *main_objfile, int symfile_flags)
648*ef5ccd6cSJohn Marino {
649*ef5ccd6cSJohn Marino int ix;
650*ef5ccd6cSJohn Marino VEC (oso_el) *vec;
651*ef5ccd6cSJohn Marino oso_el *oso;
652*ef5ccd6cSJohn Marino struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
653*ef5ccd6cSJohn Marino
654*ef5ccd6cSJohn Marino vec = oso_vector;
655*ef5ccd6cSJohn Marino oso_vector = NULL;
656*ef5ccd6cSJohn Marino
657*ef5ccd6cSJohn Marino /* Sort oso by name so that files from libraries are gathered. */
658*ef5ccd6cSJohn Marino qsort (VEC_address (oso_el, vec), VEC_length (oso_el, vec),
659*ef5ccd6cSJohn Marino sizeof (oso_el), oso_el_compare_name);
660*ef5ccd6cSJohn Marino
661*ef5ccd6cSJohn Marino for (ix = 0; VEC_iterate (oso_el, vec, ix, oso);)
662*ef5ccd6cSJohn Marino {
663*ef5ccd6cSJohn Marino int pfx_len;
664*ef5ccd6cSJohn Marino
665*ef5ccd6cSJohn Marino /* Check if this is a library name. */
666*ef5ccd6cSJohn Marino pfx_len = get_archive_prefix_len (oso->name);
667*ef5ccd6cSJohn Marino if (pfx_len > 0)
668*ef5ccd6cSJohn Marino {
669*ef5ccd6cSJohn Marino bfd *archive_bfd;
670*ef5ccd6cSJohn Marino bfd *member_bfd;
671*ef5ccd6cSJohn Marino char *archive_name = XNEWVEC (char, pfx_len + 1);
672*ef5ccd6cSJohn Marino int last_ix;
673*ef5ccd6cSJohn Marino oso_el *oso2;
674*ef5ccd6cSJohn Marino int ix2;
675*ef5ccd6cSJohn Marino
676*ef5ccd6cSJohn Marino memcpy (archive_name, oso->name, pfx_len);
677*ef5ccd6cSJohn Marino archive_name[pfx_len] = '\0';
678*ef5ccd6cSJohn Marino
679*ef5ccd6cSJohn Marino make_cleanup (xfree, archive_name);
680*ef5ccd6cSJohn Marino
681*ef5ccd6cSJohn Marino /* Compute number of oso for this archive. */
682*ef5ccd6cSJohn Marino for (last_ix = ix;
683*ef5ccd6cSJohn Marino VEC_iterate (oso_el, vec, last_ix, oso2); last_ix++)
684*ef5ccd6cSJohn Marino {
685*ef5ccd6cSJohn Marino if (strncmp (oso2->name, archive_name, pfx_len) != 0)
686*ef5ccd6cSJohn Marino break;
687*ef5ccd6cSJohn Marino }
688*ef5ccd6cSJohn Marino
689*ef5ccd6cSJohn Marino /* Open the archive and check the format. */
690*ef5ccd6cSJohn Marino archive_bfd = gdb_bfd_open (archive_name, gnutarget, -1);
691*ef5ccd6cSJohn Marino if (archive_bfd == NULL)
692*ef5ccd6cSJohn Marino {
693*ef5ccd6cSJohn Marino warning (_("Could not open OSO archive file \"%s\""),
694*ef5ccd6cSJohn Marino archive_name);
695*ef5ccd6cSJohn Marino ix = last_ix;
696*ef5ccd6cSJohn Marino continue;
697*ef5ccd6cSJohn Marino }
698*ef5ccd6cSJohn Marino if (!bfd_check_format (archive_bfd, bfd_archive))
699*ef5ccd6cSJohn Marino {
700*ef5ccd6cSJohn Marino warning (_("OSO archive file \"%s\" not an archive."),
701*ef5ccd6cSJohn Marino archive_name);
702*ef5ccd6cSJohn Marino gdb_bfd_unref (archive_bfd);
703*ef5ccd6cSJohn Marino ix = last_ix;
704*ef5ccd6cSJohn Marino continue;
705*ef5ccd6cSJohn Marino }
706*ef5ccd6cSJohn Marino
707*ef5ccd6cSJohn Marino member_bfd = gdb_bfd_openr_next_archived_file (archive_bfd, NULL);
708*ef5ccd6cSJohn Marino
709*ef5ccd6cSJohn Marino if (member_bfd == NULL)
710*ef5ccd6cSJohn Marino {
711*ef5ccd6cSJohn Marino warning (_("Could not read archive members out of "
712*ef5ccd6cSJohn Marino "OSO archive \"%s\""), archive_name);
713*ef5ccd6cSJohn Marino gdb_bfd_unref (archive_bfd);
714*ef5ccd6cSJohn Marino ix = last_ix;
715*ef5ccd6cSJohn Marino continue;
716*ef5ccd6cSJohn Marino }
717*ef5ccd6cSJohn Marino
718*ef5ccd6cSJohn Marino /* Load all oso in this library. */
719*ef5ccd6cSJohn Marino while (member_bfd != NULL)
720*ef5ccd6cSJohn Marino {
721*ef5ccd6cSJohn Marino bfd *prev;
722*ef5ccd6cSJohn Marino const char *member_name = member_bfd->filename;
723*ef5ccd6cSJohn Marino int member_len = strlen (member_name);
724*ef5ccd6cSJohn Marino
725*ef5ccd6cSJohn Marino /* If this member is referenced, add it as a symfile. */
726*ef5ccd6cSJohn Marino for (ix2 = ix; ix2 < last_ix; ix2++)
727*ef5ccd6cSJohn Marino {
728*ef5ccd6cSJohn Marino oso2 = VEC_index (oso_el, vec, ix2);
729*ef5ccd6cSJohn Marino
730*ef5ccd6cSJohn Marino if (oso2->name
731*ef5ccd6cSJohn Marino && strlen (oso2->name) == pfx_len + member_len + 2
732*ef5ccd6cSJohn Marino && !memcmp (member_name, oso2->name + pfx_len + 1,
733*ef5ccd6cSJohn Marino member_len))
734*ef5ccd6cSJohn Marino {
735*ef5ccd6cSJohn Marino macho_add_oso_symfile (oso2, member_bfd,
736*ef5ccd6cSJohn Marino main_objfile, symfile_flags);
737*ef5ccd6cSJohn Marino oso2->name = NULL;
738*ef5ccd6cSJohn Marino break;
739*ef5ccd6cSJohn Marino }
740*ef5ccd6cSJohn Marino }
741*ef5ccd6cSJohn Marino
742*ef5ccd6cSJohn Marino prev = member_bfd;
743*ef5ccd6cSJohn Marino member_bfd = gdb_bfd_openr_next_archived_file (archive_bfd,
744*ef5ccd6cSJohn Marino member_bfd);
745*ef5ccd6cSJohn Marino
746*ef5ccd6cSJohn Marino /* Free previous member if not referenced by an oso. */
747*ef5ccd6cSJohn Marino if (ix2 >= last_ix)
748*ef5ccd6cSJohn Marino gdb_bfd_unref (prev);
749*ef5ccd6cSJohn Marino }
750*ef5ccd6cSJohn Marino for (ix2 = ix; ix2 < last_ix; ix2++)
751*ef5ccd6cSJohn Marino {
752*ef5ccd6cSJohn Marino oso_el *oso2 = VEC_index (oso_el, vec, ix2);
753*ef5ccd6cSJohn Marino
754*ef5ccd6cSJohn Marino if (oso2->name != NULL)
755*ef5ccd6cSJohn Marino warning (_("Could not find specified archive member "
756*ef5ccd6cSJohn Marino "for OSO name \"%s\""), oso->name);
757*ef5ccd6cSJohn Marino }
758*ef5ccd6cSJohn Marino ix = last_ix;
759*ef5ccd6cSJohn Marino }
760*ef5ccd6cSJohn Marino else
761*ef5ccd6cSJohn Marino {
762*ef5ccd6cSJohn Marino bfd *abfd;
763*ef5ccd6cSJohn Marino
764*ef5ccd6cSJohn Marino abfd = gdb_bfd_open (oso->name, gnutarget, -1);
765*ef5ccd6cSJohn Marino if (!abfd)
766*ef5ccd6cSJohn Marino warning (_("`%s': can't open to read symbols: %s."), oso->name,
767*ef5ccd6cSJohn Marino bfd_errmsg (bfd_get_error ()));
768*ef5ccd6cSJohn Marino else
769*ef5ccd6cSJohn Marino macho_add_oso_symfile (oso, abfd, main_objfile, symfile_flags);
770*ef5ccd6cSJohn Marino
771*ef5ccd6cSJohn Marino ix++;
772*ef5ccd6cSJohn Marino }
773*ef5ccd6cSJohn Marino }
774*ef5ccd6cSJohn Marino
775*ef5ccd6cSJohn Marino VEC_free (oso_el, vec);
776*ef5ccd6cSJohn Marino do_cleanups (cleanup);
777*ef5ccd6cSJohn Marino }
778*ef5ccd6cSJohn Marino
779*ef5ccd6cSJohn Marino /* DSYM (debug symbols) files contain the debug info of an executable.
780*ef5ccd6cSJohn Marino This is a separate file created by dsymutil(1) and is similar to debug
781*ef5ccd6cSJohn Marino link feature on ELF.
782*ef5ccd6cSJohn Marino DSYM files are located in a subdirectory. Append DSYM_SUFFIX to the
783*ef5ccd6cSJohn Marino executable name and the executable base name to get the DSYM file name. */
784*ef5ccd6cSJohn Marino #define DSYM_SUFFIX ".dSYM/Contents/Resources/DWARF/"
785*ef5ccd6cSJohn Marino
786*ef5ccd6cSJohn Marino /* Check if a dsym file exists for OBJFILE. If so, returns a bfd for it.
787*ef5ccd6cSJohn Marino Return NULL if no valid dsym file is found. */
788*ef5ccd6cSJohn Marino
789*ef5ccd6cSJohn Marino static bfd *
macho_check_dsym(struct objfile * objfile)790*ef5ccd6cSJohn Marino macho_check_dsym (struct objfile *objfile)
791*ef5ccd6cSJohn Marino {
792*ef5ccd6cSJohn Marino size_t name_len = strlen (objfile->name);
793*ef5ccd6cSJohn Marino size_t dsym_len = strlen (DSYM_SUFFIX);
794*ef5ccd6cSJohn Marino const char *base_name = lbasename (objfile->name);
795*ef5ccd6cSJohn Marino size_t base_len = strlen (base_name);
796*ef5ccd6cSJohn Marino char *dsym_filename = alloca (name_len + dsym_len + base_len + 1);
797*ef5ccd6cSJohn Marino bfd *dsym_bfd;
798*ef5ccd6cSJohn Marino bfd_mach_o_load_command *main_uuid;
799*ef5ccd6cSJohn Marino bfd_mach_o_load_command *dsym_uuid;
800*ef5ccd6cSJohn Marino
801*ef5ccd6cSJohn Marino strcpy (dsym_filename, objfile->name);
802*ef5ccd6cSJohn Marino strcpy (dsym_filename + name_len, DSYM_SUFFIX);
803*ef5ccd6cSJohn Marino strcpy (dsym_filename + name_len + dsym_len, base_name);
804*ef5ccd6cSJohn Marino
805*ef5ccd6cSJohn Marino if (access (dsym_filename, R_OK) != 0)
806*ef5ccd6cSJohn Marino return NULL;
807*ef5ccd6cSJohn Marino
808*ef5ccd6cSJohn Marino if (bfd_mach_o_lookup_command (objfile->obfd,
809*ef5ccd6cSJohn Marino BFD_MACH_O_LC_UUID, &main_uuid) == 0)
810*ef5ccd6cSJohn Marino {
811*ef5ccd6cSJohn Marino warning (_("can't find UUID in %s"), objfile->name);
812*ef5ccd6cSJohn Marino return NULL;
813*ef5ccd6cSJohn Marino }
814*ef5ccd6cSJohn Marino dsym_bfd = gdb_bfd_openr (dsym_filename, gnutarget);
815*ef5ccd6cSJohn Marino if (dsym_bfd == NULL)
816*ef5ccd6cSJohn Marino {
817*ef5ccd6cSJohn Marino warning (_("can't open dsym file %s"), dsym_filename);
818*ef5ccd6cSJohn Marino return NULL;
819*ef5ccd6cSJohn Marino }
820*ef5ccd6cSJohn Marino
821*ef5ccd6cSJohn Marino if (!bfd_check_format (dsym_bfd, bfd_object))
822*ef5ccd6cSJohn Marino {
823*ef5ccd6cSJohn Marino gdb_bfd_unref (dsym_bfd);
824*ef5ccd6cSJohn Marino warning (_("bad dsym file format: %s"), bfd_errmsg (bfd_get_error ()));
825*ef5ccd6cSJohn Marino return NULL;
826*ef5ccd6cSJohn Marino }
827*ef5ccd6cSJohn Marino
828*ef5ccd6cSJohn Marino if (bfd_mach_o_lookup_command (dsym_bfd,
829*ef5ccd6cSJohn Marino BFD_MACH_O_LC_UUID, &dsym_uuid) == 0)
830*ef5ccd6cSJohn Marino {
831*ef5ccd6cSJohn Marino warning (_("can't find UUID in %s"), dsym_filename);
832*ef5ccd6cSJohn Marino gdb_bfd_unref (dsym_bfd);
833*ef5ccd6cSJohn Marino return NULL;
834*ef5ccd6cSJohn Marino }
835*ef5ccd6cSJohn Marino if (memcmp (dsym_uuid->command.uuid.uuid, main_uuid->command.uuid.uuid,
836*ef5ccd6cSJohn Marino sizeof (main_uuid->command.uuid.uuid)))
837*ef5ccd6cSJohn Marino {
838*ef5ccd6cSJohn Marino warning (_("dsym file UUID doesn't match the one in %s"), objfile->name);
839*ef5ccd6cSJohn Marino gdb_bfd_unref (dsym_bfd);
840*ef5ccd6cSJohn Marino return NULL;
841*ef5ccd6cSJohn Marino }
842*ef5ccd6cSJohn Marino return dsym_bfd;
843*ef5ccd6cSJohn Marino }
844*ef5ccd6cSJohn Marino
845*ef5ccd6cSJohn Marino static void
macho_symfile_read(struct objfile * objfile,int symfile_flags)846*ef5ccd6cSJohn Marino macho_symfile_read (struct objfile *objfile, int symfile_flags)
847*ef5ccd6cSJohn Marino {
848*ef5ccd6cSJohn Marino bfd *abfd = objfile->obfd;
849*ef5ccd6cSJohn Marino CORE_ADDR offset;
850*ef5ccd6cSJohn Marino long storage_needed;
851*ef5ccd6cSJohn Marino bfd *dsym_bfd;
852*ef5ccd6cSJohn Marino
853*ef5ccd6cSJohn Marino /* Get symbols from the symbol table only if the file is an executable.
854*ef5ccd6cSJohn Marino The symbol table of object files is not relocated and is expected to
855*ef5ccd6cSJohn Marino be in the executable. */
856*ef5ccd6cSJohn Marino if (bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC))
857*ef5ccd6cSJohn Marino {
858*ef5ccd6cSJohn Marino /* Process the normal symbol table first. */
859*ef5ccd6cSJohn Marino storage_needed = bfd_get_symtab_upper_bound (objfile->obfd);
860*ef5ccd6cSJohn Marino if (storage_needed < 0)
861*ef5ccd6cSJohn Marino error (_("Can't read symbols from %s: %s"),
862*ef5ccd6cSJohn Marino bfd_get_filename (objfile->obfd),
863*ef5ccd6cSJohn Marino bfd_errmsg (bfd_get_error ()));
864*ef5ccd6cSJohn Marino
865*ef5ccd6cSJohn Marino if (storage_needed > 0)
866*ef5ccd6cSJohn Marino {
867*ef5ccd6cSJohn Marino asymbol **symbol_table;
868*ef5ccd6cSJohn Marino long symcount;
869*ef5ccd6cSJohn Marino struct cleanup *back_to;
870*ef5ccd6cSJohn Marino
871*ef5ccd6cSJohn Marino symbol_table = (asymbol **) xmalloc (storage_needed);
872*ef5ccd6cSJohn Marino make_cleanup (xfree, symbol_table);
873*ef5ccd6cSJohn Marino
874*ef5ccd6cSJohn Marino init_minimal_symbol_collection ();
875*ef5ccd6cSJohn Marino back_to = make_cleanup_discard_minimal_symbols ();
876*ef5ccd6cSJohn Marino
877*ef5ccd6cSJohn Marino symcount = bfd_canonicalize_symtab (objfile->obfd, symbol_table);
878*ef5ccd6cSJohn Marino
879*ef5ccd6cSJohn Marino if (symcount < 0)
880*ef5ccd6cSJohn Marino error (_("Can't read symbols from %s: %s"),
881*ef5ccd6cSJohn Marino bfd_get_filename (objfile->obfd),
882*ef5ccd6cSJohn Marino bfd_errmsg (bfd_get_error ()));
883*ef5ccd6cSJohn Marino
884*ef5ccd6cSJohn Marino macho_symtab_read (objfile, symcount, symbol_table);
885*ef5ccd6cSJohn Marino
886*ef5ccd6cSJohn Marino install_minimal_symbols (objfile);
887*ef5ccd6cSJohn Marino do_cleanups (back_to);
888*ef5ccd6cSJohn Marino }
889*ef5ccd6cSJohn Marino
890*ef5ccd6cSJohn Marino /* Try to read .eh_frame / .debug_frame. */
891*ef5ccd6cSJohn Marino /* First, locate these sections. We ignore the result status
892*ef5ccd6cSJohn Marino as it only checks for debug info. */
893*ef5ccd6cSJohn Marino dwarf2_has_info (objfile, NULL);
894*ef5ccd6cSJohn Marino dwarf2_build_frame_info (objfile);
895*ef5ccd6cSJohn Marino
896*ef5ccd6cSJohn Marino /* Check for DSYM file. */
897*ef5ccd6cSJohn Marino dsym_bfd = macho_check_dsym (objfile);
898*ef5ccd6cSJohn Marino if (dsym_bfd != NULL)
899*ef5ccd6cSJohn Marino {
900*ef5ccd6cSJohn Marino int ix;
901*ef5ccd6cSJohn Marino oso_el *oso;
902*ef5ccd6cSJohn Marino struct bfd_section *asect, *dsect;
903*ef5ccd6cSJohn Marino struct cleanup *cleanup;
904*ef5ccd6cSJohn Marino
905*ef5ccd6cSJohn Marino if (mach_o_debug_level > 0)
906*ef5ccd6cSJohn Marino printf_unfiltered (_("dsym file found\n"));
907*ef5ccd6cSJohn Marino
908*ef5ccd6cSJohn Marino /* Remove oso. They won't be used. */
909*ef5ccd6cSJohn Marino VEC_free (oso_el, oso_vector);
910*ef5ccd6cSJohn Marino oso_vector = NULL;
911*ef5ccd6cSJohn Marino
912*ef5ccd6cSJohn Marino /* Set dsym section size. */
913*ef5ccd6cSJohn Marino for (asect = objfile->obfd->sections, dsect = dsym_bfd->sections;
914*ef5ccd6cSJohn Marino asect && dsect;
915*ef5ccd6cSJohn Marino asect = asect->next, dsect = dsect->next)
916*ef5ccd6cSJohn Marino {
917*ef5ccd6cSJohn Marino if (strcmp (asect->name, dsect->name) != 0)
918*ef5ccd6cSJohn Marino break;
919*ef5ccd6cSJohn Marino bfd_set_section_size (dsym_bfd, dsect,
920*ef5ccd6cSJohn Marino bfd_get_section_size (asect));
921*ef5ccd6cSJohn Marino }
922*ef5ccd6cSJohn Marino
923*ef5ccd6cSJohn Marino /* Add the dsym file as a separate file. */
924*ef5ccd6cSJohn Marino cleanup = make_cleanup_bfd_unref (dsym_bfd);
925*ef5ccd6cSJohn Marino symbol_file_add_separate (dsym_bfd, symfile_flags, objfile);
926*ef5ccd6cSJohn Marino do_cleanups (cleanup);
927*ef5ccd6cSJohn Marino
928*ef5ccd6cSJohn Marino /* Don't try to read dwarf2 from main file or shared libraries. */
929*ef5ccd6cSJohn Marino return;
930*ef5ccd6cSJohn Marino }
931*ef5ccd6cSJohn Marino }
932*ef5ccd6cSJohn Marino
933*ef5ccd6cSJohn Marino if (dwarf2_has_info (objfile, NULL))
934*ef5ccd6cSJohn Marino {
935*ef5ccd6cSJohn Marino /* DWARF 2 sections */
936*ef5ccd6cSJohn Marino dwarf2_build_psymtabs (objfile);
937*ef5ccd6cSJohn Marino }
938*ef5ccd6cSJohn Marino
939*ef5ccd6cSJohn Marino /* Then the oso. */
940*ef5ccd6cSJohn Marino if (oso_vector != NULL)
941*ef5ccd6cSJohn Marino macho_symfile_read_all_oso (objfile, symfile_flags);
942*ef5ccd6cSJohn Marino }
943*ef5ccd6cSJohn Marino
944*ef5ccd6cSJohn Marino static bfd_byte *
macho_symfile_relocate(struct objfile * objfile,asection * sectp,bfd_byte * buf)945*ef5ccd6cSJohn Marino macho_symfile_relocate (struct objfile *objfile, asection *sectp,
946*ef5ccd6cSJohn Marino bfd_byte *buf)
947*ef5ccd6cSJohn Marino {
948*ef5ccd6cSJohn Marino bfd *abfd = objfile->obfd;
949*ef5ccd6cSJohn Marino
950*ef5ccd6cSJohn Marino /* We're only interested in sections with relocation
951*ef5ccd6cSJohn Marino information. */
952*ef5ccd6cSJohn Marino if ((sectp->flags & SEC_RELOC) == 0)
953*ef5ccd6cSJohn Marino return NULL;
954*ef5ccd6cSJohn Marino
955*ef5ccd6cSJohn Marino if (mach_o_debug_level > 0)
956*ef5ccd6cSJohn Marino printf_unfiltered (_("Relocate section '%s' of %s\n"),
957*ef5ccd6cSJohn Marino sectp->name, objfile->name);
958*ef5ccd6cSJohn Marino
959*ef5ccd6cSJohn Marino return bfd_simple_get_relocated_section_contents (abfd, sectp, buf, NULL);
960*ef5ccd6cSJohn Marino }
961*ef5ccd6cSJohn Marino
962*ef5ccd6cSJohn Marino static void
macho_symfile_finish(struct objfile * objfile)963*ef5ccd6cSJohn Marino macho_symfile_finish (struct objfile *objfile)
964*ef5ccd6cSJohn Marino {
965*ef5ccd6cSJohn Marino }
966*ef5ccd6cSJohn Marino
967*ef5ccd6cSJohn Marino static void
macho_symfile_offsets(struct objfile * objfile,struct section_addr_info * addrs)968*ef5ccd6cSJohn Marino macho_symfile_offsets (struct objfile *objfile,
969*ef5ccd6cSJohn Marino struct section_addr_info *addrs)
970*ef5ccd6cSJohn Marino {
971*ef5ccd6cSJohn Marino unsigned int i;
972*ef5ccd6cSJohn Marino unsigned int num_sections;
973*ef5ccd6cSJohn Marino struct obj_section *osect;
974*ef5ccd6cSJohn Marino
975*ef5ccd6cSJohn Marino /* Allocate section_offsets. */
976*ef5ccd6cSJohn Marino objfile->num_sections = bfd_count_sections (objfile->obfd);
977*ef5ccd6cSJohn Marino objfile->section_offsets = (struct section_offsets *)
978*ef5ccd6cSJohn Marino obstack_alloc (&objfile->objfile_obstack,
979*ef5ccd6cSJohn Marino SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
980*ef5ccd6cSJohn Marino memset (objfile->section_offsets, 0,
981*ef5ccd6cSJohn Marino SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
982*ef5ccd6cSJohn Marino
983*ef5ccd6cSJohn Marino /* This code is run when we first add the objfile with
984*ef5ccd6cSJohn Marino symfile_add_with_addrs_or_offsets, when "addrs" not "offsets" are
985*ef5ccd6cSJohn Marino passed in. The place in symfile.c where the addrs are applied
986*ef5ccd6cSJohn Marino depends on the addrs having section names. But in the dyld code
987*ef5ccd6cSJohn Marino we build an anonymous array of addrs, so that code is a no-op.
988*ef5ccd6cSJohn Marino Because of that, we have to apply the addrs to the sections here.
989*ef5ccd6cSJohn Marino N.B. if an objfile slides after we've already created it, then it
990*ef5ccd6cSJohn Marino goes through objfile_relocate. */
991*ef5ccd6cSJohn Marino
992*ef5ccd6cSJohn Marino for (i = 0; i < addrs->num_sections; i++)
993*ef5ccd6cSJohn Marino {
994*ef5ccd6cSJohn Marino if (addrs->other[i].name == NULL)
995*ef5ccd6cSJohn Marino continue;
996*ef5ccd6cSJohn Marino
997*ef5ccd6cSJohn Marino ALL_OBJFILE_OSECTIONS (objfile, osect)
998*ef5ccd6cSJohn Marino {
999*ef5ccd6cSJohn Marino const char *bfd_sect_name = osect->the_bfd_section->name;
1000*ef5ccd6cSJohn Marino
1001*ef5ccd6cSJohn Marino if (strcmp (bfd_sect_name, addrs->other[i].name) == 0)
1002*ef5ccd6cSJohn Marino {
1003*ef5ccd6cSJohn Marino obj_section_offset (osect) = addrs->other[i].addr;
1004*ef5ccd6cSJohn Marino break;
1005*ef5ccd6cSJohn Marino }
1006*ef5ccd6cSJohn Marino }
1007*ef5ccd6cSJohn Marino }
1008*ef5ccd6cSJohn Marino
1009*ef5ccd6cSJohn Marino objfile->sect_index_text = 0;
1010*ef5ccd6cSJohn Marino
1011*ef5ccd6cSJohn Marino ALL_OBJFILE_OSECTIONS (objfile, osect)
1012*ef5ccd6cSJohn Marino {
1013*ef5ccd6cSJohn Marino const char *bfd_sect_name = osect->the_bfd_section->name;
1014*ef5ccd6cSJohn Marino int sect_index = osect->the_bfd_section->index;
1015*ef5ccd6cSJohn Marino
1016*ef5ccd6cSJohn Marino if (strncmp (bfd_sect_name, "LC_SEGMENT.", 11) == 0)
1017*ef5ccd6cSJohn Marino bfd_sect_name += 11;
1018*ef5ccd6cSJohn Marino if (strcmp (bfd_sect_name, "__TEXT") == 0
1019*ef5ccd6cSJohn Marino || strcmp (bfd_sect_name, "__TEXT.__text") == 0)
1020*ef5ccd6cSJohn Marino objfile->sect_index_text = sect_index;
1021*ef5ccd6cSJohn Marino }
1022*ef5ccd6cSJohn Marino }
1023*ef5ccd6cSJohn Marino
1024*ef5ccd6cSJohn Marino static const struct sym_fns macho_sym_fns = {
1025*ef5ccd6cSJohn Marino bfd_target_mach_o_flavour,
1026*ef5ccd6cSJohn Marino
1027*ef5ccd6cSJohn Marino macho_new_init, /* init anything gbl to entire symtab */
1028*ef5ccd6cSJohn Marino macho_symfile_init, /* read initial info, setup for sym_read() */
1029*ef5ccd6cSJohn Marino macho_symfile_read, /* read a symbol file into symtab */
1030*ef5ccd6cSJohn Marino NULL, /* sym_read_psymbols */
1031*ef5ccd6cSJohn Marino macho_symfile_finish, /* finished with file, cleanup */
1032*ef5ccd6cSJohn Marino macho_symfile_offsets, /* xlate external to internal form */
1033*ef5ccd6cSJohn Marino default_symfile_segments, /* Get segment information from a file. */
1034*ef5ccd6cSJohn Marino NULL,
1035*ef5ccd6cSJohn Marino macho_symfile_relocate, /* Relocate a debug section. */
1036*ef5ccd6cSJohn Marino NULL, /* sym_get_probes */
1037*ef5ccd6cSJohn Marino &psym_functions
1038*ef5ccd6cSJohn Marino };
1039*ef5ccd6cSJohn Marino
1040*ef5ccd6cSJohn Marino /* -Wmissing-prototypes */
1041*ef5ccd6cSJohn Marino extern initialize_file_ftype _initialize_machoread;
1042*ef5ccd6cSJohn Marino
1043*ef5ccd6cSJohn Marino void
_initialize_machoread()1044*ef5ccd6cSJohn Marino _initialize_machoread ()
1045*ef5ccd6cSJohn Marino {
1046*ef5ccd6cSJohn Marino add_symtab_fns (&macho_sym_fns);
1047*ef5ccd6cSJohn Marino
1048*ef5ccd6cSJohn Marino add_setshow_zuinteger_cmd ("mach-o", class_obscure,
1049*ef5ccd6cSJohn Marino &mach_o_debug_level,
1050*ef5ccd6cSJohn Marino _("Set if printing Mach-O symbols processing."),
1051*ef5ccd6cSJohn Marino _("Show if printing Mach-O symbols processing."),
1052*ef5ccd6cSJohn Marino NULL, NULL, NULL,
1053*ef5ccd6cSJohn Marino &setdebuglist, &showdebuglist);
1054*ef5ccd6cSJohn Marino }
1055