correct some mach-o section specification nits.
[deliverable/binutils-gdb.git] / bfd / mach-o.c
CommitLineData
3af9a47b 1/* Mach-O support for BFD.
4f608e79 2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
7f307238 3 2009, 2010, 2011, 2012
3af9a47b
NC
4 Free Software Foundation, Inc.
5
6 This file is part of BFD, the Binary File Descriptor library.
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
cd123cb7 10 the Free Software Foundation; either version 3 of the License, or
3af9a47b
NC
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
a95a4550 19 along with this program; if not, write to the Free Software
cd123cb7
NC
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
3af9a47b 22
3db64b00 23#include "sysdep.h"
3af9a47b
NC
24#include "mach-o.h"
25#include "bfd.h"
3af9a47b
NC
26#include "libbfd.h"
27#include "libiberty.h"
15e1c58a 28#include "aout/stab_gnu.h"
46d1c23b
TG
29#include "mach-o/reloc.h"
30#include "mach-o/external.h"
3af9a47b 31#include <ctype.h>
7f307238
IS
32#include <stdlib.h>
33#include <string.h>
3af9a47b 34
154a1ee5
TG
35#define bfd_mach_o_object_p bfd_mach_o_gen_object_p
36#define bfd_mach_o_core_p bfd_mach_o_gen_core_p
42fa0891 37#define bfd_mach_o_mkobject bfd_mach_o_gen_mkobject
116c20d2 38
92bc0e80
TG
39#define FILE_ALIGN(off, algn) \
40 (((off) + ((file_ptr) 1 << (algn)) - 1) & ((file_ptr) -1 << (algn)))
41
c2f09c75 42unsigned int
1e8a024a
TG
43bfd_mach_o_version (bfd *abfd)
44{
45 bfd_mach_o_data_struct *mdata = NULL;
46
47 BFD_ASSERT (bfd_mach_o_valid (abfd));
046b007d 48 mdata = bfd_mach_o_get_data (abfd);
1e8a024a
TG
49
50 return mdata->header.version;
51}
52
b34976b6 53bfd_boolean
116c20d2 54bfd_mach_o_valid (bfd *abfd)
3af9a47b
NC
55{
56 if (abfd == NULL || abfd->xvec == NULL)
154a1ee5 57 return FALSE;
3af9a47b 58
154a1ee5
TG
59 if (abfd->xvec->flavour != bfd_target_mach_o_flavour)
60 return FALSE;
3af9a47b 61
046b007d 62 if (bfd_mach_o_get_data (abfd) == NULL)
154a1ee5
TG
63 return FALSE;
64 return TRUE;
65}
66
c2f09c75
TG
67static INLINE bfd_boolean
68mach_o_wide_p (bfd_mach_o_header *header)
69{
70 switch (header->version)
71 {
72 case 1:
73 return FALSE;
74 case 2:
75 return TRUE;
76 default:
77 BFD_FAIL ();
78 return FALSE;
79 }
80}
81
82static INLINE bfd_boolean
83bfd_mach_o_wide_p (bfd *abfd)
84{
046b007d 85 return mach_o_wide_p (&bfd_mach_o_get_data (abfd)->header);
c2f09c75
TG
86}
87
154a1ee5
TG
88/* Tables to translate well known Mach-O segment/section names to bfd
89 names. Use of canonical names (such as .text or .debug_frame) is required
90 by gdb. */
91
a4551119
TG
92/* __TEXT Segment. */
93static const mach_o_section_name_xlat text_section_names_xlat[] =
154a1ee5 94 {
a4551119
TG
95 { ".text", "__text",
96 SEC_CODE | SEC_LOAD, BFD_MACH_O_S_REGULAR,
97 BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS, 0},
98 { ".const", "__const",
99 SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
100 BFD_MACH_O_S_ATTR_NONE, 0},
101 { ".static_const", "__static_const",
102 SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
103 BFD_MACH_O_S_ATTR_NONE, 0},
104 { ".cstring", "__cstring",
105 SEC_READONLY | SEC_DATA | SEC_LOAD | SEC_MERGE | SEC_STRINGS,
106 BFD_MACH_O_S_CSTRING_LITERALS,
107 BFD_MACH_O_S_ATTR_NONE, 0},
108 { ".literal4", "__literal4",
109 SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_4BYTE_LITERALS,
110 BFD_MACH_O_S_ATTR_NONE, 2},
111 { ".literal8", "__literal8",
112 SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_8BYTE_LITERALS,
113 BFD_MACH_O_S_ATTR_NONE, 3},
114 { ".literal16", "__literal16",
115 SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_16BYTE_LITERALS,
116 BFD_MACH_O_S_ATTR_NONE, 4},
117 { ".constructor", "__constructor",
118 SEC_CODE | SEC_LOAD, BFD_MACH_O_S_REGULAR,
119 BFD_MACH_O_S_ATTR_NONE, 0},
120 { ".destructor", "__destructor",
121 SEC_CODE | SEC_LOAD, BFD_MACH_O_S_REGULAR,
122 BFD_MACH_O_S_ATTR_NONE, 0},
123 { ".eh_frame", "__eh_frame",
632039e0 124 SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_COALESCED,
a4551119
TG
125 BFD_MACH_O_S_ATTR_LIVE_SUPPORT
126 | BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS
632039e0 127 | BFD_MACH_O_S_ATTR_NO_TOC, 2},
a4551119 128 { NULL, NULL, 0, 0, 0, 0}
154a1ee5
TG
129 };
130
a4551119
TG
131/* __DATA Segment. */
132static const mach_o_section_name_xlat data_section_names_xlat[] =
154a1ee5 133 {
a4551119
TG
134 { ".data", "__data",
135 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
136 BFD_MACH_O_S_ATTR_NONE, 0},
137 { ".bss", "__bss",
138 SEC_NO_FLAGS, BFD_MACH_O_S_ZEROFILL,
139 BFD_MACH_O_S_ATTR_NONE, 0},
140 { ".const_data", "__const",
141 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
142 BFD_MACH_O_S_ATTR_NONE, 0},
143 { ".static_data", "__static_data",
144 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
145 BFD_MACH_O_S_ATTR_NONE, 0},
146 { ".mod_init_func", "__mod_init_func",
147 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS,
148 BFD_MACH_O_S_ATTR_NONE, 2},
149 { ".mod_term_func", "__mod_term_func",
150 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS,
151 BFD_MACH_O_S_ATTR_NONE, 2},
152 { ".dyld", "__dyld",
153 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
154 BFD_MACH_O_S_ATTR_NONE, 0},
155 { ".cfstring", "__cfstring",
156 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
157 BFD_MACH_O_S_ATTR_NONE, 2},
158 { NULL, NULL, 0, 0, 0, 0}
154a1ee5
TG
159 };
160
a4551119
TG
161/* __DWARF Segment. */
162static const mach_o_section_name_xlat dwarf_section_names_xlat[] =
154a1ee5 163 {
a4551119
TG
164 { ".debug_frame", "__debug_frame",
165 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
166 BFD_MACH_O_S_ATTR_DEBUG, 0},
167 { ".debug_info", "__debug_info",
168 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
169 BFD_MACH_O_S_ATTR_DEBUG, 0},
170 { ".debug_abbrev", "__debug_abbrev",
171 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
172 BFD_MACH_O_S_ATTR_DEBUG, 0},
173 { ".debug_aranges", "__debug_aranges",
174 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
175 BFD_MACH_O_S_ATTR_DEBUG, 0},
176 { ".debug_macinfo", "__debug_macinfo",
177 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
178 BFD_MACH_O_S_ATTR_DEBUG, 0},
179 { ".debug_line", "__debug_line",
180 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
181 BFD_MACH_O_S_ATTR_DEBUG, 0},
182 { ".debug_loc", "__debug_loc",
183 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
184 BFD_MACH_O_S_ATTR_DEBUG, 0},
185 { ".debug_pubnames", "__debug_pubnames",
186 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
187 BFD_MACH_O_S_ATTR_DEBUG, 0},
188 { ".debug_pubtypes", "__debug_pubtypes",
189 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
190 BFD_MACH_O_S_ATTR_DEBUG, 0},
191 { ".debug_str", "__debug_str",
192 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
193 BFD_MACH_O_S_ATTR_DEBUG, 0},
194 { ".debug_ranges", "__debug_ranges",
195 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
196 BFD_MACH_O_S_ATTR_DEBUG, 0},
197 { ".debug_macro", "__debug_macro",
198 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
199 BFD_MACH_O_S_ATTR_DEBUG, 0},
200 { NULL, NULL, 0, 0, 0, 0}
154a1ee5
TG
201 };
202
a4551119
TG
203/* __OBJC Segment. */
204static const mach_o_section_name_xlat objc_section_names_xlat[] =
205 {
206 { ".objc_class", "__class",
207 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
208 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
209 { ".objc_meta_class", "__meta_class",
210 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
211 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
212 { ".objc_cat_cls_meth", "__cat_cls_meth",
213 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
214 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
215 { ".objc_cat_inst_meth", "__cat_inst_meth",
216 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
217 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
218 { ".objc_protocol", "__protocol",
219 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
220 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
221 { ".objc_string_object", "__string_object",
222 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
223 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
224 { ".objc_cls_meth", "__cls_meth",
225 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
226 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
227 { ".objc_inst_meth", "__inst_meth",
228 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
229 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
230 { ".objc_cls_refs", "__cls_refs",
231 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_LITERAL_POINTERS,
232 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
233 { ".objc_message_refs", "__message_refs",
234 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_LITERAL_POINTERS,
235 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
236 { ".objc_symbols", "__symbols",
237 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
238 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
239 { ".objc_category", "__category",
240 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
241 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
242 { ".objc_class_vars", "__class_vars",
243 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
244 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
245 { ".objc_instance_vars", "__instance_vars",
246 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
247 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
248 { ".objc_module_info", "__module_info",
249 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
250 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
251 { ".objc_selector_strs", "__selector_strs",
252 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_CSTRING_LITERALS,
253 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
254 { ".objc_image_info", "__image_info",
255 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
256 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
257 { ".objc_selector_fixup", "__sel_fixup",
258 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
259 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
260 /* Objc V1 */
261 { ".objc1_class_ext", "__class_ext",
262 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
263 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
264 { ".objc1_property_list", "__property",
265 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
266 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
267 { ".objc1_protocol_ext", "__protocol_ext",
268 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
269 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
270 { NULL, NULL, 0, 0, 0, 0}
271 };
5a5cbf72 272
a4551119 273static const mach_o_segment_name_xlat segsec_names_xlat[] =
154a1ee5 274 {
154a1ee5
TG
275 { "__TEXT", text_section_names_xlat },
276 { "__DATA", data_section_names_xlat },
5a5cbf72 277 { "__DWARF", dwarf_section_names_xlat },
a4551119 278 { "__OBJC", objc_section_names_xlat },
154a1ee5
TG
279 { NULL, NULL }
280 };
281
2ca7691a
TG
282static const char dsym_subdir[] = ".dSYM/Contents/Resources/DWARF";
283
a4551119
TG
284/* For both cases bfd-name => mach-o name and vice versa, the specific target
285 is checked before the generic. This allows a target (e.g. ppc for cstring)
286 to override the generic definition with a more specific one. */
154a1ee5 287
a4551119
TG
288/* Fetch the translation from a Mach-O section designation (segment, section)
289 as a bfd short name, if one exists. Otherwise return NULL.
290
291 Allow the segment and section names to be unterminated 16 byte arrays. */
292
293const mach_o_section_name_xlat *
294bfd_mach_o_section_data_for_mach_sect (bfd *abfd, const char *segname,
295 const char *sectname)
154a1ee5
TG
296{
297 const struct mach_o_segment_name_xlat *seg;
a4551119
TG
298 const mach_o_section_name_xlat *sec;
299 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
154a1ee5 300
a4551119
TG
301 /* First try any target-specific translations defined... */
302 if (bed->segsec_names_xlat)
303 for (seg = bed->segsec_names_xlat; seg->segname; seg++)
304 if (strncmp (seg->segname, segname, BFD_MACH_O_SEGNAME_SIZE) == 0)
305 for (sec = seg->sections; sec->mach_o_name; sec++)
306 if (strncmp (sec->mach_o_name, sectname,
307 BFD_MACH_O_SECTNAME_SIZE) == 0)
308 return sec;
8462aec7 309
a4551119 310 /* ... and then the Mach-O generic ones. */
154a1ee5 311 for (seg = segsec_names_xlat; seg->segname; seg++)
a4551119
TG
312 if (strncmp (seg->segname, segname, BFD_MACH_O_SEGNAME_SIZE) == 0)
313 for (sec = seg->sections; sec->mach_o_name; sec++)
314 if (strncmp (sec->mach_o_name, sectname,
315 BFD_MACH_O_SECTNAME_SIZE) == 0)
316 return sec;
154a1ee5 317
a4551119 318 return NULL;
53d58d96
TG
319}
320
a4551119
TG
321/* If the bfd_name for this section is a 'canonical' form for which we
322 know the Mach-O data, return the segment name and the data for the
323 Mach-O equivalent. Otherwise return NULL. */
7ba695a9 324
a4551119
TG
325const mach_o_section_name_xlat *
326bfd_mach_o_section_data_for_bfd_name (bfd *abfd, const char *bfd_name,
327 const char **segname)
53d58d96 328{
a4551119
TG
329 const struct mach_o_segment_name_xlat *seg;
330 const mach_o_section_name_xlat *sec;
331 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
332 *segname = NULL;
333
334 if (bfd_name[0] != '.')
335 return NULL;
336
337 /* First try any target-specific translations defined... */
338 if (bed->segsec_names_xlat)
339 for (seg = bed->segsec_names_xlat; seg->segname; seg++)
340 for (sec = seg->sections; sec->bfd_name; sec++)
341 if (strcmp (bfd_name, sec->bfd_name) == 0)
342 {
343 *segname = seg->segname;
344 return sec;
345 }
346
347 /* ... and then the Mach-O generic ones. */
348 for (seg = segsec_names_xlat; seg->segname; seg++)
349 for (sec = seg->sections; sec->bfd_name; sec++)
350 if (strcmp (bfd_name, sec->bfd_name) == 0)
351 {
352 *segname = seg->segname;
353 return sec;
354 }
355
356 return NULL;
357}
358
359/* Convert Mach-O section name to BFD.
360
361 Try to use standard/canonical names, for which we have tables including
362 default flag settings - which are returned. Otherwise forge a new name
363 in the form "<segmentname>.<sectionname>" this will be prefixed with
364 LC_SEGMENT. if the segment name does not begin with an underscore.
365
366 SEGNAME and SECTNAME are 16 byte arrays (they do not need to be NUL-
367 terminated if the name length is exactly 16 bytes - but must be if the name
368 length is less than 16 characters). */
369
370void
371bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, const char *segname,
372 const char *secname, const char **name,
373 flagword *flags)
374{
375 const mach_o_section_name_xlat *xlat;
53d58d96
TG
376 char *res;
377 unsigned int len;
378 const char *pfx = "";
379
a4551119
TG
380 *name = NULL;
381 *flags = SEC_NO_FLAGS;
53d58d96 382
a4551119
TG
383 /* First search for a canonical name...
384 xlat will be non-null if there is an entry for segname, secname. */
385 xlat = bfd_mach_o_section_data_for_mach_sect (abfd, segname, secname);
386 if (xlat)
387 {
388 len = strlen (xlat->bfd_name);
389 res = bfd_alloc (abfd, len+1);
390 if (res == NULL)
391 return;
392 memcpy (res, xlat->bfd_name, len+1);
393 *name = res;
394 *flags = xlat->bfd_flags;
395 return;
396 }
397
398 /* ... else we make up a bfd name from the segment concatenated with the
399 section. */
154a1ee5 400
7ba695a9 401 len = 16 + 1 + 16 + 1;
154a1ee5 402
c2f09c75
TG
403 /* Put "LC_SEGMENT." prefix if the segment name is weird (ie doesn't start
404 with an underscore. */
f1bde64c 405 if (segname[0] != '_')
c2f09c75
TG
406 {
407 static const char seg_pfx[] = "LC_SEGMENT.";
408
409 pfx = seg_pfx;
410 len += sizeof (seg_pfx) - 1;
411 }
412
154a1ee5
TG
413 res = bfd_alloc (abfd, len);
414 if (res == NULL)
8462aec7 415 return;
a4551119 416 snprintf (res, len, "%s%.16s.%.16s", pfx, segname, secname);
8462aec7 417 *name = res;
154a1ee5
TG
418}
419
a4551119 420/* Convert a bfd section name to a Mach-O segment + section name.
154a1ee5 421
a4551119
TG
422 If the name is a canonical one for which we have a Darwin match
423 return the translation table - which contains defaults for flags,
424 type, attribute and default alignment data.
425
426 Otherwise, expand the bfd_name (assumed to be in the form
427 "[LC_SEGMENT.]<segmentname>.<sectionname>") and return NULL. */
428
429static const mach_o_section_name_xlat *
154a1ee5
TG
430bfd_mach_o_convert_section_name_to_mach_o (bfd *abfd ATTRIBUTE_UNUSED,
431 asection *sect,
432 bfd_mach_o_section *section)
433{
a4551119 434 const mach_o_section_name_xlat *xlat;
154a1ee5 435 const char *name = bfd_get_section_name (abfd, sect);
a4551119 436 const char *segname;
154a1ee5
TG
437 const char *dot;
438 unsigned int len;
439 unsigned int seglen;
440 unsigned int seclen;
441
a4551119
TG
442 memset (section->segname, 0, BFD_MACH_O_SEGNAME_SIZE + 1);
443 memset (section->sectname, 0, BFD_MACH_O_SECTNAME_SIZE + 1);
444
445 /* See if is a canonical name ... */
446 xlat = bfd_mach_o_section_data_for_bfd_name (abfd, name, &segname);
447 if (xlat)
448 {
449 strcpy (section->segname, segname);
450 strcpy (section->sectname, xlat->mach_o_name);
451 return xlat;
452 }
154a1ee5 453
a4551119
TG
454 /* .. else we convert our constructed one back to Mach-O.
455 Strip LC_SEGMENT. prefix, if present. */
154a1ee5
TG
456 if (strncmp (name, "LC_SEGMENT.", 11) == 0)
457 name += 11;
458
459 /* Find a dot. */
460 dot = strchr (name, '.');
461 len = strlen (name);
462
463 /* Try to split name into segment and section names. */
464 if (dot && dot != name)
465 {
466 seglen = dot - name;
467 seclen = len - (dot + 1 - name);
468
469 if (seglen < 16 && seclen < 16)
470 {
471 memcpy (section->segname, name, seglen);
472 section->segname[seglen] = 0;
473 memcpy (section->sectname, dot + 1, seclen);
474 section->sectname[seclen] = 0;
a4551119 475 return NULL;
154a1ee5
TG
476 }
477 }
478
a4551119
TG
479 /* The segment and section names are both missing - don't make them
480 into dots. */
481 if (dot && dot == name)
482 return NULL;
483
484 /* Just duplicate the name into both segment and section. */
154a1ee5
TG
485 if (len > 16)
486 len = 16;
487 memcpy (section->segname, name, len);
488 section->segname[len] = 0;
489 memcpy (section->sectname, name, len);
490 section->sectname[len] = 0;
a4551119 491 return NULL;
3af9a47b
NC
492}
493
b2b62060
TG
494/* Return the size of an entry for section SEC.
495 Must be called only for symbol pointer section and symbol stubs
496 sections. */
497
c5012cd8 498unsigned int
b2b62060
TG
499bfd_mach_o_section_get_entry_size (bfd *abfd, bfd_mach_o_section *sec)
500{
501 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
502 {
503 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
504 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
505 return bfd_mach_o_wide_p (abfd) ? 8 : 4;
506 case BFD_MACH_O_S_SYMBOL_STUBS:
507 return sec->reserved2;
508 default:
509 BFD_FAIL ();
510 return 0;
511 }
512}
513
514/* Return the number of indirect symbols for a section.
515 Must be called only for symbol pointer section and symbol stubs
516 sections. */
517
c5012cd8 518unsigned int
b2b62060
TG
519bfd_mach_o_section_get_nbr_indirect (bfd *abfd, bfd_mach_o_section *sec)
520{
521 unsigned int elsz;
522
523 elsz = bfd_mach_o_section_get_entry_size (abfd, sec);
524 if (elsz == 0)
525 return 0;
526 else
527 return sec->size / elsz;
528}
529
530
3af9a47b
NC
531/* Copy any private info we understand from the input symbol
532 to the output symbol. */
533
154a1ee5 534bfd_boolean
116c20d2 535bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
b22161d6 536 asymbol *isymbol,
116c20d2 537 bfd *obfd ATTRIBUTE_UNUSED,
b22161d6
IS
538 asymbol *osymbol)
539{
540 bfd_mach_o_asymbol *os, *is;
541 os = (bfd_mach_o_asymbol *)osymbol;
542 is = (bfd_mach_o_asymbol *)isymbol;
543 os->n_type = is->n_type;
544 os->n_sect = is->n_sect;
545 os->n_desc = is->n_desc;
546 os->symbol.udata.i = is->symbol.udata.i;
b34976b6 547 return TRUE;
3af9a47b
NC
548}
549
550/* Copy any private info we understand from the input section
551 to the output section. */
552
154a1ee5 553bfd_boolean
116c20d2 554bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
a4551119 555 asection *isection,
116c20d2 556 bfd *obfd ATTRIBUTE_UNUSED,
a4551119
TG
557 asection *osection)
558{
559 if (osection->used_by_bfd == NULL)
560 osection->used_by_bfd = isection->used_by_bfd;
561 else
562 if (isection->used_by_bfd != NULL)
563 memcpy (osection->used_by_bfd, isection->used_by_bfd,
564 sizeof (bfd_mach_o_section));
565
566 if (osection->used_by_bfd != NULL)
567 ((bfd_mach_o_section *)osection->used_by_bfd)->bfdsection = osection;
568
b34976b6 569 return TRUE;
3af9a47b
NC
570}
571
572/* Copy any private info we understand from the input bfd
573 to the output bfd. */
574
154a1ee5 575bfd_boolean
116c20d2 576bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
3af9a47b 577{
154a1ee5
TG
578 if (bfd_get_flavour (ibfd) != bfd_target_mach_o_flavour
579 || bfd_get_flavour (obfd) != bfd_target_mach_o_flavour)
580 return TRUE;
581
3af9a47b
NC
582 BFD_ASSERT (bfd_mach_o_valid (ibfd));
583 BFD_ASSERT (bfd_mach_o_valid (obfd));
584
154a1ee5
TG
585 /* FIXME: copy commands. */
586
b34976b6 587 return TRUE;
3af9a47b
NC
588}
589
0c9ef0f0
TG
590/* This allows us to set up to 32 bits of flags (unless we invent some
591 fiendish scheme to subdivide). For now, we'll just set the file flags
592 without error checking - just overwrite. */
593
594bfd_boolean
595bfd_mach_o_bfd_set_private_flags (bfd *abfd, flagword flags)
596{
597 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
598
599 if (!mdata)
600 return FALSE;
601
602 mdata->header.flags = flags;
603 return TRUE;
604}
605
046b007d 606/* Count the total number of symbols. */
154a1ee5 607
3af9a47b 608static long
116c20d2 609bfd_mach_o_count_symbols (bfd *abfd)
3af9a47b 610{
046b007d 611 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 612
046b007d
TG
613 if (mdata->symtab == NULL)
614 return 0;
615 return mdata->symtab->nsyms;
3af9a47b
NC
616}
617
154a1ee5 618long
116c20d2 619bfd_mach_o_get_symtab_upper_bound (bfd *abfd)
3af9a47b
NC
620{
621 long nsyms = bfd_mach_o_count_symbols (abfd);
622
3af9a47b
NC
623 return ((nsyms + 1) * sizeof (asymbol *));
624}
625
154a1ee5 626long
116c20d2 627bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
3af9a47b 628{
046b007d 629 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 630 long nsyms = bfd_mach_o_count_symbols (abfd);
046b007d
TG
631 bfd_mach_o_symtab_command *sym = mdata->symtab;
632 unsigned long j;
3af9a47b
NC
633
634 if (nsyms < 0)
635 return nsyms;
636
092d27ff
TG
637 if (nsyms == 0)
638 {
639 /* Do not try to read symbols if there are none. */
640 alocation[0] = NULL;
641 return 0;
642 }
643
afbb9e17 644 if (!bfd_mach_o_read_symtab_symbols (abfd))
3af9a47b 645 {
afbb9e17
TG
646 (*_bfd_error_handler)
647 (_("bfd_mach_o_canonicalize_symtab: unable to load symbols"));
046b007d
TG
648 return 0;
649 }
3af9a47b 650
046b007d 651 BFD_ASSERT (sym->symbols != NULL);
3af9a47b 652
046b007d
TG
653 for (j = 0; j < sym->nsyms; j++)
654 alocation[j] = &sym->symbols[j].symbol;
3af9a47b 655
046b007d 656 alocation[j] = NULL;
a95a4550 657
3af9a47b
NC
658 return nsyms;
659}
660
aeefa1c9
TG
661/* Create synthetic symbols for indirect symbols. */
662
b2b62060
TG
663long
664bfd_mach_o_get_synthetic_symtab (bfd *abfd,
665 long symcount ATTRIBUTE_UNUSED,
666 asymbol **syms ATTRIBUTE_UNUSED,
667 long dynsymcount ATTRIBUTE_UNUSED,
668 asymbol **dynsyms ATTRIBUTE_UNUSED,
669 asymbol **ret)
670{
671 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
672 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
673 bfd_mach_o_symtab_command *symtab = mdata->symtab;
674 asymbol *s;
675 unsigned long count, i, j, n;
676 size_t size;
677 char *names;
678 char *nul_name;
679
680 *ret = NULL;
681
aeefa1c9 682 /* Stop now if no symbols or no indirect symbols. */
b2b62060
TG
683 if (dysymtab == NULL || symtab == NULL || symtab->symbols == NULL)
684 return 0;
685
686 if (dysymtab->nindirectsyms == 0)
687 return 0;
688
aeefa1c9
TG
689 /* We need to allocate a bfd symbol for every indirect symbol and to
690 allocate the memory for its name. */
b2b62060
TG
691 count = dysymtab->nindirectsyms;
692 size = count * sizeof (asymbol) + 1;
693
694 for (j = 0; j < count; j++)
695 {
696 unsigned int isym = dysymtab->indirect_syms[j];
aeefa1c9
TG
697
698 /* Some indirect symbols are anonymous. */
b2b62060
TG
699 if (isym < symtab->nsyms && symtab->symbols[isym].symbol.name)
700 size += strlen (symtab->symbols[isym].symbol.name) + sizeof ("$stub");
701 }
702
703 s = *ret = (asymbol *) bfd_malloc (size);
704 if (s == NULL)
705 return -1;
706 names = (char *) (s + count);
707 nul_name = names;
708 *names++ = 0;
709
710 n = 0;
711 for (i = 0; i < mdata->nsects; i++)
712 {
713 bfd_mach_o_section *sec = mdata->sections[i];
91d6fa6a 714 unsigned int first, last;
b2b62060
TG
715 bfd_vma addr;
716 bfd_vma entry_size;
717
718 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
719 {
720 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
721 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
722 case BFD_MACH_O_S_SYMBOL_STUBS:
aeefa1c9 723 /* Only these sections have indirect symbols. */
b2b62060
TG
724 first = sec->reserved1;
725 last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
726 addr = sec->addr;
727 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
728 for (j = first; j < last; j++)
729 {
730 unsigned int isym = dysymtab->indirect_syms[j];
731
732 s->flags = BSF_GLOBAL | BSF_SYNTHETIC;
733 s->section = sec->bfdsection;
734 s->value = addr - sec->addr;
735 s->udata.p = NULL;
736
737 if (isym < symtab->nsyms
738 && symtab->symbols[isym].symbol.name)
739 {
740 const char *sym = symtab->symbols[isym].symbol.name;
741 size_t len;
742
743 s->name = names;
744 len = strlen (sym);
745 memcpy (names, sym, len);
746 names += len;
747 memcpy (names, "$stub", sizeof ("$stub"));
748 names += sizeof ("$stub");
749 }
750 else
751 s->name = nul_name;
752
753 addr += entry_size;
754 s++;
755 n++;
756 }
757 break;
758 default:
759 break;
760 }
761 }
762
763 return n;
764}
765
154a1ee5 766void
116c20d2
NC
767bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
768 asymbol *symbol,
769 symbol_info *ret)
3af9a47b
NC
770{
771 bfd_symbol_info (symbol, ret);
772}
773
154a1ee5 774void
116c20d2 775bfd_mach_o_print_symbol (bfd *abfd,
91d6fa6a 776 void * afile,
116c20d2
NC
777 asymbol *symbol,
778 bfd_print_symbol_type how)
3af9a47b
NC
779{
780 FILE *file = (FILE *) afile;
15e1c58a 781 const char *name;
92bc0e80 782 bfd_mach_o_asymbol *asym = (bfd_mach_o_asymbol *)symbol;
3af9a47b
NC
783
784 switch (how)
785 {
786 case bfd_print_symbol_name:
787 fprintf (file, "%s", symbol->name);
788 break;
789 default:
91d6fa6a 790 bfd_print_symbol_vandf (abfd, (void *) file, symbol);
92bc0e80
TG
791 if (asym->n_type & BFD_MACH_O_N_STAB)
792 name = bfd_get_stab_name (asym->n_type);
15e1c58a 793 else
92bc0e80 794 switch (asym->n_type & BFD_MACH_O_N_TYPE)
15e1c58a
TG
795 {
796 case BFD_MACH_O_N_UNDF:
e0ce1005
TG
797 if (symbol->value == 0)
798 name = "UND";
799 else
800 name = "COM";
15e1c58a
TG
801 break;
802 case BFD_MACH_O_N_ABS:
803 name = "ABS";
804 break;
805 case BFD_MACH_O_N_INDR:
806 name = "INDR";
807 break;
808 case BFD_MACH_O_N_PBUD:
809 name = "PBUD";
810 break;
811 case BFD_MACH_O_N_SECT:
812 name = "SECT";
813 break;
814 default:
815 name = "???";
816 break;
817 }
818 if (name == NULL)
819 name = "";
92bc0e80
TG
820 fprintf (file, " %02x %-6s %02x %04x",
821 asym->n_type, name, asym->n_sect, asym->n_desc);
822 if ((asym->n_type & BFD_MACH_O_N_STAB) == 0
823 && (asym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_SECT)
e0ce1005 824 fprintf (file, " [%s]", symbol->section->name);
15e1c58a 825 fprintf (file, " %s", symbol->name);
3af9a47b
NC
826 }
827}
828
829static void
116c20d2 830bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype,
0b2de107 831 bfd_mach_o_cpu_subtype msubtype,
116c20d2
NC
832 enum bfd_architecture *type,
833 unsigned long *subtype)
3af9a47b
NC
834{
835 *subtype = bfd_arch_unknown;
836
837 switch (mtype)
838 {
0b2de107
TG
839 case BFD_MACH_O_CPU_TYPE_VAX:
840 *type = bfd_arch_vax;
841 break;
842 case BFD_MACH_O_CPU_TYPE_MC680x0:
843 *type = bfd_arch_m68k;
844 break;
1e8a024a
TG
845 case BFD_MACH_O_CPU_TYPE_I386:
846 *type = bfd_arch_i386;
847 *subtype = bfd_mach_i386_i386;
848 break;
849 case BFD_MACH_O_CPU_TYPE_X86_64:
850 *type = bfd_arch_i386;
851 *subtype = bfd_mach_x86_64;
852 break;
0b2de107
TG
853 case BFD_MACH_O_CPU_TYPE_MIPS:
854 *type = bfd_arch_mips;
855 break;
856 case BFD_MACH_O_CPU_TYPE_MC98000:
857 *type = bfd_arch_m98k;
858 break;
859 case BFD_MACH_O_CPU_TYPE_HPPA:
860 *type = bfd_arch_hppa;
861 break;
862 case BFD_MACH_O_CPU_TYPE_ARM:
863 *type = bfd_arch_arm;
864 switch (msubtype)
865 {
866 case BFD_MACH_O_CPU_SUBTYPE_ARM_V4T:
867 *subtype = bfd_mach_arm_4T;
868 break;
869 case BFD_MACH_O_CPU_SUBTYPE_ARM_V6:
870 *subtype = bfd_mach_arm_4T; /* Best fit ? */
871 break;
872 case BFD_MACH_O_CPU_SUBTYPE_ARM_V5TEJ:
873 *subtype = bfd_mach_arm_5TE;
874 break;
875 case BFD_MACH_O_CPU_SUBTYPE_ARM_XSCALE:
876 *subtype = bfd_mach_arm_XScale;
877 break;
878 case BFD_MACH_O_CPU_SUBTYPE_ARM_V7:
879 *subtype = bfd_mach_arm_5TE; /* Best fit ? */
880 break;
881 case BFD_MACH_O_CPU_SUBTYPE_ARM_ALL:
882 default:
883 break;
884 }
885 break;
886 case BFD_MACH_O_CPU_TYPE_MC88000:
887 *type = bfd_arch_m88k;
888 break;
1e8a024a
TG
889 case BFD_MACH_O_CPU_TYPE_SPARC:
890 *type = bfd_arch_sparc;
891 *subtype = bfd_mach_sparc;
892 break;
0b2de107
TG
893 case BFD_MACH_O_CPU_TYPE_I860:
894 *type = bfd_arch_i860;
895 break;
896 case BFD_MACH_O_CPU_TYPE_ALPHA:
897 *type = bfd_arch_alpha;
898 break;
1e8a024a
TG
899 case BFD_MACH_O_CPU_TYPE_POWERPC:
900 *type = bfd_arch_powerpc;
c2f09c75 901 *subtype = bfd_mach_ppc;
1e8a024a
TG
902 break;
903 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
904 *type = bfd_arch_powerpc;
c2f09c75 905 *subtype = bfd_mach_ppc64;
1e8a024a 906 break;
3af9a47b 907 default:
1e8a024a
TG
908 *type = bfd_arch_unknown;
909 break;
3af9a47b
NC
910 }
911}
a95a4550 912
154a1ee5 913static bfd_boolean
116c20d2
NC
914bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
915{
46d1c23b 916 struct mach_o_header_external raw;
1e8a024a
TG
917 unsigned int size;
918
c2f09c75 919 size = mach_o_wide_p (header) ?
154a1ee5 920 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
116c20d2 921
46d1c23b
TG
922 bfd_h_put_32 (abfd, header->magic, raw.magic);
923 bfd_h_put_32 (abfd, header->cputype, raw.cputype);
924 bfd_h_put_32 (abfd, header->cpusubtype, raw.cpusubtype);
925 bfd_h_put_32 (abfd, header->filetype, raw.filetype);
926 bfd_h_put_32 (abfd, header->ncmds, raw.ncmds);
927 bfd_h_put_32 (abfd, header->sizeofcmds, raw.sizeofcmds);
928 bfd_h_put_32 (abfd, header->flags, raw.flags);
116c20d2 929
c2f09c75 930 if (mach_o_wide_p (header))
46d1c23b 931 bfd_h_put_32 (abfd, header->reserved, raw.reserved);
1e8a024a 932
c2f09c75 933 if (bfd_seek (abfd, 0, SEEK_SET) != 0
46d1c23b 934 || bfd_bwrite (&raw, size, abfd) != size)
154a1ee5 935 return FALSE;
116c20d2 936
154a1ee5 937 return TRUE;
116c20d2
NC
938}
939
940static int
ab273af8 941bfd_mach_o_write_thread (bfd *abfd, bfd_mach_o_load_command *command)
116c20d2
NC
942{
943 bfd_mach_o_thread_command *cmd = &command->command.thread;
944 unsigned int i;
46d1c23b 945 struct mach_o_thread_command_external raw;
92bc0e80 946 unsigned int offset;
116c20d2
NC
947
948 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
949 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
950
951 offset = 8;
116c20d2
NC
952 for (i = 0; i < cmd->nflavours; i++)
953 {
954 BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
46d1c23b
TG
955 BFD_ASSERT (cmd->flavours[i].offset ==
956 (command->offset + offset + BFD_MACH_O_LC_SIZE));
116c20d2 957
46d1c23b
TG
958 bfd_h_put_32 (abfd, cmd->flavours[i].flavour, raw.flavour);
959 bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), raw.count);
116c20d2 960
c2f09c75 961 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
46d1c23b 962 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
116c20d2
NC
963 return -1;
964
46d1c23b 965 offset += cmd->flavours[i].size + sizeof (raw);
116c20d2
NC
966 }
967
968 return 0;
969}
970
92bc0e80
TG
971long
972bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
973 asection *asect)
974{
975 return (asect->reloc_count + 1) * sizeof (arelent *);
976}
977
b32e07d7 978static int
46d1c23b
TG
979bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
980 struct mach_o_reloc_info_external *raw,
b32e07d7 981 arelent *res, asymbol **syms)
92bc0e80 982{
046b007d 983 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
92bc0e80 984 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
b32e07d7
TG
985 bfd_mach_o_reloc_info reloc;
986 bfd_vma addr;
987 bfd_vma symnum;
988 asymbol **sym;
989
46d1c23b
TG
990 addr = bfd_get_32 (abfd, raw->r_address);
991 symnum = bfd_get_32 (abfd, raw->r_symbolnum);
b32e07d7
TG
992
993 if (addr & BFD_MACH_O_SR_SCATTERED)
994 {
995 unsigned int j;
996
997 /* Scattered relocation.
998 Extract section and offset from r_value. */
999 res->sym_ptr_ptr = NULL;
1000 res->addend = 0;
1001 for (j = 0; j < mdata->nsects; j++)
1002 {
1003 bfd_mach_o_section *sect = mdata->sections[j];
1004 if (symnum >= sect->addr && symnum < sect->addr + sect->size)
1005 {
1006 res->sym_ptr_ptr = sect->bfdsection->symbol_ptr_ptr;
1007 res->addend = symnum - sect->addr;
1008 break;
1009 }
1010 }
1011 res->address = BFD_MACH_O_GET_SR_ADDRESS (addr);
1012 reloc.r_type = BFD_MACH_O_GET_SR_TYPE (addr);
1013 reloc.r_length = BFD_MACH_O_GET_SR_LENGTH (addr);
1014 reloc.r_pcrel = addr & BFD_MACH_O_SR_PCREL;
1015 reloc.r_scattered = 1;
1016 }
1017 else
1018 {
1019 unsigned int num = BFD_MACH_O_GET_R_SYMBOLNUM (symnum);
1020 res->addend = 0;
1021 res->address = addr;
1022 if (symnum & BFD_MACH_O_R_EXTERN)
06988dfc
TG
1023 {
1024 sym = syms + num;
1025 reloc.r_extern = 1;
1026 }
b32e07d7
TG
1027 else
1028 {
1029 BFD_ASSERT (num != 0);
1030 BFD_ASSERT (num <= mdata->nsects);
1031 sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
1523fa24
TG
1032 /* For a symbol defined in section S, the addend (stored in the
1033 binary) contains the address of the section. To comply with
1034 bfd conventio, substract the section address.
1035 Use the address from the header, so that the user can modify
1036 the vma of the section. */
1037 res->addend = -mdata->sections[num - 1]->addr;
06988dfc 1038 reloc.r_extern = 0;
b32e07d7
TG
1039 }
1040 res->sym_ptr_ptr = sym;
1041 reloc.r_type = BFD_MACH_O_GET_R_TYPE (symnum);
1042 reloc.r_length = BFD_MACH_O_GET_R_LENGTH (symnum);
1043 reloc.r_pcrel = (symnum & BFD_MACH_O_R_PCREL) ? 1 : 0;
1044 reloc.r_scattered = 0;
1045 }
1046
1047 if (!(*bed->_bfd_mach_o_swap_reloc_in)(res, &reloc))
1048 return -1;
1049 return 0;
1050}
1051
1052static int
1053bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
1054 unsigned long count,
1055 arelent *res, asymbol **syms)
1056{
92bc0e80 1057 unsigned long i;
46d1c23b 1058 struct mach_o_reloc_info_external *native_relocs;
92bc0e80
TG
1059 bfd_size_type native_size;
1060
92bc0e80 1061 /* Allocate and read relocs. */
b32e07d7 1062 native_size = count * BFD_MACH_O_RELENT_SIZE;
46d1c23b
TG
1063 native_relocs =
1064 (struct mach_o_reloc_info_external *) bfd_malloc (native_size);
92bc0e80
TG
1065 if (native_relocs == NULL)
1066 return -1;
1067
b32e07d7 1068 if (bfd_seek (abfd, filepos, SEEK_SET) != 0
92bc0e80 1069 || bfd_bread (native_relocs, native_size, abfd) != native_size)
b32e07d7
TG
1070 goto err;
1071
1072 for (i = 0; i < count; i++)
92bc0e80 1073 {
46d1c23b
TG
1074 if (bfd_mach_o_canonicalize_one_reloc (abfd, &native_relocs[i],
1075 &res[i], syms) < 0)
b32e07d7 1076 goto err;
92bc0e80 1077 }
b32e07d7
TG
1078 free (native_relocs);
1079 return i;
1080 err:
1081 free (native_relocs);
1082 return -1;
1083}
1084
1085long
1086bfd_mach_o_canonicalize_reloc (bfd *abfd, asection *asect,
1087 arelent **rels, asymbol **syms)
1088{
1089 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
1090 unsigned long i;
1091 arelent *res;
1092
1093 if (asect->reloc_count == 0)
1094 return 0;
1095
1096 /* No need to go further if we don't know how to read relocs. */
1097 if (bed->_bfd_mach_o_swap_reloc_in == NULL)
1098 return 0;
92bc0e80 1099
dff55db0 1100 if (asect->relocation == NULL)
92bc0e80 1101 {
dff55db0
TG
1102 res = bfd_malloc (asect->reloc_count * sizeof (arelent));
1103 if (res == NULL)
1104 return -1;
1105
1106 if (bfd_mach_o_canonicalize_relocs (abfd, asect->rel_filepos,
1107 asect->reloc_count, res, syms) < 0)
1108 {
1109 free (res);
1110 return -1;
1111 }
1112 asect->relocation = res;
92bc0e80
TG
1113 }
1114
dff55db0 1115 res = asect->relocation;
92bc0e80 1116 for (i = 0; i < asect->reloc_count; i++)
b32e07d7
TG
1117 rels[i] = &res[i];
1118 rels[i] = NULL;
92bc0e80 1119
b32e07d7
TG
1120 return i;
1121}
92bc0e80 1122
b32e07d7
TG
1123long
1124bfd_mach_o_get_dynamic_reloc_upper_bound (bfd *abfd)
1125{
1126 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
92bc0e80 1127
b32e07d7
TG
1128 if (mdata->dysymtab == NULL)
1129 return 1;
dff55db0 1130 return (mdata->dysymtab->nextrel + mdata->dysymtab->nlocrel + 1)
b32e07d7
TG
1131 * sizeof (arelent *);
1132}
92bc0e80 1133
b32e07d7
TG
1134long
1135bfd_mach_o_canonicalize_dynamic_reloc (bfd *abfd, arelent **rels,
1136 struct bfd_symbol **syms)
1137{
1138 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1139 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
1140 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
1141 unsigned long i;
1142 arelent *res;
1143
1144 if (dysymtab == NULL)
1145 return 0;
1146 if (dysymtab->nextrel == 0 && dysymtab->nlocrel == 0)
1147 return 0;
1148
1149 /* No need to go further if we don't know how to read relocs. */
1150 if (bed->_bfd_mach_o_swap_reloc_in == NULL)
1151 return 0;
1152
dff55db0 1153 if (mdata->dyn_reloc_cache == NULL)
b32e07d7 1154 {
dff55db0
TG
1155 res = bfd_malloc ((dysymtab->nextrel + dysymtab->nlocrel)
1156 * sizeof (arelent));
1157 if (res == NULL)
1158 return -1;
b32e07d7 1159
dff55db0
TG
1160 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->extreloff,
1161 dysymtab->nextrel, res, syms) < 0)
1162 {
1163 free (res);
1164 return -1;
1165 }
1166
1167 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->locreloff,
1168 dysymtab->nlocrel,
1169 res + dysymtab->nextrel, syms) < 0)
1170 {
1171 free (res);
1172 return -1;
1173 }
1174
1175 mdata->dyn_reloc_cache = res;
b32e07d7
TG
1176 }
1177
dff55db0 1178 res = mdata->dyn_reloc_cache;
b32e07d7
TG
1179 for (i = 0; i < dysymtab->nextrel + dysymtab->nlocrel; i++)
1180 rels[i] = &res[i];
1181 rels[i] = NULL;
92bc0e80
TG
1182 return i;
1183}
1184
1185static bfd_boolean
ab273af8 1186bfd_mach_o_write_relocs (bfd *abfd, bfd_mach_o_section *section)
92bc0e80 1187{
92bc0e80
TG
1188 unsigned int i;
1189 arelent **entries;
1190 asection *sec;
1191 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
1192
1193 sec = section->bfdsection;
1194 if (sec->reloc_count == 0)
1195 return TRUE;
1196
1197 if (bed->_bfd_mach_o_swap_reloc_out == NULL)
1198 return TRUE;
1199
92bc0e80
TG
1200 if (bfd_seek (abfd, section->reloff, SEEK_SET) != 0)
1201 return FALSE;
1202
1203 /* Convert and write. */
1204 entries = section->bfdsection->orelocation;
1205 for (i = 0; i < section->nreloc; i++)
1206 {
1207 arelent *rel = entries[i];
46d1c23b 1208 struct mach_o_reloc_info_external raw;
92bc0e80
TG
1209 bfd_mach_o_reloc_info info, *pinfo = &info;
1210
1211 /* Convert relocation to an intermediate representation. */
1212 if (!(*bed->_bfd_mach_o_swap_reloc_out) (rel, pinfo))
1213 return FALSE;
1214
1215 /* Lower the relocation info. */
1216 if (pinfo->r_scattered)
1217 {
1218 unsigned long v;
1219
1220 v = BFD_MACH_O_SR_SCATTERED
1221 | (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0)
1222 | BFD_MACH_O_SET_SR_LENGTH(pinfo->r_length)
1223 | BFD_MACH_O_SET_SR_TYPE(pinfo->r_type)
1224 | BFD_MACH_O_SET_SR_ADDRESS(pinfo->r_address);
46d1c23b
TG
1225 /* Note: scattered relocs have field in reverse order... */
1226 bfd_put_32 (abfd, v, raw.r_address);
1227 bfd_put_32 (abfd, pinfo->r_value, raw.r_symbolnum);
92bc0e80
TG
1228 }
1229 else
1230 {
1231 unsigned long v;
1232
46d1c23b 1233 bfd_put_32 (abfd, pinfo->r_address, raw.r_address);
92bc0e80
TG
1234 v = BFD_MACH_O_SET_R_SYMBOLNUM (pinfo->r_value)
1235 | (pinfo->r_pcrel ? BFD_MACH_O_R_PCREL : 0)
1236 | BFD_MACH_O_SET_R_LENGTH (pinfo->r_length)
1237 | (pinfo->r_extern ? BFD_MACH_O_R_EXTERN : 0)
1238 | BFD_MACH_O_SET_R_TYPE (pinfo->r_type);
46d1c23b 1239 bfd_put_32 (abfd, v, raw.r_symbolnum);
92bc0e80
TG
1240 }
1241
46d1c23b 1242 if (bfd_bwrite (&raw, BFD_MACH_O_RELENT_SIZE, abfd)
92bc0e80
TG
1243 != BFD_MACH_O_RELENT_SIZE)
1244 return FALSE;
1245 }
1246 return TRUE;
1247}
1248
116c20d2 1249static int
ab273af8 1250bfd_mach_o_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
116c20d2 1251{
46d1c23b
TG
1252 struct mach_o_section_32_external raw;
1253
1254 memcpy (raw.sectname, section->sectname, 16);
72b5104c 1255 memcpy (raw.segname, section->segname, 16);
46d1c23b
TG
1256 bfd_h_put_32 (abfd, section->addr, raw.addr);
1257 bfd_h_put_32 (abfd, section->size, raw.size);
1258 bfd_h_put_32 (abfd, section->offset, raw.offset);
1259 bfd_h_put_32 (abfd, section->align, raw.align);
1260 bfd_h_put_32 (abfd, section->reloff, raw.reloff);
1261 bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
1262 bfd_h_put_32 (abfd, section->flags, raw.flags);
1263 bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
1264 bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
1265
1266 if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
92bc0e80 1267 != BFD_MACH_O_SECTION_SIZE)
116c20d2
NC
1268 return -1;
1269
1270 return 0;
1271}
1272
1273static int
ab273af8 1274bfd_mach_o_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
116c20d2 1275{
46d1c23b
TG
1276 struct mach_o_section_64_external raw;
1277
1278 memcpy (raw.sectname, section->sectname, 16);
1279 memcpy (raw.segname, section->segname, 16);
1280 bfd_h_put_64 (abfd, section->addr, raw.addr);
1281 bfd_h_put_64 (abfd, section->size, raw.size);
1282 bfd_h_put_32 (abfd, section->offset, raw.offset);
1283 bfd_h_put_32 (abfd, section->align, raw.align);
1284 bfd_h_put_32 (abfd, section->reloff, raw.reloff);
1285 bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
1286 bfd_h_put_32 (abfd, section->flags, raw.flags);
1287 bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
1288 bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
1289 bfd_h_put_32 (abfd, section->reserved3, raw.reserved3);
1290
1291 if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
92bc0e80 1292 != BFD_MACH_O_SECTION_64_SIZE)
116c20d2
NC
1293 return -1;
1294
1e8a024a
TG
1295 return 0;
1296}
1297
1298static int
ab273af8 1299bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 1300{
46d1c23b 1301 struct mach_o_segment_command_32_external raw;
1e8a024a 1302 bfd_mach_o_segment_command *seg = &command->command.segment;
f1bde64c 1303 bfd_mach_o_section *sec;
1e8a024a 1304
c2f09c75
TG
1305 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1306
f1bde64c
TG
1307 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1308 if (!bfd_mach_o_write_relocs (abfd, sec))
92bc0e80 1309 return -1;
c2f09c75 1310
46d1c23b
TG
1311 memcpy (raw.segname, seg->segname, 16);
1312 bfd_h_put_32 (abfd, seg->vmaddr, raw.vmaddr);
1313 bfd_h_put_32 (abfd, seg->vmsize, raw.vmsize);
1314 bfd_h_put_32 (abfd, seg->fileoff, raw.fileoff);
1315 bfd_h_put_32 (abfd, seg->filesize, raw.filesize);
1316 bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
1317 bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
1318 bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
1319 bfd_h_put_32 (abfd, seg->flags, raw.flags);
c2f09c75 1320
46d1c23b
TG
1321 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1322 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
c2f09c75 1323 return -1;
1e8a024a 1324
f1bde64c
TG
1325 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1326 if (bfd_mach_o_write_section_32 (abfd, sec))
92bc0e80 1327 return -1;
1e8a024a 1328
116c20d2
NC
1329 return 0;
1330}
1331
1e8a024a 1332static int
ab273af8 1333bfd_mach_o_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 1334{
46d1c23b 1335 struct mach_o_segment_command_64_external raw;
c2f09c75 1336 bfd_mach_o_segment_command *seg = &command->command.segment;
f1bde64c 1337 bfd_mach_o_section *sec;
c2f09c75
TG
1338
1339 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
1340
f1bde64c
TG
1341 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1342 if (!bfd_mach_o_write_relocs (abfd, sec))
92bc0e80 1343 return -1;
c2f09c75 1344
46d1c23b
TG
1345 memcpy (raw.segname, seg->segname, 16);
1346 bfd_h_put_64 (abfd, seg->vmaddr, raw.vmaddr);
1347 bfd_h_put_64 (abfd, seg->vmsize, raw.vmsize);
1348 bfd_h_put_64 (abfd, seg->fileoff, raw.fileoff);
1349 bfd_h_put_64 (abfd, seg->filesize, raw.filesize);
1350 bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
1351 bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
1352 bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
1353 bfd_h_put_32 (abfd, seg->flags, raw.flags);
1354
1355 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1356 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
c2f09c75
TG
1357 return -1;
1358
f1bde64c
TG
1359 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1360 if (bfd_mach_o_write_section_64 (abfd, sec))
92bc0e80 1361 return -1;
c2f09c75 1362
c2f09c75 1363 return 0;
1e8a024a
TG
1364}
1365
c2f09c75 1366static bfd_boolean
ab273af8 1367bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
116c20d2 1368{
046b007d 1369 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
116c20d2 1370 bfd_mach_o_symtab_command *sym = &command->command.symtab;
116c20d2 1371 unsigned long i;
c2f09c75 1372 unsigned int wide = bfd_mach_o_wide_p (abfd);
046b007d 1373 unsigned int symlen = wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
c2f09c75
TG
1374 struct bfd_strtab_hash *strtab;
1375 asymbol **symbols = bfd_get_outsymbols (abfd);
1376
1377 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1378
1379 /* Write the symbols first. */
92bc0e80
TG
1380 mdata->filelen = FILE_ALIGN(mdata->filelen, wide ? 3 : 2);
1381 sym->symoff = mdata->filelen;
c2f09c75
TG
1382 if (bfd_seek (abfd, sym->symoff, SEEK_SET) != 0)
1383 return FALSE;
1384
1385 sym->nsyms = bfd_get_symcount (abfd);
92bc0e80 1386 mdata->filelen += sym->nsyms * symlen;
c2f09c75
TG
1387
1388 strtab = _bfd_stringtab_init ();
1389 if (strtab == NULL)
1390 return FALSE;
116c20d2 1391
a4551119
TG
1392 if (sym->nsyms > 0)
1393 /* Although we don't strictly need to do this, for compatibility with
1394 Darwin system tools, actually output an empty string for the index
1395 0 entry. */
1396 _bfd_stringtab_add (strtab, "", TRUE, FALSE);
1397
116c20d2
NC
1398 for (i = 0; i < sym->nsyms; i++)
1399 {
91d6fa6a 1400 bfd_size_type str_index;
92bc0e80 1401 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
7f307238 1402
92bc0e80 1403 if (s->symbol.name == 0 || s->symbol.name[0] == '\0')
7f307238 1404 /* An index of 0 always means the empty string. */
91d6fa6a 1405 str_index = 0;
c2f09c75
TG
1406 else
1407 {
91d6fa6a 1408 str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
7f307238 1409
91d6fa6a 1410 if (str_index == (bfd_size_type) -1)
c2f09c75
TG
1411 goto err;
1412 }
46d1c23b 1413
c2f09c75 1414 if (wide)
46d1c23b
TG
1415 {
1416 struct mach_o_nlist_64_external raw;
1417
1418 bfd_h_put_32 (abfd, str_index, raw.n_strx);
1419 bfd_h_put_8 (abfd, s->n_type, raw.n_type);
1420 bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
1421 bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
1422 bfd_h_put_64 (abfd, s->symbol.section->vma + s->symbol.value,
1423 raw.n_value);
1424
1425 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1426 goto err;
1427 }
c2f09c75 1428 else
46d1c23b
TG
1429 {
1430 struct mach_o_nlist_external raw;
116c20d2 1431
46d1c23b
TG
1432 bfd_h_put_32 (abfd, str_index, raw.n_strx);
1433 bfd_h_put_8 (abfd, s->n_type, raw.n_type);
1434 bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
1435 bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
1436 bfd_h_put_32 (abfd, s->symbol.section->vma + s->symbol.value,
1437 raw.n_value);
1438
1439 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1440 goto err;
1441 }
116c20d2 1442 }
c2f09c75 1443 sym->strsize = _bfd_stringtab_size (strtab);
92bc0e80
TG
1444 sym->stroff = mdata->filelen;
1445 mdata->filelen += sym->strsize;
116c20d2 1446
c2f09c75
TG
1447 if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
1448 goto err;
1449 _bfd_stringtab_free (strtab);
116c20d2 1450
c2f09c75 1451 /* The command. */
46d1c23b
TG
1452 {
1453 struct mach_o_symtab_command_external raw;
116c20d2 1454
46d1c23b
TG
1455 bfd_h_put_32 (abfd, sym->symoff, raw.symoff);
1456 bfd_h_put_32 (abfd, sym->nsyms, raw.nsyms);
1457 bfd_h_put_32 (abfd, sym->stroff, raw.stroff);
1458 bfd_h_put_32 (abfd, sym->strsize, raw.strsize);
1459
1460 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1461 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1462 return FALSE;
1463 }
116c20d2 1464
c2f09c75 1465 return TRUE;
116c20d2 1466
c2f09c75
TG
1467 err:
1468 _bfd_stringtab_free (strtab);
1469 return FALSE;
116c20d2
NC
1470}
1471
7f307238
IS
1472/* Write a dysymtab command.
1473 TODO: Possibly coalesce writes of smaller objects. */
1474
1475static bfd_boolean
1476bfd_mach_o_write_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
1477{
1478 bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
1479
1480 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
1481
1482 if (cmd->nmodtab != 0)
1483 {
1484 unsigned int i;
1485
1486 if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0)
1487 return FALSE;
1488
1489 for (i = 0; i < cmd->nmodtab; i++)
1490 {
1491 bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
1492 unsigned int iinit;
1493 unsigned int ninit;
1494
1495 iinit = module->iinit & 0xffff;
1496 iinit |= ((module->iterm & 0xffff) << 16);
1497
1498 ninit = module->ninit & 0xffff;
1499 ninit |= ((module->nterm & 0xffff) << 16);
1500
1501 if (bfd_mach_o_wide_p (abfd))
1502 {
1503 struct mach_o_dylib_module_64_external w;
1504
1505 bfd_h_put_32 (abfd, module->module_name_idx, &w.module_name);
1506 bfd_h_put_32 (abfd, module->iextdefsym, &w.iextdefsym);
1507 bfd_h_put_32 (abfd, module->nextdefsym, &w.nextdefsym);
1508 bfd_h_put_32 (abfd, module->irefsym, &w.irefsym);
1509 bfd_h_put_32 (abfd, module->nrefsym, &w.nrefsym);
1510 bfd_h_put_32 (abfd, module->ilocalsym, &w.ilocalsym);
1511 bfd_h_put_32 (abfd, module->nlocalsym, &w.nlocalsym);
1512 bfd_h_put_32 (abfd, module->iextrel, &w.iextrel);
1513 bfd_h_put_32 (abfd, module->nextrel, &w.nextrel);
1514 bfd_h_put_32 (abfd, iinit, &w.iinit_iterm);
1515 bfd_h_put_32 (abfd, ninit, &w.ninit_nterm);
1516 bfd_h_put_64 (abfd, module->objc_module_info_addr,
1517 &w.objc_module_info_addr);
1518 bfd_h_put_32 (abfd, module->objc_module_info_size,
1519 &w.objc_module_info_size);
1520
1521 if (bfd_bwrite ((void *) &w, sizeof (w), abfd) != sizeof (w))
1522 return FALSE;
1523 }
1524 else
1525 {
1526 struct mach_o_dylib_module_external n;
1527
1528 bfd_h_put_32 (abfd, module->module_name_idx, &n.module_name);
1529 bfd_h_put_32 (abfd, module->iextdefsym, &n.iextdefsym);
1530 bfd_h_put_32 (abfd, module->nextdefsym, &n.nextdefsym);
1531 bfd_h_put_32 (abfd, module->irefsym, &n.irefsym);
1532 bfd_h_put_32 (abfd, module->nrefsym, &n.nrefsym);
1533 bfd_h_put_32 (abfd, module->ilocalsym, &n.ilocalsym);
1534 bfd_h_put_32 (abfd, module->nlocalsym, &n.nlocalsym);
1535 bfd_h_put_32 (abfd, module->iextrel, &n.iextrel);
1536 bfd_h_put_32 (abfd, module->nextrel, &n.nextrel);
1537 bfd_h_put_32 (abfd, iinit, &n.iinit_iterm);
1538 bfd_h_put_32 (abfd, ninit, &n.ninit_nterm);
1539 bfd_h_put_32 (abfd, module->objc_module_info_addr,
1540 &n.objc_module_info_addr);
1541 bfd_h_put_32 (abfd, module->objc_module_info_size,
1542 &n.objc_module_info_size);
1543
1544 if (bfd_bwrite ((void *) &n, sizeof (n), abfd) != sizeof (n))
1545 return FALSE;
1546 }
1547 }
1548 }
1549
1550 if (cmd->ntoc != 0)
1551 {
1552 unsigned int i;
1553
1554 if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
1555 return FALSE;
1556
1557 for (i = 0; i < cmd->ntoc; i++)
1558 {
1559 struct mach_o_dylib_table_of_contents_external raw;
1560 bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
1561
1562 bfd_h_put_32 (abfd, toc->symbol_index, &raw.symbol_index);
1563 bfd_h_put_32 (abfd, toc->module_index, &raw.module_index);
1564
1565 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1566 return FALSE;
1567 }
1568 }
1569
1570 if (cmd->nindirectsyms > 0)
1571 {
1572 unsigned int i;
1573
1574 if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
1575 return FALSE;
1576
1577 for (i = 0; i < cmd->nindirectsyms; ++i)
1578 {
1579 unsigned char raw[4];
1580
1581 bfd_h_put_32 (abfd, cmd->indirect_syms[i], &raw);
1582 if (bfd_bwrite (raw, sizeof (raw), abfd) != sizeof (raw))
1583 return FALSE;
1584 }
1585 }
1586
1587 if (cmd->nextrefsyms != 0)
1588 {
1589 unsigned int i;
1590
1591 if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
1592 return FALSE;
1593
1594 for (i = 0; i < cmd->nextrefsyms; i++)
1595 {
1596 unsigned long v;
1597 unsigned char raw[4];
1598 bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
1599
1600 /* Fields isym and flags are written as bit-fields, thus we need
1601 a specific processing for endianness. */
1602
1603 if (bfd_big_endian (abfd))
1604 {
1605 v = ((ref->isym & 0xffffff) << 8);
1606 v |= ref->flags & 0xff;
1607 }
1608 else
1609 {
1610 v = ref->isym & 0xffffff;
1611 v |= ((ref->flags & 0xff) << 24);
1612 }
1613
1614 bfd_h_put_32 (abfd, v, raw);
1615 if (bfd_bwrite (raw, sizeof (raw), abfd) != sizeof (raw))
1616 return FALSE;
1617 }
1618 }
1619
1620 /* The command. */
1621 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0)
1622 return FALSE;
1623 else
1624 {
1625 struct mach_o_dysymtab_command_external raw;
1626
1627 bfd_h_put_32 (abfd, cmd->ilocalsym, &raw.ilocalsym);
1628 bfd_h_put_32 (abfd, cmd->nlocalsym, &raw.nlocalsym);
1629 bfd_h_put_32 (abfd, cmd->iextdefsym, &raw.iextdefsym);
1630 bfd_h_put_32 (abfd, cmd->nextdefsym, &raw.nextdefsym);
1631 bfd_h_put_32 (abfd, cmd->iundefsym, &raw.iundefsym);
1632 bfd_h_put_32 (abfd, cmd->nundefsym, &raw.nundefsym);
1633 bfd_h_put_32 (abfd, cmd->tocoff, &raw.tocoff);
1634 bfd_h_put_32 (abfd, cmd->ntoc, &raw.ntoc);
1635 bfd_h_put_32 (abfd, cmd->modtaboff, &raw.modtaboff);
1636 bfd_h_put_32 (abfd, cmd->nmodtab, &raw.nmodtab);
1637 bfd_h_put_32 (abfd, cmd->extrefsymoff, &raw.extrefsymoff);
1638 bfd_h_put_32 (abfd, cmd->nextrefsyms, &raw.nextrefsyms);
1639 bfd_h_put_32 (abfd, cmd->indirectsymoff, &raw.indirectsymoff);
1640 bfd_h_put_32 (abfd, cmd->nindirectsyms, &raw.nindirectsyms);
1641 bfd_h_put_32 (abfd, cmd->extreloff, &raw.extreloff);
1642 bfd_h_put_32 (abfd, cmd->nextrel, &raw.nextrel);
1643 bfd_h_put_32 (abfd, cmd->locreloff, &raw.locreloff);
1644 bfd_h_put_32 (abfd, cmd->nlocrel, &raw.nlocrel);
1645
1646 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1647 return FALSE;
1648 }
1649
1650 return TRUE;
1651}
1652
1653static unsigned
b22161d6 1654bfd_mach_o_primary_symbol_sort_key (bfd_mach_o_asymbol *s)
7f307238 1655{
b22161d6 1656 unsigned mtyp = s->n_type & BFD_MACH_O_N_TYPE;
68588f95
IS
1657
1658 /* Just leave debug symbols where they are (pretend they are local, and
1659 then they will just be sorted on position). */
b22161d6 1660 if (s->n_type & BFD_MACH_O_N_STAB)
68588f95
IS
1661 return 0;
1662
7f307238 1663 /* Local (we should never see an undefined local AFAICT). */
b22161d6 1664 if (! (s->n_type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT)))
7f307238
IS
1665 return 0;
1666
1667 /* Common symbols look like undefined externs. */
68588f95 1668 if (mtyp == BFD_MACH_O_N_UNDF)
7f307238
IS
1669 return 2;
1670
b22161d6 1671 /* A defined non-local, non-debug symbol. */
7f307238
IS
1672 return 1;
1673}
1674
1675static int
1676bfd_mach_o_cf_symbols (const void *a, const void *b)
1677{
1678 bfd_mach_o_asymbol *sa = *(bfd_mach_o_asymbol **) a;
1679 bfd_mach_o_asymbol *sb = *(bfd_mach_o_asymbol **) b;
1680 unsigned int soa, sob;
1681
b22161d6
IS
1682 soa = bfd_mach_o_primary_symbol_sort_key (sa);
1683 sob = bfd_mach_o_primary_symbol_sort_key (sb);
7f307238
IS
1684 if (soa < sob)
1685 return -1;
1686
1687 if (soa > sob)
1688 return 1;
1689
68588f95 1690 /* If it's local or stab, just preserve the input order. */
7f307238
IS
1691 if (soa == 0)
1692 {
1693 if (sa->symbol.udata.i < sb->symbol.udata.i)
1694 return -1;
1695 if (sa->symbol.udata.i > sb->symbol.udata.i)
1696 return 1;
b22161d6
IS
1697
1698 /* This is probably an error. */
7f307238
IS
1699 return 0;
1700 }
1701
b22161d6
IS
1702 /* The second sort key is name. */
1703 return strcmp (sa->symbol.name, sb->symbol.name);
7f307238
IS
1704}
1705
1706/* Process the symbols.
1707
1708 This should be OK for single-module files - but it is not likely to work
1709 for multi-module shared libraries.
1710
1711 (a) If the application has not filled in the relevant mach-o fields, make
1712 an estimate.
1713
1714 (b) Order them, like this:
1715 ( i) local.
1716 (unsorted)
1717 ( ii) external defined
1718 (by name)
b22161d6 1719 (iii) external undefined/common
7f307238
IS
1720 (by name)
1721 ( iv) common
1722 (by name)
b22161d6 1723*/
92bc0e80
TG
1724
1725static bfd_boolean
b22161d6 1726bfd_mach_o_mangle_symbols (bfd *abfd)
92bc0e80
TG
1727{
1728 unsigned long i;
1729 asymbol **symbols = bfd_get_outsymbols (abfd);
1730
7f307238
IS
1731 if (symbols == NULL || bfd_get_symcount (abfd) == 0)
1732 return TRUE;
1733
92bc0e80
TG
1734 for (i = 0; i < bfd_get_symcount (abfd); i++)
1735 {
1736 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1737
b22161d6
IS
1738 /* We use this value, which is out-of-range as a symbol index, to signal
1739 that the mach-o-specific data are not filled in and need to be created
1740 from the bfd values. It is much preferable for the application to do
1741 this, since more meaningful diagnostics can be made that way. */
1742
1743 if (s->symbol.udata.i == SYM_MACHO_FIELDS_UNSET)
92bc0e80 1744 {
b22161d6
IS
1745 /* No symbol information has been set - therefore determine
1746 it from the bfd symbol flags/info. */
92bc0e80
TG
1747 if (s->symbol.section == bfd_abs_section_ptr)
1748 s->n_type = BFD_MACH_O_N_ABS;
1749 else if (s->symbol.section == bfd_und_section_ptr)
1750 {
1751 s->n_type = BFD_MACH_O_N_UNDF;
1752 if (s->symbol.flags & BSF_WEAK)
1753 s->n_desc |= BFD_MACH_O_N_WEAK_REF;
7f307238
IS
1754 /* mach-o automatically makes undefined symbols extern. */
1755 s->n_type |= BFD_MACH_O_N_EXT;
b22161d6 1756 s->symbol.flags |= BSF_GLOBAL;
92bc0e80
TG
1757 }
1758 else if (s->symbol.section == bfd_com_section_ptr)
b22161d6
IS
1759 {
1760 s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
1761 s->symbol.flags |= BSF_GLOBAL;
1762 }
92bc0e80
TG
1763 else
1764 s->n_type = BFD_MACH_O_N_SECT;
1765
1766 if (s->symbol.flags & BSF_GLOBAL)
1767 s->n_type |= BFD_MACH_O_N_EXT;
1768 }
1769
7f307238 1770 /* Put the section index in, where required. */
68588f95 1771 if ((s->symbol.section != bfd_abs_section_ptr
92bc0e80
TG
1772 && s->symbol.section != bfd_und_section_ptr
1773 && s->symbol.section != bfd_com_section_ptr)
68588f95
IS
1774 || ((s->n_type & BFD_MACH_O_N_STAB) != 0
1775 && s->symbol.name == NULL))
1776 s->n_sect = s->symbol.section->target_index;
92bc0e80 1777
b22161d6
IS
1778 /* Number to preserve order for local and debug syms. */
1779 s->symbol.udata.i = i;
7f307238
IS
1780 }
1781
b22161d6
IS
1782 /* Sort the symbols. */
1783 qsort ((void *) symbols, (size_t) bfd_get_symcount (abfd),
1784 sizeof (asymbol *), bfd_mach_o_cf_symbols);
7f307238 1785
b22161d6
IS
1786 for (i = 0; i < bfd_get_symcount (abfd); ++i)
1787 {
1788 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1789 s->symbol.udata.i = i; /* renumber. */
7f307238
IS
1790 }
1791
1792 return TRUE;
1793}
1794
1795/* We build a flat table of sections, which can be re-ordered if necessary.
1796 Fill in the section number and other mach-o-specific data. */
1797
1798static bfd_boolean
1799bfd_mach_o_mangle_sections (bfd *abfd, bfd_mach_o_data_struct *mdata)
1800{
1801 asection *sec;
1802 unsigned target_index;
1803 unsigned nsect;
1804
1805 nsect = bfd_count_sections (abfd);
1806
1807 /* Don't do it if it's already set - assume the application knows what it's
1808 doing. */
1809 if (mdata->nsects == nsect
1810 && (mdata->nsects == 0 || mdata->sections != NULL))
1811 return TRUE;
1812
1813 mdata->nsects = nsect;
1814 mdata->sections = bfd_alloc (abfd,
1815 mdata->nsects * sizeof (bfd_mach_o_section *));
1816 if (mdata->sections == NULL)
1817 return FALSE;
1818
1819 /* We need to check that this can be done... */
1820 if (nsect > 255)
1821 (*_bfd_error_handler) (_("mach-o: there are too many sections (%d)"
1822 " maximum is 255,\n"), nsect);
1823
1824 /* Create Mach-O sections.
1825 Section type, attribute and align should have been set when the
1826 section was created - either read in or specified. */
1827 target_index = 0;
1828 for (sec = abfd->sections; sec; sec = sec->next)
1829 {
1830 unsigned bfd_align = bfd_get_section_alignment (abfd, sec);
1831 bfd_mach_o_section *msect = bfd_mach_o_get_mach_o_section (sec);
1832
1833 mdata->sections[target_index] = msect;
1834
1835 msect->addr = bfd_get_section_vma (abfd, sec);
1836 msect->size = bfd_get_section_size (sec);
1837
1838 /* Use the largest alignment set, in case it was bumped after the
1839 section was created. */
1840 msect->align = msect->align > bfd_align ? msect->align : bfd_align;
1841
1842 msect->offset = 0;
1843 sec->target_index = ++target_index;
92bc0e80 1844 }
7f307238 1845
92bc0e80
TG
1846 return TRUE;
1847}
1848
154a1ee5 1849bfd_boolean
116c20d2 1850bfd_mach_o_write_contents (bfd *abfd)
3af9a47b
NC
1851{
1852 unsigned int i;
046b007d 1853 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 1854
7f307238 1855 /* Make the commands, if not already present. */
92bc0e80
TG
1856 if (mdata->header.ncmds == 0)
1857 if (!bfd_mach_o_build_commands (abfd))
1858 return FALSE;
1859
154a1ee5 1860 if (!bfd_mach_o_write_header (abfd, &mdata->header))
b34976b6 1861 return FALSE;
3af9a47b
NC
1862
1863 for (i = 0; i < mdata->header.ncmds; i++)
1864 {
46d1c23b 1865 struct mach_o_load_command_external raw;
3af9a47b
NC
1866 bfd_mach_o_load_command *cur = &mdata->commands[i];
1867 unsigned long typeflag;
1868
154a1ee5 1869 typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
3af9a47b 1870
46d1c23b
TG
1871 bfd_h_put_32 (abfd, typeflag, raw.cmd);
1872 bfd_h_put_32 (abfd, cur->len, raw.cmdsize);
3af9a47b 1873
c2f09c75 1874 if (bfd_seek (abfd, cur->offset, SEEK_SET) != 0
46d1c23b 1875 || bfd_bwrite (&raw, BFD_MACH_O_LC_SIZE, abfd) != 8)
b34976b6 1876 return FALSE;
3af9a47b
NC
1877
1878 switch (cur->type)
1879 {
1880 case BFD_MACH_O_LC_SEGMENT:
ab273af8 1881 if (bfd_mach_o_write_segment_32 (abfd, cur) != 0)
1e8a024a
TG
1882 return FALSE;
1883 break;
1884 case BFD_MACH_O_LC_SEGMENT_64:
ab273af8 1885 if (bfd_mach_o_write_segment_64 (abfd, cur) != 0)
b34976b6 1886 return FALSE;
3af9a47b
NC
1887 break;
1888 case BFD_MACH_O_LC_SYMTAB:
ab273af8 1889 if (!bfd_mach_o_write_symtab (abfd, cur))
b34976b6 1890 return FALSE;
3af9a47b 1891 break;
7f307238
IS
1892 case BFD_MACH_O_LC_DYSYMTAB:
1893 if (!bfd_mach_o_write_dysymtab (abfd, cur))
1894 return FALSE;
1895 break;
3af9a47b
NC
1896 case BFD_MACH_O_LC_SYMSEG:
1897 break;
1898 case BFD_MACH_O_LC_THREAD:
1899 case BFD_MACH_O_LC_UNIXTHREAD:
ab273af8 1900 if (bfd_mach_o_write_thread (abfd, cur) != 0)
b34976b6 1901 return FALSE;
3af9a47b
NC
1902 break;
1903 case BFD_MACH_O_LC_LOADFVMLIB:
1904 case BFD_MACH_O_LC_IDFVMLIB:
1905 case BFD_MACH_O_LC_IDENT:
1906 case BFD_MACH_O_LC_FVMFILE:
1907 case BFD_MACH_O_LC_PREPAGE:
3af9a47b
NC
1908 case BFD_MACH_O_LC_LOAD_DYLIB:
1909 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1910 case BFD_MACH_O_LC_ID_DYLIB:
046b007d 1911 case BFD_MACH_O_LC_REEXPORT_DYLIB:
73017762 1912 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
3af9a47b
NC
1913 case BFD_MACH_O_LC_LOAD_DYLINKER:
1914 case BFD_MACH_O_LC_ID_DYLINKER:
1915 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1916 case BFD_MACH_O_LC_ROUTINES:
1917 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1918 break;
1919 default:
4a97a0e5
AM
1920 (*_bfd_error_handler) (_("unable to write unknown load command 0x%lx"),
1921 (unsigned long) cur->type);
b34976b6 1922 return FALSE;
3af9a47b
NC
1923 }
1924 }
1925
b34976b6 1926 return TRUE;
3af9a47b
NC
1927}
1928
f1bde64c
TG
1929static void
1930bfd_mach_o_append_section_to_segment (bfd_mach_o_segment_command *seg,
1931 asection *sec)
1932{
1933 bfd_mach_o_section *s = (bfd_mach_o_section *)sec->used_by_bfd;
1934 if (seg->sect_head == NULL)
1935 seg->sect_head = s;
1936 else
1937 seg->sect_tail->next = s;
1938 seg->sect_tail = s;
1939}
1940
1941/* Create section Mach-O flags from BFD flags. */
1942
1943static void
1944bfd_mach_o_set_section_flags_from_bfd (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
1945{
1946 flagword bfd_flags;
1947 bfd_mach_o_section *s = bfd_mach_o_get_mach_o_section (sec);
1948
1949 /* Create default flags. */
1950 bfd_flags = bfd_get_section_flags (abfd, sec);
1951 if ((bfd_flags & SEC_CODE) == SEC_CODE)
1952 s->flags = BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS
1953 | BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS
1954 | BFD_MACH_O_S_REGULAR;
1955 else if ((bfd_flags & (SEC_ALLOC | SEC_LOAD)) == SEC_ALLOC)
1956 s->flags = BFD_MACH_O_S_ZEROFILL;
1957 else if (bfd_flags & SEC_DEBUGGING)
1958 s->flags = BFD_MACH_O_S_REGULAR | BFD_MACH_O_S_ATTR_DEBUG;
1959 else
1960 s->flags = BFD_MACH_O_S_REGULAR;
1961}
1962
7f307238
IS
1963/* Count the number of sections in the list for the segment named.
1964
1965 The special case of NULL or "" for the segment name is valid for
1966 an MH_OBJECT file and means 'all sections available'.
1967
1968 Requires that the sections table in mdata be filled in.
1969
1970 Returns the number of sections (0 is valid).
1971 Any number > 255 signals an invalid section count, although we will,
1972 perhaps, allow the file to be written (in line with Darwin tools up
1973 to XCode 4).
1974
1975 A section count of (unsigned long) -1 signals a definite error. */
1976
1977static unsigned long
1978bfd_mach_o_count_sections_for_seg (const char *segment,
1979 bfd_mach_o_data_struct *mdata)
1980{
1981 unsigned i,j;
1982 if (mdata == NULL || mdata->sections == NULL)
1983 return (unsigned long) -1;
1984
1985 /* The MH_OBJECT case, all sections are considered; Although nsects is
1986 is an unsigned long, the maximum valid section count is 255 and this
1987 will have been checked already by mangle_sections. */
1988 if (segment == NULL || segment[0] == '\0')
1989 return mdata->nsects;
1990
1991 /* Count the number of sections we see in this segment. */
1992 j = 0;
1993 for (i = 0; i < mdata->nsects; ++i)
1994 {
1995 bfd_mach_o_section *s = mdata->sections[i];
1996 if (strncmp (segment, s->segname, BFD_MACH_O_SEGNAME_SIZE) == 0)
1997 j++;
1998 }
1999 return j;
2000}
2001
2002static bfd_boolean
2003bfd_mach_o_build_seg_command (const char *segment,
2004 bfd_mach_o_data_struct *mdata,
2005 bfd_mach_o_segment_command *seg)
2006{
2007 unsigned i;
2008 int is_mho = (segment == NULL || segment[0] == '\0');
2009
2010 /* Fill segment command. */
2011 if (is_mho)
2012 memset (seg->segname, 0, sizeof (seg->segname));
2013 else
2014 strncpy (seg->segname, segment, sizeof (seg->segname));
2015
2016 /* TODO: fix this up for non-MH_OBJECT cases. */
2017 seg->vmaddr = 0;
e5081f2f 2018 seg->vmsize = 0;
7f307238
IS
2019
2020 seg->fileoff = mdata->filelen;
2021 seg->filesize = 0;
2022 seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
2023 | BFD_MACH_O_PROT_EXECUTE;
2024 seg->initprot = seg->maxprot;
2025 seg->flags = 0;
2026 seg->sect_head = NULL;
2027 seg->sect_tail = NULL;
2028
2029 /* Append sections to the segment. */
2030
2031 for (i = 0; i < mdata->nsects; ++i)
2032 {
2033 bfd_mach_o_section *s = mdata->sections[i];
2034 asection *sec = s->bfdsection;
2035
2036 /* If we're not making an MH_OBJECT, check whether this section is from
2037 our segment, and skip if not. Otherwise, just add all sections. */
2038 if (! is_mho
2039 && strncmp (segment, s->segname, BFD_MACH_O_SEGNAME_SIZE) != 0)
2040 continue;
2041
2042 bfd_mach_o_append_section_to_segment (seg, sec);
2043
e5081f2f
IS
2044 s->offset = 0;
2045 if (s->size > 0)
2046 {
2047 seg->vmsize = FILE_ALIGN (seg->vmsize, s->align);
2048 seg->vmsize += s->size;
2049 }
2050
2051 /* Zerofill sections have zero file size & offset,
2052 and are not written. */
2053 if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) == BFD_MACH_O_S_ZEROFILL
2054 || (s->flags & BFD_MACH_O_SECTION_TYPE_MASK)
2055 == BFD_MACH_O_S_GB_ZEROFILL)
2056 continue;
2057
2058 if (s->size > 0)
7f307238
IS
2059 {
2060 mdata->filelen = FILE_ALIGN (mdata->filelen, s->align);
2061 s->offset = mdata->filelen;
2062 }
2063
2064 sec->filepos = s->offset;
2065
2066 mdata->filelen += s->size;
2067 }
2068
2069 seg->filesize = mdata->filelen - seg->fileoff;
bb76d940
IS
2070 seg->filesize = FILE_ALIGN(seg->filesize, 2);
2071
2072 /* Allocate relocation room. */
2073 mdata->filelen = FILE_ALIGN(mdata->filelen, 2);
2074
2075 for (i = 0; i < mdata->nsects; ++i)
2076 {
2077 bfd_mach_o_section *ms = mdata->sections[i];
2078 asection *sec = ms->bfdsection;
2079
2080 if ((ms->nreloc = sec->reloc_count) == 0)
2081 {
2082 ms->reloff = 0;
2083 continue;
2084 }
2085 sec->rel_filepos = mdata->filelen;
2086 ms->reloff = sec->rel_filepos;
2087 mdata->filelen += sec->reloc_count * BFD_MACH_O_RELENT_SIZE;
2088 }
7f307238
IS
2089
2090 return TRUE;
2091}
2092
50d10658
IS
2093/* Count the number of indirect symbols in the image.
2094 Requires that the sections are in their final order. */
2095
2096static unsigned int
2097bfd_mach_o_count_indirect_symbols (bfd *abfd, bfd_mach_o_data_struct *mdata)
2098{
2099 unsigned int i;
2100 unsigned int nisyms = 0;
2101
2102 for (i = 0; i < mdata->nsects; ++i)
2103 {
2104 bfd_mach_o_section *sec = mdata->sections[i];
2105
2106 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
2107 {
2108 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
2109 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
2110 case BFD_MACH_O_S_SYMBOL_STUBS:
2111 nisyms += bfd_mach_o_section_get_nbr_indirect (abfd, sec);
2112 break;
2113 default:
2114 break;
2115 }
2116 }
2117 return nisyms;
2118}
2119
7f307238
IS
2120static bfd_boolean
2121bfd_mach_o_build_dysymtab_command (bfd *abfd,
2122 bfd_mach_o_data_struct *mdata,
2123 bfd_mach_o_load_command *cmd)
2124{
2125 bfd_mach_o_dysymtab_command *dsym = &cmd->command.dysymtab;
2126
2127 /* TODO:
2128 We are not going to try and fill these in yet and, moreover, we are
2129 going to bail if they are already set. */
2130 if (dsym->nmodtab != 0
2131 || dsym->ntoc != 0
2132 || dsym->nextrefsyms != 0)
2133 {
2134 (*_bfd_error_handler) (_("sorry: modtab, toc and extrefsyms are not yet"
2135 " implemented for dysymtab commands."));
2136 return FALSE;
2137 }
2138
2139 dsym->ilocalsym = 0;
7f307238 2140
b22161d6 2141 if (bfd_get_symcount (abfd) > 0)
7f307238 2142 {
b22161d6
IS
2143 asymbol **symbols = bfd_get_outsymbols (abfd);
2144 unsigned long i;
2145
2146 /* Count the number of each kind of symbol. */
2147 for (i = 0; i < bfd_get_symcount (abfd); ++i)
2148 {
2149 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
2150 if (s->n_type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT))
2151 break;
2152 }
2153 dsym->nlocalsym = i;
2154 dsym->iextdefsym = i;
2155 for (; i < bfd_get_symcount (abfd); ++i)
2156 {
2157 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
2158 if ((s->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_UNDF)
2159 break;
2160 }
2161 dsym->nextdefsym = i - dsym->nlocalsym;
2162 dsym->iundefsym = dsym->nextdefsym + dsym->iextdefsym;
2163 dsym->nundefsym = bfd_get_symcount (abfd)
2164 - dsym->nlocalsym
2165 - dsym->nextdefsym;
2166 }
2167 else
2168 {
2169 dsym->nlocalsym = 0;
2170 dsym->iextdefsym = 0;
2171 dsym->nextdefsym = 0;
2172 dsym->iundefsym = 0;
2173 dsym->nundefsym = 0;
2174 }
2175
50d10658 2176 dsym->nindirectsyms = bfd_mach_o_count_indirect_symbols (abfd, mdata);
b22161d6
IS
2177 if (dsym->nindirectsyms > 0)
2178 {
2179 unsigned i;
50d10658 2180 unsigned n;
7f307238
IS
2181
2182 mdata->filelen = FILE_ALIGN (mdata->filelen, 2);
2183 dsym->indirectsymoff = mdata->filelen;
b22161d6 2184 mdata->filelen += dsym->nindirectsyms * 4;
7f307238 2185
b22161d6 2186 dsym->indirect_syms = bfd_zalloc (abfd, dsym->nindirectsyms * 4);
7f307238
IS
2187 if (dsym->indirect_syms == NULL)
2188 return FALSE;
50d10658
IS
2189
2190 n = 0;
2191 for (i = 0; i < mdata->nsects; ++i)
7f307238 2192 {
50d10658
IS
2193 bfd_mach_o_section *sec = mdata->sections[i];
2194
2195 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
2196 {
2197 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
2198 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
2199 case BFD_MACH_O_S_SYMBOL_STUBS:
2200 {
2201 unsigned j, num;
2202 bfd_mach_o_asymbol **isyms = sec->indirect_syms;
2203
2204 num = bfd_mach_o_section_get_nbr_indirect (abfd, sec);
2205 if (isyms == NULL || num == 0)
2206 break;
2207 /* Record the starting index in the reserved1 field. */
2208 sec->reserved1 = n;
2209 for (j = 0; j < num; j++, n++)
2210 {
2211 if (isyms[j] == NULL)
2212 dsym->indirect_syms[n] = BFD_MACH_O_INDIRECT_SYM_LOCAL;
687be931
IS
2213 else if (isyms[j]->symbol.section == bfd_abs_section_ptr
2214 && ! (isyms[j]->n_type & BFD_MACH_O_N_EXT))
2215 dsym->indirect_syms[n] = BFD_MACH_O_INDIRECT_SYM_LOCAL
2216 | BFD_MACH_O_INDIRECT_SYM_ABS;
50d10658
IS
2217 else
2218 dsym->indirect_syms[n] = isyms[j]->symbol.udata.i;
2219 }
2220 }
2221 break;
2222 default:
2223 break;
2224 }
7f307238
IS
2225 }
2226 }
2227
2228 return TRUE;
2229}
2230
2231/* Build Mach-O load commands (currently assuming an MH_OBJECT file).
2232 TODO: Other file formats, rebuilding symtab/dysymtab commands for strip
2233 and copy functionality. */
154a1ee5
TG
2234
2235bfd_boolean
2236bfd_mach_o_build_commands (bfd *abfd)
2237{
046b007d 2238 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
bbd56171
IS
2239 unsigned wide = mach_o_wide_p (&mdata->header);
2240 int segcmd_idx = -1;
2241 int symtab_idx = -1;
2242 int dysymtab_idx = -1;
2243 unsigned long base_offset = 0;
154a1ee5 2244
7f307238 2245 /* Return now if commands are already present. */
154a1ee5
TG
2246 if (mdata->header.ncmds)
2247 return FALSE;
2248
7f307238 2249 /* Fill in the file type, if not already set. */
154a1ee5 2250
7f307238 2251 if (mdata->header.filetype == 0)
154a1ee5 2252 {
7f307238
IS
2253 if (abfd->flags & EXEC_P)
2254 mdata->header.filetype = BFD_MACH_O_MH_EXECUTE;
2255 else if (abfd->flags & DYNAMIC)
2256 mdata->header.filetype = BFD_MACH_O_MH_DYLIB;
2257 else
2258 mdata->header.filetype = BFD_MACH_O_MH_OBJECT;
154a1ee5 2259 }
7f307238
IS
2260
2261 /* If hasn't already been done, flatten sections list, and sort
2262 if/when required. Must be done before the symbol table is adjusted,
2263 since that depends on properly numbered sections. */
2264 if (mdata->nsects == 0 || mdata->sections == NULL)
2265 if (! bfd_mach_o_mangle_sections (abfd, mdata))
2266 return FALSE;
2267
2268 /* Order the symbol table, fill-in/check mach-o specific fields and
2269 partition out any indirect symbols. */
b22161d6 2270 if (!bfd_mach_o_mangle_symbols (abfd))
7f307238
IS
2271 return FALSE;
2272
bbd56171
IS
2273 /* Very simple command set (only really applicable to MH_OBJECTs):
2274 All the commands are optional - present only when there is suitable data.
2275 (i.e. it is valid to have an empty file)
2276
2277 a command (segment) to contain all the sections,
2278 command for the symbol table,
2279 a command for the dysymtab.
2280
2281 ??? maybe we should assert that this is an MH_OBJECT? */
2282
7f307238 2283 if (mdata->nsects > 0)
154a1ee5 2284 {
bbd56171 2285 segcmd_idx = 0;
7f307238 2286 mdata->header.ncmds = 1;
154a1ee5 2287 }
154a1ee5 2288
7f307238 2289 if (bfd_get_symcount (abfd) > 0)
bbd56171
IS
2290 {
2291 mdata->header.ncmds++;
2292 symtab_idx = segcmd_idx + 1; /* 0 if the seg command is absent. */
2293 }
c2f09c75 2294
bbd56171
IS
2295 /* FIXME:
2296 This is a rather crude test for whether we should build a dysymtab. */
2297 if (bfd_mach_o_should_emit_dysymtab ()
2298 && bfd_get_symcount (abfd))
2299 {
2300 mdata->header.ncmds++;
2301 /* If there should be a case where a dysymtab could be emitted without
2302 a symtab (seems improbable), this would need amending. */
2303 dysymtab_idx = symtab_idx + 1;
2304 }
154a1ee5 2305
bbd56171
IS
2306 if (wide)
2307 base_offset = BFD_MACH_O_HEADER_64_SIZE;
2308 else
2309 base_offset = BFD_MACH_O_HEADER_SIZE;
c2f09c75 2310
bbd56171
IS
2311 /* Well, we must have a header, at least. */
2312 mdata->filelen = base_offset;
f1bde64c 2313
bbd56171 2314 /* A bit unusual, but no content is valid;
7f307238
IS
2315 as -n empty.s -o empty.o */
2316 if (mdata->header.ncmds == 0)
2317 return TRUE;
f1bde64c 2318
7f307238
IS
2319 mdata->commands = bfd_zalloc (abfd, mdata->header.ncmds
2320 * sizeof (bfd_mach_o_load_command));
2321 if (mdata->commands == NULL)
2322 return FALSE;
2323
bbd56171 2324 if (segcmd_idx >= 0)
7f307238 2325 {
bbd56171
IS
2326 bfd_mach_o_load_command *cmd = &mdata->commands[segcmd_idx];
2327 bfd_mach_o_segment_command *seg = &cmd->command.segment;
7f307238
IS
2328
2329 /* Count the segctions in the special blank segment used for MH_OBJECT. */
2330 seg->nsects = bfd_mach_o_count_sections_for_seg (NULL, mdata);
2331 if (seg->nsects == (unsigned long) -1)
2332 return FALSE;
2333
2334 /* Init segment command. */
bbd56171 2335 cmd->offset = base_offset;
7f307238
IS
2336 if (wide)
2337 {
2338 cmd->type = BFD_MACH_O_LC_SEGMENT_64;
7f307238
IS
2339 cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
2340 + BFD_MACH_O_SECTION_64_SIZE * seg->nsects;
2341 }
92bc0e80 2342 else
7f307238
IS
2343 {
2344 cmd->type = BFD_MACH_O_LC_SEGMENT;
7f307238
IS
2345 cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
2346 + BFD_MACH_O_SECTION_SIZE * seg->nsects;
2347 }
bbd56171 2348
7f307238
IS
2349 cmd->type_required = FALSE;
2350 mdata->header.sizeofcmds = cmd->len;
bbd56171 2351 mdata->filelen += cmd->len;
7f307238 2352 }
f1bde64c 2353
bbd56171 2354 if (symtab_idx >= 0)
7f307238
IS
2355 {
2356 /* Init symtab command. */
bbd56171 2357 bfd_mach_o_load_command *cmd = &mdata->commands[symtab_idx];
7f307238 2358
bbd56171
IS
2359 cmd->type = BFD_MACH_O_LC_SYMTAB;
2360 cmd->offset = base_offset;
2361 if (segcmd_idx >= 0)
2362 cmd->offset += mdata->commands[segcmd_idx].len;
2363
2364 cmd->len = sizeof (struct mach_o_symtab_command_external)
2365 + BFD_MACH_O_LC_SIZE;
2366 cmd->type_required = FALSE;
2367 mdata->header.sizeofcmds += cmd->len;
2368 mdata->filelen += cmd->len;
7f307238 2369 }
154a1ee5 2370
bbd56171
IS
2371 /* If required, setup symtab command, see comment above about the quality
2372 of this test. */
2373 if (dysymtab_idx >= 0)
7f307238 2374 {
bbd56171
IS
2375 bfd_mach_o_load_command *cmd = &mdata->commands[dysymtab_idx];
2376
7f307238 2377 cmd->type = BFD_MACH_O_LC_DYSYMTAB;
bbd56171
IS
2378 if (symtab_idx >= 0)
2379 cmd->offset = mdata->commands[symtab_idx].offset
2380 + mdata->commands[symtab_idx].len;
2381 else if (segcmd_idx >= 0)
2382 cmd->offset = mdata->commands[segcmd_idx].offset
2383 + mdata->commands[segcmd_idx].len;
2384 else
2385 cmd->offset = base_offset;
2386
7f307238 2387 cmd->type_required = FALSE;
bbd56171
IS
2388 cmd->len = sizeof (struct mach_o_dysymtab_command_external)
2389 + BFD_MACH_O_LC_SIZE;
7f307238
IS
2390
2391 mdata->header.sizeofcmds += cmd->len;
2392 mdata->filelen += cmd->len;
154a1ee5 2393 }
154a1ee5 2394
7f307238
IS
2395 /* So, now we have sized the commands and the filelen set to that.
2396 Now we can build the segment command and set the section file offsets. */
bbd56171
IS
2397 if (segcmd_idx >= 0
2398 && ! bfd_mach_o_build_seg_command
2399 (NULL, mdata, &mdata->commands[segcmd_idx].command.segment))
7f307238
IS
2400 return FALSE;
2401
2402 /* If we're doing a dysymtab, cmd points to its load command. */
bbd56171 2403 if (dysymtab_idx >= 0
7f307238 2404 && ! bfd_mach_o_build_dysymtab_command (abfd, mdata,
bbd56171 2405 &mdata->commands[dysymtab_idx]))
7f307238
IS
2406 return FALSE;
2407
2408 /* The symtab command is filled in when the symtab is written. */
154a1ee5
TG
2409 return TRUE;
2410}
2411
2412/* Set the contents of a section. */
2413
2414bfd_boolean
2415bfd_mach_o_set_section_contents (bfd *abfd,
2416 asection *section,
2417 const void * location,
2418 file_ptr offset,
2419 bfd_size_type count)
2420{
2421 file_ptr pos;
2422
7f307238
IS
2423 /* Trying to write the first section contents will trigger the creation of
2424 the load commands if they are not already present. */
154a1ee5
TG
2425 if (! abfd->output_has_begun && ! bfd_mach_o_build_commands (abfd))
2426 return FALSE;
2427
2428 if (count == 0)
2429 return TRUE;
2430
2431 pos = section->filepos + offset;
2432 if (bfd_seek (abfd, pos, SEEK_SET) != 0
2433 || bfd_bwrite (location, count, abfd) != count)
2434 return FALSE;
2435
2436 return TRUE;
2437}
2438
2439int
116c20d2 2440bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
a6b96beb 2441 struct bfd_link_info *info ATTRIBUTE_UNUSED)
3af9a47b
NC
2442{
2443 return 0;
2444}
2445
2446/* Make an empty symbol. This is required only because
2447 bfd_make_section_anyway wants to create a symbol for the section. */
2448
154a1ee5 2449asymbol *
116c20d2 2450bfd_mach_o_make_empty_symbol (bfd *abfd)
3af9a47b 2451{
d3ce72d0
NC
2452 asymbol *new_symbol;
2453
2454 new_symbol = bfd_zalloc (abfd, sizeof (bfd_mach_o_asymbol));
2455 if (new_symbol == NULL)
2456 return new_symbol;
2457 new_symbol->the_bfd = abfd;
b22161d6 2458 new_symbol->udata.i = SYM_MACHO_FIELDS_UNSET;
d3ce72d0 2459 return new_symbol;
3af9a47b
NC
2460}
2461
154a1ee5 2462static bfd_boolean
116c20d2 2463bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
3af9a47b 2464{
46d1c23b 2465 struct mach_o_header_external raw;
1e8a024a 2466 unsigned int size;
edeb6e24 2467 bfd_vma (*get32) (const void *) = NULL;
3af9a47b 2468
1e8a024a 2469 /* Just read the magic number. */
c2f09c75 2470 if (bfd_seek (abfd, 0, SEEK_SET) != 0
46d1c23b 2471 || bfd_bread (raw.magic, sizeof (raw.magic), abfd) != 4)
154a1ee5 2472 return FALSE;
3af9a47b 2473
46d1c23b 2474 if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
3af9a47b
NC
2475 {
2476 header->byteorder = BFD_ENDIAN_BIG;
154a1ee5 2477 header->magic = BFD_MACH_O_MH_MAGIC;
1e8a024a 2478 header->version = 1;
3af9a47b
NC
2479 get32 = bfd_getb32;
2480 }
46d1c23b 2481 else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
3af9a47b 2482 {
a95a4550 2483 header->byteorder = BFD_ENDIAN_LITTLE;
154a1ee5 2484 header->magic = BFD_MACH_O_MH_MAGIC;
1e8a024a
TG
2485 header->version = 1;
2486 get32 = bfd_getl32;
2487 }
46d1c23b 2488 else if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
1e8a024a
TG
2489 {
2490 header->byteorder = BFD_ENDIAN_BIG;
154a1ee5 2491 header->magic = BFD_MACH_O_MH_MAGIC_64;
1e8a024a
TG
2492 header->version = 2;
2493 get32 = bfd_getb32;
2494 }
46d1c23b 2495 else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
1e8a024a
TG
2496 {
2497 header->byteorder = BFD_ENDIAN_LITTLE;
154a1ee5 2498 header->magic = BFD_MACH_O_MH_MAGIC_64;
1e8a024a 2499 header->version = 2;
3af9a47b
NC
2500 get32 = bfd_getl32;
2501 }
2502 else
2503 {
2504 header->byteorder = BFD_ENDIAN_UNKNOWN;
154a1ee5 2505 return FALSE;
3af9a47b 2506 }
a95a4550 2507
1e8a024a 2508 /* Once the size of the header is known, read the full header. */
c2f09c75 2509 size = mach_o_wide_p (header) ?
154a1ee5 2510 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
1e8a024a 2511
c2f09c75 2512 if (bfd_seek (abfd, 0, SEEK_SET) != 0
46d1c23b 2513 || bfd_bread (&raw, size, abfd) != size)
154a1ee5 2514 return FALSE;
1e8a024a 2515
46d1c23b
TG
2516 header->cputype = (*get32) (raw.cputype);
2517 header->cpusubtype = (*get32) (raw.cpusubtype);
2518 header->filetype = (*get32) (raw.filetype);
2519 header->ncmds = (*get32) (raw.ncmds);
2520 header->sizeofcmds = (*get32) (raw.sizeofcmds);
2521 header->flags = (*get32) (raw.flags);
3af9a47b 2522
c2f09c75 2523 if (mach_o_wide_p (header))
46d1c23b 2524 header->reserved = (*get32) (raw.reserved);
facf03f2
TG
2525 else
2526 header->reserved = 0;
1e8a024a 2527
154a1ee5 2528 return TRUE;
3af9a47b
NC
2529}
2530
f1bde64c
TG
2531bfd_boolean
2532bfd_mach_o_new_section_hook (bfd *abfd, asection *sec)
2533{
2534 bfd_mach_o_section *s;
a4551119 2535 unsigned bfdalign = bfd_get_section_alignment (abfd, sec);
f1bde64c
TG
2536
2537 s = bfd_mach_o_get_mach_o_section (sec);
2538 if (s == NULL)
2539 {
2540 flagword bfd_flags;
a4551119 2541 static const mach_o_section_name_xlat * xlat;
f1bde64c
TG
2542
2543 s = (bfd_mach_o_section *) bfd_zalloc (abfd, sizeof (*s));
2544 if (s == NULL)
2545 return FALSE;
2546 sec->used_by_bfd = s;
2547 s->bfdsection = sec;
2548
a4551119
TG
2549 /* Create the Darwin seg/sect name pair from the bfd name.
2550 If this is a canonical name for which a specific paiting exists
2551 there will also be defined flags, type, attribute and alignment
2552 values. */
2553 xlat = bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, s);
2554 if (xlat != NULL)
2555 {
2556 s->flags = xlat->macho_sectype | xlat->macho_secattr;
2557 s->align = xlat->sectalign > bfdalign ? xlat->sectalign
2558 : bfdalign;
2559 bfd_set_section_alignment (abfd, sec, s->align);
2560 bfd_flags = bfd_get_section_flags (abfd, sec);
2561 if (bfd_flags == SEC_NO_FLAGS)
2562 bfd_set_section_flags (abfd, sec, xlat->bfd_flags);
2563 }
f1bde64c 2564 else
a4551119
TG
2565 /* Create default flags. */
2566 bfd_mach_o_set_section_flags_from_bfd (abfd, sec);
f1bde64c
TG
2567 }
2568
2569 return _bfd_generic_new_section_hook (abfd, sec);
2570}
2571
2572static void
2573bfd_mach_o_init_section_from_mach_o (bfd *abfd, asection *sec,
2574 unsigned long prot)
3af9a47b 2575{
117ed4f8 2576 flagword flags;
f1bde64c 2577 bfd_mach_o_section *section;
3af9a47b 2578
f1bde64c
TG
2579 flags = bfd_get_section_flags (abfd, sec);
2580 section = bfd_mach_o_get_mach_o_section (sec);
3af9a47b 2581
a4551119
TG
2582 /* TODO: see if we should use the xlat system for doing this by
2583 preference and fall back to this for unknown sections. */
2584
8462aec7 2585 if (flags == SEC_NO_FLAGS)
ef17cb22 2586 {
8462aec7
TG
2587 /* Try to guess flags. */
2588 if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
2589 flags = SEC_DEBUGGING;
2590 else
2591 {
2592 flags = SEC_ALLOC;
2593 if ((section->flags & BFD_MACH_O_SECTION_TYPE_MASK)
2594 != BFD_MACH_O_S_ZEROFILL)
2595 {
2596 flags |= SEC_LOAD;
2597 if (prot & BFD_MACH_O_PROT_EXECUTE)
2598 flags |= SEC_CODE;
2599 if (prot & BFD_MACH_O_PROT_WRITE)
2600 flags |= SEC_DATA;
2601 else if (prot & BFD_MACH_O_PROT_READ)
2602 flags |= SEC_READONLY;
2603 }
2604 }
ef17cb22 2605 }
15e1c58a
TG
2606 else
2607 {
8462aec7
TG
2608 if ((flags & SEC_DEBUGGING) == 0)
2609 flags |= SEC_ALLOC;
15e1c58a 2610 }
8462aec7
TG
2611
2612 if (section->offset != 0)
2613 flags |= SEC_HAS_CONTENTS;
92bc0e80
TG
2614 if (section->nreloc != 0)
2615 flags |= SEC_RELOC;
2616
f1bde64c
TG
2617 bfd_set_section_flags (abfd, sec, flags);
2618
2619 sec->vma = section->addr;
2620 sec->lma = section->addr;
2621 sec->size = section->size;
2622 sec->filepos = section->offset;
2623 sec->alignment_power = section->align;
2624 sec->segment_mark = 0;
2625 sec->reloc_count = section->nreloc;
2626 sec->rel_filepos = section->reloff;
2627}
2628
2629static asection *
2630bfd_mach_o_make_bfd_section (bfd *abfd,
2631 const unsigned char *segname,
2632 const unsigned char *sectname)
2633{
2634 const char *sname;
2635 flagword flags;
a95a4550 2636
f1bde64c
TG
2637 bfd_mach_o_convert_section_name_to_bfd
2638 (abfd, (const char *)segname, (const char *)sectname, &sname, &flags);
2639 if (sname == NULL)
2640 return NULL;
3af9a47b 2641
f1bde64c 2642 return bfd_make_section_anyway_with_flags (abfd, sname, flags);
3af9a47b
NC
2643}
2644
f1bde64c 2645static asection *
ab273af8 2646bfd_mach_o_read_section_32 (bfd *abfd,
ab273af8
TG
2647 unsigned int offset,
2648 unsigned long prot)
3af9a47b 2649{
46d1c23b 2650 struct mach_o_section_32_external raw;
f1bde64c
TG
2651 asection *sec;
2652 bfd_mach_o_section *section;
3af9a47b 2653
c2f09c75 2654 if (bfd_seek (abfd, offset, SEEK_SET) != 0
46d1c23b 2655 || (bfd_bread (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
c2f09c75 2656 != BFD_MACH_O_SECTION_SIZE))
f1bde64c 2657 return NULL;
a95a4550 2658
5a5cbf72 2659 sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
f1bde64c
TG
2660 if (sec == NULL)
2661 return NULL;
2662
2663 section = bfd_mach_o_get_mach_o_section (sec);
2664 memcpy (section->segname, raw.segname, sizeof (raw.segname));
2665 section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
2666 memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
69499dca 2667 section->sectname[BFD_MACH_O_SECTNAME_SIZE] = 0;
46d1c23b
TG
2668 section->addr = bfd_h_get_32 (abfd, raw.addr);
2669 section->size = bfd_h_get_32 (abfd, raw.size);
2670 section->offset = bfd_h_get_32 (abfd, raw.offset);
2671 section->align = bfd_h_get_32 (abfd, raw.align);
2672 section->reloff = bfd_h_get_32 (abfd, raw.reloff);
2673 section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
2674 section->flags = bfd_h_get_32 (abfd, raw.flags);
2675 section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
2676 section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
1e8a024a 2677 section->reserved3 = 0;
1e8a024a 2678
f1bde64c 2679 bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
1e8a024a 2680
f1bde64c 2681 return sec;
1e8a024a
TG
2682}
2683
f1bde64c 2684static asection *
ab273af8 2685bfd_mach_o_read_section_64 (bfd *abfd,
ab273af8
TG
2686 unsigned int offset,
2687 unsigned long prot)
1e8a024a 2688{
46d1c23b 2689 struct mach_o_section_64_external raw;
f1bde64c
TG
2690 asection *sec;
2691 bfd_mach_o_section *section;
1e8a024a 2692
c2f09c75 2693 if (bfd_seek (abfd, offset, SEEK_SET) != 0
46d1c23b 2694 || (bfd_bread (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
c2f09c75 2695 != BFD_MACH_O_SECTION_64_SIZE))
f1bde64c
TG
2696 return NULL;
2697
5a5cbf72 2698 sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
f1bde64c
TG
2699 if (sec == NULL)
2700 return NULL;
1e8a024a 2701
f1bde64c
TG
2702 section = bfd_mach_o_get_mach_o_section (sec);
2703 memcpy (section->segname, raw.segname, sizeof (raw.segname));
2704 section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
2705 memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
69499dca 2706 section->sectname[BFD_MACH_O_SECTNAME_SIZE] = 0;
46d1c23b
TG
2707 section->addr = bfd_h_get_64 (abfd, raw.addr);
2708 section->size = bfd_h_get_64 (abfd, raw.size);
2709 section->offset = bfd_h_get_32 (abfd, raw.offset);
2710 section->align = bfd_h_get_32 (abfd, raw.align);
2711 section->reloff = bfd_h_get_32 (abfd, raw.reloff);
2712 section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
2713 section->flags = bfd_h_get_32 (abfd, raw.flags);
2714 section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
2715 section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
2716 section->reserved3 = bfd_h_get_32 (abfd, raw.reserved3);
3af9a47b 2717
f1bde64c 2718 bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
3af9a47b 2719
f1bde64c 2720 return sec;
3af9a47b
NC
2721}
2722
f1bde64c 2723static asection *
ab273af8 2724bfd_mach_o_read_section (bfd *abfd,
ab273af8
TG
2725 unsigned int offset,
2726 unsigned long prot,
2727 unsigned int wide)
1e8a024a
TG
2728{
2729 if (wide)
f1bde64c 2730 return bfd_mach_o_read_section_64 (abfd, offset, prot);
1e8a024a 2731 else
f1bde64c 2732 return bfd_mach_o_read_section_32 (abfd, offset, prot);
1e8a024a
TG
2733}
2734
afbb9e17 2735static bfd_boolean
ab273af8
TG
2736bfd_mach_o_read_symtab_symbol (bfd *abfd,
2737 bfd_mach_o_symtab_command *sym,
2738 bfd_mach_o_asymbol *s,
2739 unsigned long i)
3af9a47b 2740{
046b007d 2741 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
c2f09c75 2742 unsigned int wide = mach_o_wide_p (&mdata->header);
046b007d
TG
2743 unsigned int symwidth =
2744 wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
92bc0e80 2745 unsigned int symoff = sym->symoff + (i * symwidth);
46d1c23b 2746 struct mach_o_nlist_64_external raw;
3af9a47b
NC
2747 unsigned char type = -1;
2748 unsigned char section = -1;
2749 short desc = -1;
1e8a024a 2750 symvalue value = -1;
3af9a47b
NC
2751 unsigned long stroff = -1;
2752 unsigned int symtype = -1;
2753
2754 BFD_ASSERT (sym->strtab != NULL);
2755
c2f09c75 2756 if (bfd_seek (abfd, symoff, SEEK_SET) != 0
46d1c23b 2757 || bfd_bread (&raw, symwidth, abfd) != symwidth)
3af9a47b 2758 {
46d1c23b
TG
2759 (*_bfd_error_handler)
2760 (_("bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"),
2761 symwidth, (unsigned long) symoff);
afbb9e17 2762 return FALSE;
3af9a47b
NC
2763 }
2764
46d1c23b
TG
2765 stroff = bfd_h_get_32 (abfd, raw.n_strx);
2766 type = bfd_h_get_8 (abfd, raw.n_type);
c2f09c75 2767 symtype = type & BFD_MACH_O_N_TYPE;
46d1c23b
TG
2768 section = bfd_h_get_8 (abfd, raw.n_sect);
2769 desc = bfd_h_get_16 (abfd, raw.n_desc);
1e8a024a 2770 if (wide)
46d1c23b 2771 value = bfd_h_get_64 (abfd, raw.n_value);
1e8a024a 2772 else
46d1c23b 2773 value = bfd_h_get_32 (abfd, raw.n_value);
3af9a47b
NC
2774
2775 if (stroff >= sym->strsize)
2776 {
46d1c23b
TG
2777 (*_bfd_error_handler)
2778 (_("bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"),
2779 (unsigned long) stroff,
2780 (unsigned long) sym->strsize);
afbb9e17 2781 return FALSE;
3af9a47b
NC
2782 }
2783
92bc0e80
TG
2784 s->symbol.the_bfd = abfd;
2785 s->symbol.name = sym->strtab + stroff;
2786 s->symbol.value = value;
2787 s->symbol.flags = 0x0;
b22161d6 2788 s->symbol.udata.i = i;
92bc0e80
TG
2789 s->n_type = type;
2790 s->n_sect = section;
2791 s->n_desc = desc;
3af9a47b
NC
2792
2793 if (type & BFD_MACH_O_N_STAB)
2794 {
92bc0e80
TG
2795 s->symbol.flags |= BSF_DEBUGGING;
2796 s->symbol.section = bfd_und_section_ptr;
15e1c58a
TG
2797 switch (type)
2798 {
2799 case N_FUN:
2800 case N_STSYM:
2801 case N_LCSYM:
2802 case N_BNSYM:
2803 case N_SLINE:
2804 case N_ENSYM:
2805 case N_ECOMM:
2806 case N_ECOML:
2807 case N_GSYM:
2808 if ((section > 0) && (section <= mdata->nsects))
2809 {
92bc0e80
TG
2810 s->symbol.section = mdata->sections[section - 1]->bfdsection;
2811 s->symbol.value =
2812 s->symbol.value - mdata->sections[section - 1]->addr;
15e1c58a
TG
2813 }
2814 break;
2815 }
3af9a47b
NC
2816 }
2817 else
2818 {
b22161d6 2819 if (type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT))
92bc0e80 2820 s->symbol.flags |= BSF_GLOBAL;
b22161d6 2821 else
92bc0e80 2822 s->symbol.flags |= BSF_LOCAL;
3af9a47b
NC
2823
2824 switch (symtype)
2825 {
2826 case BFD_MACH_O_N_UNDF:
c2f09c75 2827 if (type == (BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT)
92bc0e80 2828 && s->symbol.value != 0)
c2f09c75
TG
2829 {
2830 /* A common symbol. */
92bc0e80
TG
2831 s->symbol.section = bfd_com_section_ptr;
2832 s->symbol.flags = BSF_NO_FLAGS;
c2f09c75
TG
2833 }
2834 else
92bc0e80
TG
2835 {
2836 s->symbol.section = bfd_und_section_ptr;
2837 if (s->n_desc & BFD_MACH_O_N_WEAK_REF)
2838 s->symbol.flags |= BSF_WEAK;
2839 }
3af9a47b
NC
2840 break;
2841 case BFD_MACH_O_N_PBUD:
92bc0e80 2842 s->symbol.section = bfd_und_section_ptr;
3af9a47b
NC
2843 break;
2844 case BFD_MACH_O_N_ABS:
92bc0e80 2845 s->symbol.section = bfd_abs_section_ptr;
3af9a47b
NC
2846 break;
2847 case BFD_MACH_O_N_SECT:
2848 if ((section > 0) && (section <= mdata->nsects))
2849 {
92bc0e80
TG
2850 s->symbol.section = mdata->sections[section - 1]->bfdsection;
2851 s->symbol.value =
2852 s->symbol.value - mdata->sections[section - 1]->addr;
3af9a47b
NC
2853 }
2854 else
2855 {
2856 /* Mach-O uses 0 to mean "no section"; not an error. */
2857 if (section != 0)
2858 {
4a97a0e5
AM
2859 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
2860 "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"),
2861 s->symbol.name, section, mdata->nsects);
3af9a47b 2862 }
92bc0e80 2863 s->symbol.section = bfd_und_section_ptr;
3af9a47b
NC
2864 }
2865 break;
2866 case BFD_MACH_O_N_INDR:
0596a831
TG
2867 /* FIXME: we don't follow the BFD convention as this indirect symbol
2868 won't be followed by the referenced one. This looks harmless
2869 unless we start using the linker. */
2870 s->symbol.flags |= BSF_INDIRECT;
2871 s->symbol.section = bfd_ind_section_ptr;
2872 s->symbol.value = 0;
3af9a47b
NC
2873 break;
2874 default:
4a97a0e5
AM
2875 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
2876 "symbol \"%s\" specified invalid type field 0x%x: setting to undefined"),
2877 s->symbol.name, symtype);
92bc0e80 2878 s->symbol.section = bfd_und_section_ptr;
3af9a47b
NC
2879 break;
2880 }
2881 }
2882
afbb9e17 2883 return TRUE;
3af9a47b
NC
2884}
2885
c5012cd8 2886bfd_boolean
ab273af8 2887bfd_mach_o_read_symtab_strtab (bfd *abfd)
3af9a47b 2888{
046b007d
TG
2889 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2890 bfd_mach_o_symtab_command *sym = mdata->symtab;
2891
2892 /* Fail if there is no symtab. */
2893 if (sym == NULL)
afbb9e17 2894 return FALSE;
046b007d
TG
2895
2896 /* Success if already loaded. */
2897 if (sym->strtab)
afbb9e17 2898 return TRUE;
3af9a47b
NC
2899
2900 if (abfd->flags & BFD_IN_MEMORY)
2901 {
2902 struct bfd_in_memory *b;
2903
2904 b = (struct bfd_in_memory *) abfd->iostream;
2905
2906 if ((sym->stroff + sym->strsize) > b->size)
2907 {
2908 bfd_set_error (bfd_error_file_truncated);
afbb9e17 2909 return FALSE;
3af9a47b 2910 }
f075ee0c 2911 sym->strtab = (char *) b->buffer + sym->stroff;
3af9a47b 2912 }
046b007d 2913 else
3af9a47b 2914 {
046b007d
TG
2915 sym->strtab = bfd_alloc (abfd, sym->strsize);
2916 if (sym->strtab == NULL)
afbb9e17 2917 return FALSE;
046b007d
TG
2918
2919 if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0
afbb9e17 2920 || bfd_bread (sym->strtab, sym->strsize, abfd) != sym->strsize)
046b007d
TG
2921 {
2922 bfd_set_error (bfd_error_file_truncated);
afbb9e17 2923 return FALSE;
046b007d 2924 }
3af9a47b
NC
2925 }
2926
afbb9e17 2927 return TRUE;
3af9a47b
NC
2928}
2929
c5012cd8 2930bfd_boolean
ab273af8 2931bfd_mach_o_read_symtab_symbols (bfd *abfd)
3af9a47b 2932{
046b007d
TG
2933 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2934 bfd_mach_o_symtab_command *sym = mdata->symtab;
3af9a47b 2935 unsigned long i;
3af9a47b 2936
092d27ff
TG
2937 if (sym == NULL || sym->symbols)
2938 {
2939 /* Return now if there are no symbols or if already loaded. */
afbb9e17 2940 return TRUE;
092d27ff 2941 }
046b007d 2942
92bc0e80 2943 sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
3af9a47b
NC
2944
2945 if (sym->symbols == NULL)
2946 {
4a97a0e5 2947 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"));
afbb9e17 2948 return FALSE;
3af9a47b 2949 }
a95a4550 2950
afbb9e17
TG
2951 if (!bfd_mach_o_read_symtab_strtab (abfd))
2952 return FALSE;
3af9a47b
NC
2953
2954 for (i = 0; i < sym->nsyms; i++)
2955 {
afbb9e17
TG
2956 if (!bfd_mach_o_read_symtab_symbol (abfd, sym, &sym->symbols[i], i))
2957 return FALSE;
3af9a47b 2958 }
a95a4550 2959
afbb9e17 2960 return TRUE;
3af9a47b
NC
2961}
2962
2963static const char *
116c20d2 2964bfd_mach_o_i386_flavour_string (unsigned int flavour)
3af9a47b
NC
2965{
2966 switch ((int) flavour)
2967 {
15e1c58a
TG
2968 case BFD_MACH_O_x86_THREAD_STATE32: return "x86_THREAD_STATE32";
2969 case BFD_MACH_O_x86_FLOAT_STATE32: return "x86_FLOAT_STATE32";
2970 case BFD_MACH_O_x86_EXCEPTION_STATE32: return "x86_EXCEPTION_STATE32";
2971 case BFD_MACH_O_x86_THREAD_STATE64: return "x86_THREAD_STATE64";
2972 case BFD_MACH_O_x86_FLOAT_STATE64: return "x86_FLOAT_STATE64";
2973 case BFD_MACH_O_x86_EXCEPTION_STATE64: return "x86_EXCEPTION_STATE64";
2974 case BFD_MACH_O_x86_THREAD_STATE: return "x86_THREAD_STATE";
2975 case BFD_MACH_O_x86_FLOAT_STATE: return "x86_FLOAT_STATE";
2976 case BFD_MACH_O_x86_EXCEPTION_STATE: return "x86_EXCEPTION_STATE";
2977 case BFD_MACH_O_x86_DEBUG_STATE32: return "x86_DEBUG_STATE32";
2978 case BFD_MACH_O_x86_DEBUG_STATE64: return "x86_DEBUG_STATE64";
2979 case BFD_MACH_O_x86_DEBUG_STATE: return "x86_DEBUG_STATE";
b32e07d7 2980 case BFD_MACH_O_x86_THREAD_STATE_NONE: return "x86_THREAD_STATE_NONE";
3af9a47b
NC
2981 default: return "UNKNOWN";
2982 }
2983}
2984
2985static const char *
116c20d2 2986bfd_mach_o_ppc_flavour_string (unsigned int flavour)
3af9a47b
NC
2987{
2988 switch ((int) flavour)
2989 {
b32e07d7
TG
2990 case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
2991 case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
2992 case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
2993 case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
2994 case BFD_MACH_O_PPC_THREAD_STATE64: return "PPC_THREAD_STATE64";
2995 case BFD_MACH_O_PPC_EXCEPTION_STATE64: return "PPC_EXCEPTION_STATE64";
3af9a47b
NC
2996 default: return "UNKNOWN";
2997 }
2998}
2999
3000static int
ab273af8 3001bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b
NC
3002{
3003 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
46d1c23b 3004 struct mach_o_str_command_external raw;
3af9a47b 3005 unsigned int nameoff;
3af9a47b
NC
3006
3007 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
3008 || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
3009
46d1c23b
TG
3010 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3011 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
3012 return -1;
3013
46d1c23b 3014 nameoff = bfd_h_get_32 (abfd, raw.str);
3af9a47b
NC
3015
3016 cmd->name_offset = command->offset + nameoff;
3017 cmd->name_len = command->len - nameoff;
b32e07d7
TG
3018 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
3019 if (cmd->name_str == NULL)
3af9a47b 3020 return -1;
b32e07d7
TG
3021 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
3022 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
3af9a47b 3023 return -1;
3af9a47b
NC
3024 return 0;
3025}
3026
3027static int
ab273af8 3028bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b
NC
3029{
3030 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
46d1c23b 3031 struct mach_o_dylib_command_external raw;
3af9a47b 3032 unsigned int nameoff;
3af9a47b 3033
046b007d
TG
3034 switch (command->type)
3035 {
3036 case BFD_MACH_O_LC_LOAD_DYLIB:
046b007d 3037 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
046b007d 3038 case BFD_MACH_O_LC_ID_DYLIB:
046b007d 3039 case BFD_MACH_O_LC_REEXPORT_DYLIB:
73017762 3040 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
046b007d
TG
3041 break;
3042 default:
b32e07d7
TG
3043 BFD_FAIL ();
3044 return -1;
046b007d 3045 }
3af9a47b 3046
46d1c23b
TG
3047 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3048 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
3049 return -1;
3050
46d1c23b
TG
3051 nameoff = bfd_h_get_32 (abfd, raw.name);
3052 cmd->timestamp = bfd_h_get_32 (abfd, raw.timestamp);
3053 cmd->current_version = bfd_h_get_32 (abfd, raw.current_version);
3054 cmd->compatibility_version = bfd_h_get_32 (abfd, raw.compatibility_version);
3af9a47b
NC
3055
3056 cmd->name_offset = command->offset + nameoff;
3057 cmd->name_len = command->len - nameoff;
b32e07d7
TG
3058 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
3059 if (cmd->name_str == NULL)
3af9a47b 3060 return -1;
b32e07d7
TG
3061 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
3062 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
3af9a47b 3063 return -1;
3af9a47b
NC
3064 return 0;
3065}
3066
3067static int
ab273af8
TG
3068bfd_mach_o_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
3069 bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
3af9a47b
NC
3070{
3071 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
3072
3073 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
3074 return 0;
3075}
3076
9f4a5bd1
TG
3077static int
3078bfd_mach_o_read_fvmlib (bfd *abfd, bfd_mach_o_load_command *command)
3079{
3080 bfd_mach_o_fvmlib_command *fvm = &command->command.fvmlib;
3081 struct mach_o_fvmlib_command_external raw;
3082 unsigned int nameoff;
3083
3084 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3085 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3086 return -1;
3087
3088 nameoff = bfd_h_get_32 (abfd, raw.name);
3089 fvm->minor_version = bfd_h_get_32 (abfd, raw.minor_version);
3090 fvm->header_addr = bfd_h_get_32 (abfd, raw.header_addr);
3091
3092 fvm->name_offset = command->offset + nameoff;
3093 fvm->name_len = command->len - nameoff;
3094 fvm->name_str = bfd_alloc (abfd, fvm->name_len);
3095 if (fvm->name_str == NULL)
3096 return -1;
3097 if (bfd_seek (abfd, fvm->name_offset, SEEK_SET) != 0
3098 || bfd_bread (fvm->name_str, fvm->name_len, abfd) != fvm->name_len)
3099 return -1;
3100 return 0;
3101}
3102
3af9a47b 3103static int
ab273af8 3104bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 3105{
b32e07d7 3106 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 3107 bfd_mach_o_thread_command *cmd = &command->command.thread;
92bc0e80 3108 unsigned int offset;
3af9a47b
NC
3109 unsigned int nflavours;
3110 unsigned int i;
3111
3112 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
3113 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
3114
b32e07d7 3115 /* Count the number of threads. */
3af9a47b
NC
3116 offset = 8;
3117 nflavours = 0;
3118 while (offset != command->len)
3119 {
46d1c23b
TG
3120 struct mach_o_thread_command_external raw;
3121
3af9a47b
NC
3122 if (offset >= command->len)
3123 return -1;
3124
c2f09c75 3125 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
46d1c23b 3126 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
3127 return -1;
3128
46d1c23b 3129 offset += sizeof (raw) + bfd_h_get_32 (abfd, raw.count) * 4;
3af9a47b
NC
3130 nflavours++;
3131 }
3132
b32e07d7
TG
3133 /* Allocate threads. */
3134 cmd->flavours = bfd_alloc
3135 (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
3af9a47b
NC
3136 if (cmd->flavours == NULL)
3137 return -1;
3138 cmd->nflavours = nflavours;
3139
3140 offset = 8;
3141 nflavours = 0;
3142 while (offset != command->len)
3143 {
46d1c23b
TG
3144 struct mach_o_thread_command_external raw;
3145
3af9a47b
NC
3146 if (offset >= command->len)
3147 return -1;
3148
3149 if (nflavours >= cmd->nflavours)
3150 return -1;
3151
c2f09c75 3152 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
46d1c23b 3153 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
3154 return -1;
3155
46d1c23b
TG
3156 cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, raw.flavour);
3157 cmd->flavours[nflavours].offset = command->offset + offset + sizeof (raw);
3158 cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, raw.count) * 4;
3159 offset += cmd->flavours[nflavours].size + sizeof (raw);
3af9a47b
NC
3160 nflavours++;
3161 }
3162
3163 for (i = 0; i < nflavours; i++)
3164 {
3165 asection *bfdsec;
3166 unsigned int snamelen;
3167 char *sname;
3168 const char *flavourstr;
3169 const char *prefix = "LC_THREAD";
a95a4550
AM
3170 unsigned int j = 0;
3171
3af9a47b
NC
3172 switch (mdata->header.cputype)
3173 {
3174 case BFD_MACH_O_CPU_TYPE_POWERPC:
1e8a024a 3175 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
3af9a47b
NC
3176 flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
3177 break;
3178 case BFD_MACH_O_CPU_TYPE_I386:
1e8a024a 3179 case BFD_MACH_O_CPU_TYPE_X86_64:
3af9a47b
NC
3180 flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
3181 break;
3182 default:
3183 flavourstr = "UNKNOWN_ARCHITECTURE";
3184 break;
3185 }
a95a4550 3186
3af9a47b 3187 snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
116c20d2 3188 sname = bfd_alloc (abfd, snamelen);
3af9a47b
NC
3189 if (sname == NULL)
3190 return -1;
3191
3192 for (;;)
3193 {
a95a4550
AM
3194 sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
3195 if (bfd_get_section_by_name (abfd, sname) == NULL)
3af9a47b 3196 break;
a95a4550 3197 j++;
3af9a47b
NC
3198 }
3199
117ed4f8 3200 bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
a95a4550 3201
3af9a47b
NC
3202 bfdsec->vma = 0;
3203 bfdsec->lma = 0;
eea6121a 3204 bfdsec->size = cmd->flavours[i].size;
3af9a47b
NC
3205 bfdsec->filepos = cmd->flavours[i].offset;
3206 bfdsec->alignment_power = 0x0;
3af9a47b
NC
3207
3208 cmd->section = bfdsec;
3209 }
3210
3211 return 0;
3212}
3213
a95a4550 3214static int
ab273af8 3215bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 3216{
046b007d 3217 bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
b32e07d7 3218 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b
NC
3219
3220 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
3221
46d1c23b
TG
3222 {
3223 struct mach_o_dysymtab_command_external raw;
3224
3225 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3226 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3227 return -1;
3af9a47b 3228
46d1c23b
TG
3229 cmd->ilocalsym = bfd_h_get_32 (abfd, raw.ilocalsym);
3230 cmd->nlocalsym = bfd_h_get_32 (abfd, raw.nlocalsym);
3231 cmd->iextdefsym = bfd_h_get_32 (abfd, raw.iextdefsym);
3232 cmd->nextdefsym = bfd_h_get_32 (abfd, raw.nextdefsym);
3233 cmd->iundefsym = bfd_h_get_32 (abfd, raw.iundefsym);
3234 cmd->nundefsym = bfd_h_get_32 (abfd, raw.nundefsym);
3235 cmd->tocoff = bfd_h_get_32 (abfd, raw.tocoff);
3236 cmd->ntoc = bfd_h_get_32 (abfd, raw.ntoc);
3237 cmd->modtaboff = bfd_h_get_32 (abfd, raw.modtaboff);
3238 cmd->nmodtab = bfd_h_get_32 (abfd, raw.nmodtab);
3239 cmd->extrefsymoff = bfd_h_get_32 (abfd, raw.extrefsymoff);
3240 cmd->nextrefsyms = bfd_h_get_32 (abfd, raw.nextrefsyms);
3241 cmd->indirectsymoff = bfd_h_get_32 (abfd, raw.indirectsymoff);
3242 cmd->nindirectsyms = bfd_h_get_32 (abfd, raw.nindirectsyms);
3243 cmd->extreloff = bfd_h_get_32 (abfd, raw.extreloff);
3244 cmd->nextrel = bfd_h_get_32 (abfd, raw.nextrel);
3245 cmd->locreloff = bfd_h_get_32 (abfd, raw.locreloff);
3246 cmd->nlocrel = bfd_h_get_32 (abfd, raw.nlocrel);
3247 }
046b007d
TG
3248
3249 if (cmd->nmodtab != 0)
3250 {
046b007d
TG
3251 unsigned int i;
3252 int wide = bfd_mach_o_wide_p (abfd);
3253 unsigned int module_len = wide ? 56 : 52;
3254
3255 cmd->dylib_module =
3256 bfd_alloc (abfd, cmd->nmodtab * sizeof (bfd_mach_o_dylib_module));
3257 if (cmd->dylib_module == NULL)
3258 return -1;
3259
3260 if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0)
3261 return -1;
3262
3263 for (i = 0; i < cmd->nmodtab; i++)
3264 {
3265 bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
3266 unsigned long v;
46d1c23b 3267 unsigned char buf[56];
046b007d 3268
91d6fa6a 3269 if (bfd_bread ((void *) buf, module_len, abfd) != module_len)
046b007d
TG
3270 return -1;
3271
3272 module->module_name_idx = bfd_h_get_32 (abfd, buf + 0);
3273 module->iextdefsym = bfd_h_get_32 (abfd, buf + 4);
3274 module->nextdefsym = bfd_h_get_32 (abfd, buf + 8);
3275 module->irefsym = bfd_h_get_32 (abfd, buf + 12);
3276 module->nrefsym = bfd_h_get_32 (abfd, buf + 16);
3277 module->ilocalsym = bfd_h_get_32 (abfd, buf + 20);
3278 module->nlocalsym = bfd_h_get_32 (abfd, buf + 24);
3279 module->iextrel = bfd_h_get_32 (abfd, buf + 28);
3280 module->nextrel = bfd_h_get_32 (abfd, buf + 32);
3281 v = bfd_h_get_32 (abfd, buf +36);
3282 module->iinit = v & 0xffff;
3283 module->iterm = (v >> 16) & 0xffff;
3284 v = bfd_h_get_32 (abfd, buf + 40);
3285 module->ninit = v & 0xffff;
3286 module->nterm = (v >> 16) & 0xffff;
3287 if (wide)
3288 {
3289 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 44);
3290 module->objc_module_info_addr = bfd_h_get_64 (abfd, buf + 48);
3291 }
3292 else
3293 {
3294 module->objc_module_info_addr = bfd_h_get_32 (abfd, buf + 44);
3295 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 48);
3296 }
3297 }
3298 }
afbb9e17 3299
046b007d
TG
3300 if (cmd->ntoc != 0)
3301 {
046b007d
TG
3302 unsigned int i;
3303
3304 cmd->dylib_toc = bfd_alloc
3305 (abfd, cmd->ntoc * sizeof (bfd_mach_o_dylib_table_of_content));
3306 if (cmd->dylib_toc == NULL)
3307 return -1;
3308
3309 if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
3310 return -1;
3311
3312 for (i = 0; i < cmd->ntoc; i++)
3313 {
46d1c23b 3314 struct mach_o_dylib_table_of_contents_external raw;
046b007d
TG
3315 bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
3316
46d1c23b 3317 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
3318 return -1;
3319
46d1c23b
TG
3320 toc->symbol_index = bfd_h_get_32 (abfd, raw.symbol_index);
3321 toc->module_index = bfd_h_get_32 (abfd, raw.module_index);
046b007d
TG
3322 }
3323 }
3324
3325 if (cmd->nindirectsyms != 0)
3326 {
046b007d
TG
3327 unsigned int i;
3328
3329 cmd->indirect_syms = bfd_alloc
3330 (abfd, cmd->nindirectsyms * sizeof (unsigned int));
3331 if (cmd->indirect_syms == NULL)
3332 return -1;
3333
3334 if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
3335 return -1;
3336
3337 for (i = 0; i < cmd->nindirectsyms; i++)
3338 {
46d1c23b 3339 unsigned char raw[4];
046b007d
TG
3340 unsigned int *is = &cmd->indirect_syms[i];
3341
46d1c23b 3342 if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
3343 return -1;
3344
46d1c23b 3345 *is = bfd_h_get_32 (abfd, raw);
046b007d
TG
3346 }
3347 }
3348
3349 if (cmd->nextrefsyms != 0)
3350 {
046b007d
TG
3351 unsigned long v;
3352 unsigned int i;
3353
3354 cmd->ext_refs = bfd_alloc
3355 (abfd, cmd->nextrefsyms * sizeof (bfd_mach_o_dylib_reference));
3356 if (cmd->ext_refs == NULL)
3357 return -1;
3358
3359 if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
3360 return -1;
3361
3362 for (i = 0; i < cmd->nextrefsyms; i++)
3363 {
46d1c23b 3364 unsigned char raw[4];
046b007d
TG
3365 bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
3366
46d1c23b 3367 if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
3368 return -1;
3369
b32e07d7
TG
3370 /* Fields isym and flags are written as bit-fields, thus we need
3371 a specific processing for endianness. */
46d1c23b 3372 v = bfd_h_get_32 (abfd, raw);
b32e07d7
TG
3373 if (bfd_big_endian (abfd))
3374 {
3375 ref->isym = (v >> 8) & 0xffffff;
3376 ref->flags = v & 0xff;
3377 }
3378 else
3379 {
3380 ref->isym = v & 0xffffff;
3381 ref->flags = (v >> 24) & 0xff;
3382 }
046b007d
TG
3383 }
3384 }
3af9a47b 3385
b32e07d7
TG
3386 if (mdata->dysymtab)
3387 return -1;
3388 mdata->dysymtab = cmd;
3389
3af9a47b
NC
3390 return 0;
3391}
3392
a95a4550 3393static int
ab273af8 3394bfd_mach_o_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 3395{
046b007d
TG
3396 bfd_mach_o_symtab_command *symtab = &command->command.symtab;
3397 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
46d1c23b 3398 struct mach_o_symtab_command_external raw;
3af9a47b
NC
3399
3400 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
3401
46d1c23b
TG
3402 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3403 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b 3404 return -1;
a95a4550 3405
46d1c23b
TG
3406 symtab->symoff = bfd_h_get_32 (abfd, raw.symoff);
3407 symtab->nsyms = bfd_h_get_32 (abfd, raw.nsyms);
3408 symtab->stroff = bfd_h_get_32 (abfd, raw.stroff);
3409 symtab->strsize = bfd_h_get_32 (abfd, raw.strsize);
046b007d
TG
3410 symtab->symbols = NULL;
3411 symtab->strtab = NULL;
3af9a47b 3412
046b007d 3413 if (symtab->nsyms != 0)
15e1c58a
TG
3414 abfd->flags |= HAS_SYMS;
3415
046b007d
TG
3416 if (mdata->symtab)
3417 return -1;
3418 mdata->symtab = symtab;
3af9a47b
NC
3419 return 0;
3420}
3421
15e1c58a 3422static int
ab273af8 3423bfd_mach_o_read_uuid (bfd *abfd, bfd_mach_o_load_command *command)
15e1c58a
TG
3424{
3425 bfd_mach_o_uuid_command *cmd = &command->command.uuid;
15e1c58a
TG
3426
3427 BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
3428
46d1c23b
TG
3429 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3430 || bfd_bread (cmd->uuid, 16, abfd) != 16)
15e1c58a
TG
3431 return -1;
3432
15e1c58a
TG
3433 return 0;
3434}
3435
046b007d 3436static int
ab273af8 3437bfd_mach_o_read_linkedit (bfd *abfd, bfd_mach_o_load_command *command)
046b007d
TG
3438{
3439 bfd_mach_o_linkedit_command *cmd = &command->command.linkedit;
46d1c23b 3440 struct mach_o_linkedit_data_command_external raw;
046b007d 3441
46d1c23b
TG
3442 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3443 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
3444 return -1;
3445
46d1c23b
TG
3446 cmd->dataoff = bfd_get_32 (abfd, raw.dataoff);
3447 cmd->datasize = bfd_get_32 (abfd, raw.datasize);
046b007d
TG
3448 return 0;
3449}
3450
3451static int
ab273af8 3452bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command)
046b007d
TG
3453{
3454 bfd_mach_o_str_command *cmd = &command->command.str;
46d1c23b 3455 struct mach_o_str_command_external raw;
046b007d
TG
3456 unsigned long off;
3457
46d1c23b
TG
3458 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3459 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
3460 return -1;
3461
46d1c23b 3462 off = bfd_get_32 (abfd, raw.str);
046b007d
TG
3463 cmd->stroff = command->offset + off;
3464 cmd->str_len = command->len - off;
3465 cmd->str = bfd_alloc (abfd, cmd->str_len);
3466 if (cmd->str == NULL)
3467 return -1;
3468 if (bfd_seek (abfd, cmd->stroff, SEEK_SET) != 0
91d6fa6a 3469 || bfd_bread ((void *) cmd->str, cmd->str_len, abfd) != cmd->str_len)
046b007d
TG
3470 return -1;
3471 return 0;
3472}
3473
ad86f1fb 3474static int
ab273af8 3475bfd_mach_o_read_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
ad86f1fb
TG
3476{
3477 bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
46d1c23b 3478 struct mach_o_dyld_info_command_external raw;
ad86f1fb 3479
46d1c23b
TG
3480 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3481 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
ad86f1fb
TG
3482 return -1;
3483
46d1c23b
TG
3484 cmd->rebase_off = bfd_get_32 (abfd, raw.rebase_off);
3485 cmd->rebase_size = bfd_get_32 (abfd, raw.rebase_size);
3486 cmd->bind_off = bfd_get_32 (abfd, raw.bind_off);
3487 cmd->bind_size = bfd_get_32 (abfd, raw.bind_size);
3488 cmd->weak_bind_off = bfd_get_32 (abfd, raw.weak_bind_off);
3489 cmd->weak_bind_size = bfd_get_32 (abfd, raw.weak_bind_size);
3490 cmd->lazy_bind_off = bfd_get_32 (abfd, raw.lazy_bind_off);
3491 cmd->lazy_bind_size = bfd_get_32 (abfd, raw.lazy_bind_size);
3492 cmd->export_off = bfd_get_32 (abfd, raw.export_off);
3493 cmd->export_size = bfd_get_32 (abfd, raw.export_size);
ad86f1fb
TG
3494 return 0;
3495}
3496
edbdea0e
TG
3497static bfd_boolean
3498bfd_mach_o_read_version_min (bfd *abfd, bfd_mach_o_load_command *command)
3499{
3500 bfd_mach_o_version_min_command *cmd = &command->command.version_min;
3501 struct mach_o_version_min_command_external raw;
3502 unsigned int ver;
3503
3504 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3505 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3506 return FALSE;
3507
3508 ver = bfd_get_32 (abfd, raw.version);
3509 cmd->rel = ver >> 16;
3510 cmd->maj = ver >> 8;
3511 cmd->min = ver;
3512 cmd->reserved = bfd_get_32 (abfd, raw.reserved);
3513 return TRUE;
3514}
3515
fc55a902
TG
3516static bfd_boolean
3517bfd_mach_o_read_encryption_info (bfd *abfd, bfd_mach_o_load_command *command)
3518{
3519 bfd_mach_o_encryption_info_command *cmd = &command->command.encryption_info;
3520 struct mach_o_encryption_info_command_external raw;
3521
3522 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3523 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3524 return FALSE;
3525
3526 cmd->cryptoff = bfd_get_32 (abfd, raw.cryptoff);
3527 cmd->cryptsize = bfd_get_32 (abfd, raw.cryptsize);
3528 cmd->cryptid = bfd_get_32 (abfd, raw.cryptid);
3529 return TRUE;
3530}
3531
3af9a47b 3532static int
ab273af8
TG
3533bfd_mach_o_read_segment (bfd *abfd,
3534 bfd_mach_o_load_command *command,
3535 unsigned int wide)
3af9a47b 3536{
3af9a47b
NC
3537 bfd_mach_o_segment_command *seg = &command->command.segment;
3538 unsigned long i;
a95a4550 3539
1e8a024a
TG
3540 if (wide)
3541 {
46d1c23b
TG
3542 struct mach_o_segment_command_64_external raw;
3543
1e8a024a 3544 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
3af9a47b 3545
46d1c23b
TG
3546 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3547 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3548 return -1;
3af9a47b 3549
46d1c23b 3550 memcpy (seg->segname, raw.segname, 16);
15e1c58a 3551 seg->segname[16] = '\0';
1e8a024a 3552
46d1c23b
TG
3553 seg->vmaddr = bfd_h_get_64 (abfd, raw.vmaddr);
3554 seg->vmsize = bfd_h_get_64 (abfd, raw.vmsize);
3555 seg->fileoff = bfd_h_get_64 (abfd, raw.fileoff);
3556 seg->filesize = bfd_h_get_64 (abfd, raw.filesize);
3557 seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
3558 seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
3559 seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
3560 seg->flags = bfd_h_get_32 (abfd, raw.flags);
1e8a024a
TG
3561 }
3562 else
3563 {
46d1c23b
TG
3564 struct mach_o_segment_command_32_external raw;
3565
1e8a024a
TG
3566 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
3567
46d1c23b
TG
3568 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3569 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3570 return -1;
1e8a024a 3571
46d1c23b 3572 memcpy (seg->segname, raw.segname, 16);
15e1c58a 3573 seg->segname[16] = '\0';
1e8a024a 3574
46d1c23b
TG
3575 seg->vmaddr = bfd_h_get_32 (abfd, raw.vmaddr);
3576 seg->vmsize = bfd_h_get_32 (abfd, raw.vmsize);
3577 seg->fileoff = bfd_h_get_32 (abfd, raw.fileoff);
3578 seg->filesize = bfd_h_get_32 (abfd, raw.filesize);
3579 seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
3580 seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
3581 seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
3582 seg->flags = bfd_h_get_32 (abfd, raw.flags);
1e8a024a 3583 }
9d4b6009
TG
3584 seg->sect_head = NULL;
3585 seg->sect_tail = NULL;
3af9a47b 3586
f1bde64c 3587 for (i = 0; i < seg->nsects; i++)
3af9a47b 3588 {
f1bde64c
TG
3589 bfd_vma segoff;
3590 asection *sec;
a95a4550 3591
f1bde64c
TG
3592 if (wide)
3593 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
3594 + (i * BFD_MACH_O_SECTION_64_SIZE);
3595 else
3596 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
3597 + (i * BFD_MACH_O_SECTION_SIZE);
3af9a47b 3598
f1bde64c
TG
3599 sec = bfd_mach_o_read_section (abfd, segoff, seg->initprot, wide);
3600 if (sec == NULL)
3601 return -1;
3602
3603 bfd_mach_o_append_section_to_segment (seg, sec);
3af9a47b
NC
3604 }
3605
3606 return 0;
3607}
3608
1e8a024a 3609static int
ab273af8 3610bfd_mach_o_read_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 3611{
ab273af8 3612 return bfd_mach_o_read_segment (abfd, command, 0);
1e8a024a
TG
3613}
3614
3615static int
ab273af8 3616bfd_mach_o_read_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 3617{
ab273af8 3618 return bfd_mach_o_read_segment (abfd, command, 1);
1e8a024a
TG
3619}
3620
3af9a47b 3621static int
ab273af8 3622bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 3623{
46d1c23b
TG
3624 struct mach_o_load_command_external raw;
3625 unsigned int cmd;
3af9a47b 3626
046b007d 3627 /* Read command type and length. */
c2f09c75 3628 if (bfd_seek (abfd, command->offset, SEEK_SET) != 0
46d1c23b 3629 || bfd_bread (&raw, BFD_MACH_O_LC_SIZE, abfd) != BFD_MACH_O_LC_SIZE)
3af9a47b
NC
3630 return -1;
3631
46d1c23b
TG
3632 cmd = bfd_h_get_32 (abfd, raw.cmd);
3633 command->type = cmd & ~BFD_MACH_O_LC_REQ_DYLD;
3634 command->type_required = cmd & BFD_MACH_O_LC_REQ_DYLD ? TRUE : FALSE;
3635 command->len = bfd_h_get_32 (abfd, raw.cmdsize);
3af9a47b
NC
3636
3637 switch (command->type)
3638 {
3639 case BFD_MACH_O_LC_SEGMENT:
ab273af8 3640 if (bfd_mach_o_read_segment_32 (abfd, command) != 0)
1e8a024a
TG
3641 return -1;
3642 break;
3643 case BFD_MACH_O_LC_SEGMENT_64:
ab273af8 3644 if (bfd_mach_o_read_segment_64 (abfd, command) != 0)
3af9a47b
NC
3645 return -1;
3646 break;
3647 case BFD_MACH_O_LC_SYMTAB:
ab273af8 3648 if (bfd_mach_o_read_symtab (abfd, command) != 0)
3af9a47b
NC
3649 return -1;
3650 break;
3651 case BFD_MACH_O_LC_SYMSEG:
3652 break;
3653 case BFD_MACH_O_LC_THREAD:
3654 case BFD_MACH_O_LC_UNIXTHREAD:
ab273af8 3655 if (bfd_mach_o_read_thread (abfd, command) != 0)
3af9a47b
NC
3656 return -1;
3657 break;
3658 case BFD_MACH_O_LC_LOAD_DYLINKER:
3659 case BFD_MACH_O_LC_ID_DYLINKER:
ab273af8 3660 if (bfd_mach_o_read_dylinker (abfd, command) != 0)
3af9a47b
NC
3661 return -1;
3662 break;
3663 case BFD_MACH_O_LC_LOAD_DYLIB:
3664 case BFD_MACH_O_LC_ID_DYLIB:
3665 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
046b007d 3666 case BFD_MACH_O_LC_REEXPORT_DYLIB:
73017762 3667 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
ab273af8 3668 if (bfd_mach_o_read_dylib (abfd, command) != 0)
3af9a47b
NC
3669 return -1;
3670 break;
3671 case BFD_MACH_O_LC_PREBOUND_DYLIB:
ab273af8 3672 if (bfd_mach_o_read_prebound_dylib (abfd, command) != 0)
3af9a47b
NC
3673 return -1;
3674 break;
3675 case BFD_MACH_O_LC_LOADFVMLIB:
3676 case BFD_MACH_O_LC_IDFVMLIB:
9f4a5bd1
TG
3677 if (bfd_mach_o_read_fvmlib (abfd, command) != 0)
3678 return -1;
3679 break;
3af9a47b
NC
3680 case BFD_MACH_O_LC_IDENT:
3681 case BFD_MACH_O_LC_FVMFILE:
3682 case BFD_MACH_O_LC_PREPAGE:
3683 case BFD_MACH_O_LC_ROUTINES:
9b02d212 3684 case BFD_MACH_O_LC_ROUTINES_64:
046b007d 3685 break;
3af9a47b 3686 case BFD_MACH_O_LC_SUB_FRAMEWORK:
046b007d
TG
3687 case BFD_MACH_O_LC_SUB_UMBRELLA:
3688 case BFD_MACH_O_LC_SUB_LIBRARY:
3689 case BFD_MACH_O_LC_SUB_CLIENT:
0c9b2b4c 3690 case BFD_MACH_O_LC_RPATH:
ab273af8 3691 if (bfd_mach_o_read_str (abfd, command) != 0)
046b007d 3692 return -1;
3af9a47b
NC
3693 break;
3694 case BFD_MACH_O_LC_DYSYMTAB:
ab273af8 3695 if (bfd_mach_o_read_dysymtab (abfd, command) != 0)
3af9a47b
NC
3696 return -1;
3697 break;
3af9a47b
NC
3698 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
3699 case BFD_MACH_O_LC_PREBIND_CKSUM:
3700 break;
15e1c58a 3701 case BFD_MACH_O_LC_UUID:
ab273af8 3702 if (bfd_mach_o_read_uuid (abfd, command) != 0)
15e1c58a
TG
3703 return -1;
3704 break;
3705 case BFD_MACH_O_LC_CODE_SIGNATURE:
846b9259 3706 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
edbdea0e 3707 case BFD_MACH_O_LC_FUNCTION_STARTS:
ab273af8 3708 if (bfd_mach_o_read_linkedit (abfd, command) != 0)
046b007d 3709 return -1;
15e1c58a 3710 break;
fc55a902
TG
3711 case BFD_MACH_O_LC_ENCRYPTION_INFO:
3712 if (!bfd_mach_o_read_encryption_info (abfd, command))
3713 return -1;
3714 break;
ad86f1fb 3715 case BFD_MACH_O_LC_DYLD_INFO:
ab273af8 3716 if (bfd_mach_o_read_dyld_info (abfd, command) != 0)
ad86f1fb
TG
3717 return -1;
3718 break;
edbdea0e
TG
3719 case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
3720 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
3721 if (!bfd_mach_o_read_version_min (abfd, command))
3722 return -1;
3723 break;
3af9a47b 3724 default:
fc55a902 3725 (*_bfd_error_handler)(_("%B: unknown load command 0x%lx"),
c0d9d051 3726 abfd, (unsigned long) command->type);
3af9a47b
NC
3727 break;
3728 }
3729
3730 return 0;
3731}
3732
3733static void
116c20d2 3734bfd_mach_o_flatten_sections (bfd *abfd)
3af9a47b 3735{
046b007d 3736 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 3737 long csect = 0;
f1bde64c 3738 unsigned long i;
a95a4550 3739
15e1c58a 3740 /* Count total number of sections. */
3af9a47b
NC
3741 mdata->nsects = 0;
3742
3743 for (i = 0; i < mdata->header.ncmds; i++)
3744 {
1e8a024a
TG
3745 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
3746 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
3af9a47b 3747 {
e84d6fca
AM
3748 bfd_mach_o_segment_command *seg;
3749
3750 seg = &mdata->commands[i].command.segment;
3af9a47b
NC
3751 mdata->nsects += seg->nsects;
3752 }
3753 }
3754
15e1c58a 3755 /* Allocate sections array. */
e84d6fca
AM
3756 mdata->sections = bfd_alloc (abfd,
3757 mdata->nsects * sizeof (bfd_mach_o_section *));
15e1c58a
TG
3758
3759 /* Fill the array. */
3af9a47b
NC
3760 csect = 0;
3761
3762 for (i = 0; i < mdata->header.ncmds; i++)
3763 {
1e8a024a
TG
3764 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
3765 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
3af9a47b 3766 {
e84d6fca 3767 bfd_mach_o_segment_command *seg;
f1bde64c 3768 bfd_mach_o_section *sec;
3af9a47b 3769
e84d6fca 3770 seg = &mdata->commands[i].command.segment;
3af9a47b
NC
3771 BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
3772
f1bde64c
TG
3773 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
3774 mdata->sections[csect++] = sec;
3af9a47b
NC
3775 }
3776 }
3777}
3778
afbb9e17 3779static bfd_boolean
116c20d2 3780bfd_mach_o_scan_start_address (bfd *abfd)
3af9a47b 3781{
046b007d 3782 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b
NC
3783 bfd_mach_o_thread_command *cmd = NULL;
3784 unsigned long i;
3785
3786 for (i = 0; i < mdata->header.ncmds; i++)
afbb9e17
TG
3787 if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
3788 (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
3789 {
3790 cmd = &mdata->commands[i].command.thread;
3791 break;
3792 }
3af9a47b
NC
3793
3794 if (cmd == NULL)
afbb9e17 3795 return FALSE;
3af9a47b 3796
afbb9e17 3797 /* FIXME: create a subtarget hook ? */
3af9a47b
NC
3798 for (i = 0; i < cmd->nflavours; i++)
3799 {
a95a4550 3800 if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
e84d6fca 3801 && (cmd->flavours[i].flavour
15e1c58a 3802 == (unsigned long) BFD_MACH_O_x86_THREAD_STATE32))
3af9a47b
NC
3803 {
3804 unsigned char buf[4];
3805
c2f09c75
TG
3806 if (bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET) != 0
3807 || bfd_bread (buf, 4, abfd) != 4)
afbb9e17 3808 return FALSE;
3af9a47b
NC
3809
3810 abfd->start_address = bfd_h_get_32 (abfd, buf);
3811 }
a95a4550 3812 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
3af9a47b
NC
3813 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
3814 {
3815 unsigned char buf[4];
3816
c2f09c75
TG
3817 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
3818 || bfd_bread (buf, 4, abfd) != 4)
afbb9e17 3819 return FALSE;
3af9a47b
NC
3820
3821 abfd->start_address = bfd_h_get_32 (abfd, buf);
3822 }
1e8a024a 3823 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
b32e07d7 3824 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE64))
1e8a024a
TG
3825 {
3826 unsigned char buf[8];
3827
c2f09c75
TG
3828 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
3829 || bfd_bread (buf, 8, abfd) != 8)
afbb9e17 3830 return FALSE;
1e8a024a
TG
3831
3832 abfd->start_address = bfd_h_get_64 (abfd, buf);
3833 }
3834 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
3835 && (cmd->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE64))
3836 {
3837 unsigned char buf[8];
3838
c2f09c75
TG
3839 if (bfd_seek (abfd, cmd->flavours[i].offset + (16 * 8), SEEK_SET) != 0
3840 || bfd_bread (buf, 8, abfd) != 8)
afbb9e17 3841 return FALSE;
1e8a024a
TG
3842
3843 abfd->start_address = bfd_h_get_64 (abfd, buf);
3844 }
3af9a47b
NC
3845 }
3846
afbb9e17 3847 return TRUE;
3af9a47b
NC
3848}
3849
42fa0891
TG
3850bfd_boolean
3851bfd_mach_o_set_arch_mach (bfd *abfd,
3852 enum bfd_architecture arch,
3853 unsigned long machine)
3854{
3855 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
3856
3857 /* If this isn't the right architecture for this backend, and this
3858 isn't the generic backend, fail. */
3859 if (arch != bed->arch
3860 && arch != bfd_arch_unknown
3861 && bed->arch != bfd_arch_unknown)
3862 return FALSE;
3863
3864 return bfd_default_set_arch_mach (abfd, arch, machine);
3865}
3866
afbb9e17 3867static bfd_boolean
116c20d2
NC
3868bfd_mach_o_scan (bfd *abfd,
3869 bfd_mach_o_header *header,
3870 bfd_mach_o_data_struct *mdata)
3af9a47b
NC
3871{
3872 unsigned int i;
3af9a47b
NC
3873 enum bfd_architecture cputype;
3874 unsigned long cpusubtype;
1e8a024a
TG
3875 unsigned int hdrsize;
3876
c2f09c75 3877 hdrsize = mach_o_wide_p (header) ?
154a1ee5 3878 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
3af9a47b 3879
3af9a47b 3880 mdata->header = *header;
3af9a47b 3881
154a1ee5 3882 abfd->flags = abfd->flags & BFD_IN_MEMORY;
15e1c58a
TG
3883 switch (header->filetype)
3884 {
3885 case BFD_MACH_O_MH_OBJECT:
3886 abfd->flags |= HAS_RELOC;
3887 break;
3888 case BFD_MACH_O_MH_EXECUTE:
3889 abfd->flags |= EXEC_P;
3890 break;
3891 case BFD_MACH_O_MH_DYLIB:
3892 case BFD_MACH_O_MH_BUNDLE:
3893 abfd->flags |= DYNAMIC;
3894 break;
3895 }
3896
3af9a47b
NC
3897 abfd->tdata.mach_o_data = mdata;
3898
e84d6fca
AM
3899 bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
3900 &cputype, &cpusubtype);
3af9a47b
NC
3901 if (cputype == bfd_arch_unknown)
3902 {
afbb9e17
TG
3903 (*_bfd_error_handler)
3904 (_("bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"),
3905 header->cputype, header->cpusubtype);
3906 return FALSE;
3af9a47b
NC
3907 }
3908
3909 bfd_set_arch_mach (abfd, cputype, cpusubtype);
a95a4550 3910
3af9a47b
NC
3911 if (header->ncmds != 0)
3912 {
046b007d
TG
3913 mdata->commands = bfd_alloc
3914 (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
3af9a47b 3915 if (mdata->commands == NULL)
afbb9e17 3916 return FALSE;
a95a4550 3917
3af9a47b
NC
3918 for (i = 0; i < header->ncmds; i++)
3919 {
3920 bfd_mach_o_load_command *cur = &mdata->commands[i];
3921
3922 if (i == 0)
1e8a024a 3923 cur->offset = hdrsize;
3af9a47b
NC
3924 else
3925 {
3926 bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
3927 cur->offset = prev->offset + prev->len;
3928 }
3929
ab273af8 3930 if (bfd_mach_o_read_command (abfd, cur) < 0)
afbb9e17 3931 return FALSE;
a95a4550 3932 }
3af9a47b
NC
3933 }
3934
3935 if (bfd_mach_o_scan_start_address (abfd) < 0)
afbb9e17 3936 return FALSE;
3af9a47b
NC
3937
3938 bfd_mach_o_flatten_sections (abfd);
afbb9e17 3939 return TRUE;
3af9a47b
NC
3940}
3941
b34976b6 3942bfd_boolean
154a1ee5 3943bfd_mach_o_mkobject_init (bfd *abfd)
3af9a47b
NC
3944{
3945 bfd_mach_o_data_struct *mdata = NULL;
3946
116c20d2 3947 mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
3af9a47b 3948 if (mdata == NULL)
b34976b6 3949 return FALSE;
3af9a47b
NC
3950 abfd->tdata.mach_o_data = mdata;
3951
3952 mdata->header.magic = 0;
3953 mdata->header.cputype = 0;
3954 mdata->header.cpusubtype = 0;
3955 mdata->header.filetype = 0;
3956 mdata->header.ncmds = 0;
3957 mdata->header.sizeofcmds = 0;
3958 mdata->header.flags = 0;
3959 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
3960 mdata->commands = NULL;
3af9a47b
NC
3961 mdata->nsects = 0;
3962 mdata->sections = NULL;
4434114c 3963 mdata->dyn_reloc_cache = NULL;
3af9a47b 3964
b34976b6 3965 return TRUE;
3af9a47b
NC
3966}
3967
42fa0891
TG
3968static bfd_boolean
3969bfd_mach_o_gen_mkobject (bfd *abfd)
3970{
3971 bfd_mach_o_data_struct *mdata;
3972
3973 if (!bfd_mach_o_mkobject_init (abfd))
3974 return FALSE;
3975
3976 mdata = bfd_mach_o_get_data (abfd);
3977 mdata->header.magic = BFD_MACH_O_MH_MAGIC;
3978 mdata->header.cputype = 0;
3979 mdata->header.cpusubtype = 0;
3980 mdata->header.byteorder = abfd->xvec->byteorder;
3981 mdata->header.version = 1;
3982
3983 return TRUE;
3984}
3985
3af9a47b 3986const bfd_target *
154a1ee5
TG
3987bfd_mach_o_header_p (bfd *abfd,
3988 bfd_mach_o_filetype filetype,
3989 bfd_mach_o_cpu_type cputype)
3af9a47b 3990{
e84d6fca 3991 struct bfd_preserve preserve;
3af9a47b
NC
3992 bfd_mach_o_header header;
3993
e84d6fca 3994 preserve.marker = NULL;
154a1ee5 3995 if (!bfd_mach_o_read_header (abfd, &header))
e84d6fca 3996 goto wrong;
3af9a47b 3997
e84d6fca
AM
3998 if (! (header.byteorder == BFD_ENDIAN_BIG
3999 || header.byteorder == BFD_ENDIAN_LITTLE))
3af9a47b 4000 {
4a97a0e5
AM
4001 (*_bfd_error_handler) (_("unknown header byte-order value 0x%lx"),
4002 (unsigned long) header.byteorder);
e84d6fca 4003 goto wrong;
3af9a47b
NC
4004 }
4005
e84d6fca
AM
4006 if (! ((header.byteorder == BFD_ENDIAN_BIG
4007 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
4008 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
4009 || (header.byteorder == BFD_ENDIAN_LITTLE
4010 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
4011 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
4012 goto wrong;
3af9a47b 4013
154a1ee5
TG
4014 /* Check cputype and filetype.
4015 In case of wildcard, do not accept magics that are handled by existing
4016 targets. */
4017 if (cputype)
4018 {
4019 if (header.cputype != cputype)
4020 goto wrong;
4021 }
b22161d6 4022
154a1ee5
TG
4023 if (filetype)
4024 {
4025 if (header.filetype != filetype)
4026 goto wrong;
4027 }
4028 else
4029 {
4030 switch (header.filetype)
4031 {
4032 case BFD_MACH_O_MH_CORE:
4033 /* Handled by core_p */
4034 goto wrong;
4035 default:
4036 break;
4037 }
4038 }
4039
e84d6fca
AM
4040 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
4041 if (preserve.marker == NULL
4042 || !bfd_preserve_save (abfd, &preserve))
4043 goto fail;
3af9a47b 4044
afbb9e17
TG
4045 if (!bfd_mach_o_scan (abfd, &header,
4046 (bfd_mach_o_data_struct *) preserve.marker))
e84d6fca 4047 goto wrong;
a95a4550 4048
e84d6fca 4049 bfd_preserve_finish (abfd, &preserve);
3af9a47b 4050 return abfd->xvec;
e84d6fca
AM
4051
4052 wrong:
4053 bfd_set_error (bfd_error_wrong_format);
4054
4055 fail:
4056 if (preserve.marker != NULL)
4057 bfd_preserve_restore (abfd, &preserve);
4058 return NULL;
3af9a47b
NC
4059}
4060
154a1ee5
TG
4061static const bfd_target *
4062bfd_mach_o_gen_object_p (bfd *abfd)
3af9a47b 4063{
154a1ee5
TG
4064 return bfd_mach_o_header_p (abfd, 0, 0);
4065}
e84d6fca 4066
154a1ee5
TG
4067static const bfd_target *
4068bfd_mach_o_gen_core_p (bfd *abfd)
4069{
4070 return bfd_mach_o_header_p (abfd, BFD_MACH_O_MH_CORE, 0);
3af9a47b
NC
4071}
4072
4073typedef struct mach_o_fat_archentry
4074{
4075 unsigned long cputype;
4076 unsigned long cpusubtype;
4077 unsigned long offset;
4078 unsigned long size;
4079 unsigned long align;
3af9a47b
NC
4080} mach_o_fat_archentry;
4081
4082typedef struct mach_o_fat_data_struct
4083{
4084 unsigned long magic;
4085 unsigned long nfat_arch;
4086 mach_o_fat_archentry *archentries;
4087} mach_o_fat_data_struct;
4088
4089const bfd_target *
116c20d2 4090bfd_mach_o_archive_p (bfd *abfd)
3af9a47b 4091{
e84d6fca 4092 mach_o_fat_data_struct *adata = NULL;
46d1c23b 4093 struct mach_o_fat_header_external hdr;
3af9a47b
NC
4094 unsigned long i;
4095
c2f09c75 4096 if (bfd_seek (abfd, 0, SEEK_SET) != 0
46d1c23b 4097 || bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
e84d6fca 4098 goto error;
3af9a47b 4099
116c20d2 4100 adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
3af9a47b 4101 if (adata == NULL)
e84d6fca 4102 goto error;
a95a4550 4103
46d1c23b
TG
4104 adata->magic = bfd_getb32 (hdr.magic);
4105 adata->nfat_arch = bfd_getb32 (hdr.nfat_arch);
3af9a47b 4106 if (adata->magic != 0xcafebabe)
e84d6fca 4107 goto error;
27cc28f9
AS
4108 /* Avoid matching Java bytecode files, which have the same magic number.
4109 In the Java bytecode file format this field contains the JVM version,
4110 which starts at 43.0. */
4111 if (adata->nfat_arch > 30)
4112 goto error;
3af9a47b 4113
c2f09c75 4114 adata->archentries =
3af9a47b
NC
4115 bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
4116 if (adata->archentries == NULL)
e84d6fca 4117 goto error;
3af9a47b
NC
4118
4119 for (i = 0; i < adata->nfat_arch; i++)
4120 {
46d1c23b
TG
4121 struct mach_o_fat_arch_external arch;
4122 if (bfd_bread (&arch, sizeof (arch), abfd) != sizeof (arch))
e84d6fca 4123 goto error;
46d1c23b
TG
4124 adata->archentries[i].cputype = bfd_getb32 (arch.cputype);
4125 adata->archentries[i].cpusubtype = bfd_getb32 (arch.cpusubtype);
4126 adata->archentries[i].offset = bfd_getb32 (arch.offset);
4127 adata->archentries[i].size = bfd_getb32 (arch.size);
4128 adata->archentries[i].align = bfd_getb32 (arch.align);
3af9a47b
NC
4129 }
4130
4131 abfd->tdata.mach_o_fat_data = adata;
4132 return abfd->xvec;
e84d6fca
AM
4133
4134 error:
4135 if (adata != NULL)
4136 bfd_release (abfd, adata);
4137 bfd_set_error (bfd_error_wrong_format);
4138 return NULL;
3af9a47b
NC
4139}
4140
a4e241ca
TG
4141/* Set the filename for a fat binary member ABFD, whose bfd architecture is
4142 ARCH_TYPE/ARCH_SUBTYPE and corresponding entry in header is ENTRY.
4143 Set arelt_data and origin fields too. */
4144
4145static void
4146bfd_mach_o_fat_member_init (bfd *abfd,
4147 enum bfd_architecture arch_type,
4148 unsigned long arch_subtype,
4149 mach_o_fat_archentry *entry)
4150{
4151 struct areltdata *areltdata;
4152 /* Create the member filename. Use ARCH_NAME. */
4153 const bfd_arch_info_type *ap = bfd_lookup_arch (arch_type, arch_subtype);
4154
4155 if (ap)
4156 {
4157 /* Use the architecture name if known. */
4158 abfd->filename = ap->printable_name;
4159 }
4160 else
4161 {
4162 /* Forge a uniq id. */
4163 const size_t namelen = 2 + 8 + 1 + 2 + 8 + 1;
4164 char *name = bfd_alloc (abfd, namelen);
4165 snprintf (name, namelen, "0x%lx-0x%lx",
4166 entry->cputype, entry->cpusubtype);
4167 abfd->filename = name;
4168 }
4169
4170 areltdata = bfd_zalloc (abfd, sizeof (struct areltdata));
4171 areltdata->parsed_size = entry->size;
4172 abfd->arelt_data = areltdata;
4173 abfd->iostream = NULL;
4174 abfd->origin = entry->offset;
4175}
4176
3af9a47b 4177bfd *
116c20d2 4178bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
3af9a47b 4179{
e84d6fca 4180 mach_o_fat_data_struct *adata;
3af9a47b
NC
4181 mach_o_fat_archentry *entry = NULL;
4182 unsigned long i;
15e1c58a 4183 bfd *nbfd;
15e1c58a
TG
4184 enum bfd_architecture arch_type;
4185 unsigned long arch_subtype;
3af9a47b 4186
e84d6fca 4187 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
3af9a47b
NC
4188 BFD_ASSERT (adata != NULL);
4189
4190 /* Find index of previous entry. */
4191 if (prev == NULL)
a4e241ca
TG
4192 {
4193 /* Start at first one. */
4194 i = 0;
4195 }
3af9a47b
NC
4196 else
4197 {
a4e241ca 4198 /* Find index of PREV. */
3af9a47b
NC
4199 for (i = 0; i < adata->nfat_arch; i++)
4200 {
15e1c58a 4201 if (adata->archentries[i].offset == prev->origin)
3af9a47b
NC
4202 break;
4203 }
4204
4205 if (i == adata->nfat_arch)
4206 {
4207 /* Not found. */
4208 bfd_set_error (bfd_error_bad_value);
a95a4550 4209 return NULL;
3af9a47b 4210 }
a4e241ca
TG
4211
4212 /* Get next entry. */
4213 i++;
4214 }
a95a4550 4215
3af9a47b
NC
4216 if (i >= adata->nfat_arch)
4217 {
4218 bfd_set_error (bfd_error_no_more_archived_files);
4219 return NULL;
4220 }
4221
4222 entry = &adata->archentries[i];
15e1c58a
TG
4223 nbfd = _bfd_new_bfd_contained_in (archive);
4224 if (nbfd == NULL)
4225 return NULL;
4226
15e1c58a
TG
4227 bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype,
4228 &arch_type, &arch_subtype);
846b9259 4229
a4e241ca
TG
4230 bfd_mach_o_fat_member_init (nbfd, arch_type, arch_subtype, entry);
4231
846b9259 4232 bfd_set_arch_mach (nbfd, arch_type, arch_subtype);
3af9a47b 4233
15e1c58a 4234 return nbfd;
3af9a47b
NC
4235}
4236
15bbba8d
TG
4237/* Analogous to stat call. */
4238
4239static int
4240bfd_mach_o_fat_stat_arch_elt (bfd *abfd, struct stat *buf)
4241{
4242 if (abfd->arelt_data == NULL)
4243 {
4244 bfd_set_error (bfd_error_invalid_operation);
4245 return -1;
4246 }
4247
4248 buf->st_mtime = 0;
4249 buf->st_uid = 0;
4250 buf->st_gid = 0;
4251 buf->st_mode = 0644;
4252 buf->st_size = arelt_size (abfd);
4253
4254 return 0;
4255}
4256
846b9259
TG
4257/* If ABFD format is FORMAT and architecture is ARCH, return it.
4258 If ABFD is a fat image containing a member that corresponds to FORMAT
4259 and ARCH, returns it.
4260 In other case, returns NULL.
4261 This function allows transparent uses of fat images. */
a4e241ca 4262
846b9259
TG
4263bfd *
4264bfd_mach_o_fat_extract (bfd *abfd,
4265 bfd_format format,
4266 const bfd_arch_info_type *arch)
4267{
4268 bfd *res;
4269 mach_o_fat_data_struct *adata;
4270 unsigned int i;
4271
4272 if (bfd_check_format (abfd, format))
4273 {
4274 if (bfd_get_arch_info (abfd) == arch)
4275 return abfd;
4276 return NULL;
4277 }
4278 if (!bfd_check_format (abfd, bfd_archive)
4279 || abfd->xvec != &mach_o_fat_vec)
4280 return NULL;
c2f09c75 4281
846b9259
TG
4282 /* This is a Mach-O fat image. */
4283 adata = (mach_o_fat_data_struct *) abfd->tdata.mach_o_fat_data;
4284 BFD_ASSERT (adata != NULL);
4285
4286 for (i = 0; i < adata->nfat_arch; i++)
4287 {
4288 struct mach_o_fat_archentry *e = &adata->archentries[i];
4289 enum bfd_architecture cpu_type;
4290 unsigned long cpu_subtype;
4291
4292 bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype,
4293 &cpu_type, &cpu_subtype);
4294 if (cpu_type != arch->arch || cpu_subtype != arch->mach)
4295 continue;
4296
4297 /* The architecture is found. */
4298 res = _bfd_new_bfd_contained_in (abfd);
4299 if (res == NULL)
4300 return NULL;
4301
a4e241ca 4302 bfd_mach_o_fat_member_init (res, cpu_type, cpu_subtype, e);
846b9259
TG
4303
4304 if (bfd_check_format (res, format))
4305 {
4306 BFD_ASSERT (bfd_get_arch_info (res) == arch);
4307 return res;
4308 }
4309 bfd_close (res);
4310 return NULL;
4311 }
4312
4313 return NULL;
4314}
4315
3af9a47b 4316int
116c20d2
NC
4317bfd_mach_o_lookup_command (bfd *abfd,
4318 bfd_mach_o_load_command_type type,
4319 bfd_mach_o_load_command **mcommand)
3af9a47b 4320{
046b007d 4321 struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
3af9a47b
NC
4322 bfd_mach_o_load_command *ncmd = NULL;
4323 unsigned int i, num;
4324
3af9a47b
NC
4325 BFD_ASSERT (md != NULL);
4326 BFD_ASSERT (mcommand != NULL);
4327
4328 num = 0;
4329 for (i = 0; i < md->header.ncmds; i++)
4330 {
4331 struct bfd_mach_o_load_command *cmd = &md->commands[i];
4332
4333 if (cmd->type != type)
4334 continue;
4335
4336 if (num == 0)
4337 ncmd = cmd;
4338 num++;
4339 }
4340
4341 *mcommand = ncmd;
4342 return num;
4343}
4344
4345unsigned long
116c20d2 4346bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
3af9a47b
NC
4347{
4348 switch (type)
4349 {
4350 case BFD_MACH_O_CPU_TYPE_MC680x0:
4351 return 0x04000000;
4352 case BFD_MACH_O_CPU_TYPE_MC88000:
4353 return 0xffffe000;
4354 case BFD_MACH_O_CPU_TYPE_POWERPC:
4355 return 0xc0000000;
4356 case BFD_MACH_O_CPU_TYPE_I386:
4357 return 0xc0000000;
4358 case BFD_MACH_O_CPU_TYPE_SPARC:
4359 return 0xf0000000;
4360 case BFD_MACH_O_CPU_TYPE_I860:
4361 return 0;
4362 case BFD_MACH_O_CPU_TYPE_HPPA:
e84d6fca 4363 return 0xc0000000 - 0x04000000;
3af9a47b
NC
4364 default:
4365 return 0;
4366 }
4367}
4368
ab76eeaf
IS
4369/* The following two tables should be kept, as far as possible, in order of
4370 most frequently used entries to optimize their use from gas. */
4371
c5012cd8 4372const bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] =
046b007d
TG
4373{
4374 { "regular", BFD_MACH_O_S_REGULAR},
ab76eeaf 4375 { "coalesced", BFD_MACH_O_S_COALESCED},
046b007d
TG
4376 { "zerofill", BFD_MACH_O_S_ZEROFILL},
4377 { "cstring_literals", BFD_MACH_O_S_CSTRING_LITERALS},
4378 { "4byte_literals", BFD_MACH_O_S_4BYTE_LITERALS},
4379 { "8byte_literals", BFD_MACH_O_S_8BYTE_LITERALS},
ab76eeaf 4380 { "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS},
046b007d 4381 { "literal_pointers", BFD_MACH_O_S_LITERAL_POINTERS},
046b007d
TG
4382 { "mod_init_func_pointers", BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS},
4383 { "mod_fini_func_pointers", BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS},
046b007d
TG
4384 { "gb_zerofill", BFD_MACH_O_S_GB_ZEROFILL},
4385 { "interposing", BFD_MACH_O_S_INTERPOSING},
046b007d 4386 { "dtrace_dof", BFD_MACH_O_S_DTRACE_DOF},
ab76eeaf
IS
4387 { "non_lazy_symbol_pointers", BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS},
4388 { "lazy_symbol_pointers", BFD_MACH_O_S_LAZY_SYMBOL_POINTERS},
a4551119 4389 { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS},
046b007d
TG
4390 { "lazy_dylib_symbol_pointers", BFD_MACH_O_S_LAZY_DYLIB_SYMBOL_POINTERS},
4391 { NULL, 0}
4392};
4393
c5012cd8 4394const bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[] =
046b007d 4395{
ab76eeaf
IS
4396 { "pure_instructions", BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS },
4397 { "some_instructions", BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS },
046b007d
TG
4398 { "loc_reloc", BFD_MACH_O_S_ATTR_LOC_RELOC },
4399 { "ext_reloc", BFD_MACH_O_S_ATTR_EXT_RELOC },
046b007d 4400 { "debug", BFD_MACH_O_S_ATTR_DEBUG },
046b007d
TG
4401 { "live_support", BFD_MACH_O_S_ATTR_LIVE_SUPPORT },
4402 { "no_dead_strip", BFD_MACH_O_S_ATTR_NO_DEAD_STRIP },
4403 { "strip_static_syms", BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS },
4404 { "no_toc", BFD_MACH_O_S_ATTR_NO_TOC },
a4551119 4405 { "self_modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
ab76eeaf 4406 { "modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
046b007d
TG
4407 { NULL, 0}
4408};
4409
a4551119 4410/* Get the section type from NAME. Return 256 if NAME is unknown. */
53d58d96
TG
4411
4412unsigned int
ab76eeaf 4413bfd_mach_o_get_section_type_from_name (bfd *abfd, const char *name)
53d58d96 4414{
afbb9e17 4415 const bfd_mach_o_xlat_name *x;
ab76eeaf 4416 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
53d58d96
TG
4417
4418 for (x = bfd_mach_o_section_type_name; x->name; x++)
4419 if (strcmp (x->name, name) == 0)
ab76eeaf
IS
4420 {
4421 /* We found it... does the target support it? */
4422 if (bed->bfd_mach_o_section_type_valid_for_target == NULL
4423 || bed->bfd_mach_o_section_type_valid_for_target (x->val))
4424 return x->val; /* OK. */
4425 else
4426 break; /* Not supported. */
4427 }
a4551119
TG
4428 /* Maximum section ID = 0xff. */
4429 return 256;
53d58d96
TG
4430}
4431
4432/* Get the section attribute from NAME. Return -1 if NAME is unknown. */
4433
4434unsigned int
4435bfd_mach_o_get_section_attribute_from_name (const char *name)
4436{
afbb9e17 4437 const bfd_mach_o_xlat_name *x;
53d58d96
TG
4438
4439 for (x = bfd_mach_o_section_attribute_name; x->name; x++)
4440 if (strcmp (x->name, name) == 0)
4441 return x->val;
4442 return (unsigned int)-1;
4443}
4444
3af9a47b 4445int
116c20d2
NC
4446bfd_mach_o_core_fetch_environment (bfd *abfd,
4447 unsigned char **rbuf,
4448 unsigned int *rlen)
3af9a47b 4449{
046b007d 4450 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b
NC
4451 unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
4452 unsigned int i = 0;
4453
4454 for (i = 0; i < mdata->header.ncmds; i++)
4455 {
4456 bfd_mach_o_load_command *cur = &mdata->commands[i];
4457 bfd_mach_o_segment_command *seg = NULL;
4458
4459 if (cur->type != BFD_MACH_O_LC_SEGMENT)
4460 continue;
4461
4462 seg = &cur->command.segment;
4463
4464 if ((seg->vmaddr + seg->vmsize) == stackaddr)
4465 {
4466 unsigned long start = seg->fileoff;
4467 unsigned long end = seg->fileoff + seg->filesize;
4468 unsigned char *buf = bfd_malloc (1024);
4469 unsigned long size = 1024;
4470
4471 for (;;)
4472 {
4473 bfd_size_type nread = 0;
4474 unsigned long offset;
4475 int found_nonnull = 0;
4476
4477 if (size > (end - start))
4478 size = (end - start);
4479
515ef31d
NC
4480 buf = bfd_realloc_or_free (buf, size);
4481 if (buf == NULL)
4482 return -1;
c2f09c75
TG
4483
4484 if (bfd_seek (abfd, end - size, SEEK_SET) != 0)
4485 {
4486 free (buf);
4487 return -1;
4488 }
4489
3af9a47b 4490 nread = bfd_bread (buf, size, abfd);
a95a4550 4491
3af9a47b 4492 if (nread != size)
515ef31d
NC
4493 {
4494 free (buf);
4495 return -1;
4496 }
a95a4550 4497
3af9a47b
NC
4498 for (offset = 4; offset <= size; offset += 4)
4499 {
e84d6fca 4500 unsigned long val;
3af9a47b 4501
e84d6fca 4502 val = *((unsigned long *) (buf + size - offset));
3af9a47b
NC
4503 if (! found_nonnull)
4504 {
4505 if (val != 0)
4506 found_nonnull = 1;
4507 }
4508 else if (val == 0x0)
4509 {
e84d6fca
AM
4510 unsigned long bottom;
4511 unsigned long top;
3af9a47b 4512
e84d6fca
AM
4513 bottom = seg->fileoff + seg->filesize - offset;
4514 top = seg->fileoff + seg->filesize - 4;
3af9a47b
NC
4515 *rbuf = bfd_malloc (top - bottom);
4516 *rlen = top - bottom;
4517
4518 memcpy (*rbuf, buf + size - *rlen, *rlen);
515ef31d 4519 free (buf);
3af9a47b
NC
4520 return 0;
4521 }
4522 }
4523
4524 if (size == (end - start))
4525 break;
4526
4527 size *= 2;
4528 }
515ef31d
NC
4529
4530 free (buf);
3af9a47b
NC
4531 }
4532 }
4533
4534 return -1;
4535}
4536
4537char *
116c20d2 4538bfd_mach_o_core_file_failing_command (bfd *abfd)
3af9a47b
NC
4539{
4540 unsigned char *buf = NULL;
4541 unsigned int len = 0;
4542 int ret = -1;
4543
4544 ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
4545 if (ret < 0)
4546 return NULL;
4547
f075ee0c 4548 return (char *) buf;
3af9a47b
NC
4549}
4550
4551int
116c20d2 4552bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
3af9a47b
NC
4553{
4554 return 0;
4555}
4556
2ca7691a
TG
4557static bfd_mach_o_uuid_command *
4558bfd_mach_o_lookup_uuid_command (bfd *abfd)
4559{
4560 bfd_mach_o_load_command *uuid_cmd;
4561 int ncmd = bfd_mach_o_lookup_command (abfd, BFD_MACH_O_LC_UUID, &uuid_cmd);
4562 if (ncmd != 1)
4563 return FALSE;
4564 return &uuid_cmd->command.uuid;
4565}
4566
4567/* Return true if ABFD is a dSYM file and its UUID matches UUID_CMD. */
4568
4569static bfd_boolean
4570bfd_mach_o_dsym_for_uuid_p (bfd *abfd, const bfd_mach_o_uuid_command *uuid_cmd)
4571{
4572 bfd_mach_o_uuid_command *dsym_uuid_cmd;
4573
4574 BFD_ASSERT (abfd);
4575 BFD_ASSERT (uuid_cmd);
4576
4577 if (!bfd_check_format (abfd, bfd_object))
4578 return FALSE;
4579
4580 if (bfd_get_flavour (abfd) != bfd_target_mach_o_flavour
4581 || bfd_mach_o_get_data (abfd) == NULL
4582 || bfd_mach_o_get_data (abfd)->header.filetype != BFD_MACH_O_MH_DSYM)
4583 return FALSE;
4584
4585 dsym_uuid_cmd = bfd_mach_o_lookup_uuid_command (abfd);
4586 if (dsym_uuid_cmd == NULL)
4587 return FALSE;
4588
4589 if (memcmp (uuid_cmd->uuid, dsym_uuid_cmd->uuid,
4590 sizeof (uuid_cmd->uuid)) != 0)
4591 return FALSE;
4592
4593 return TRUE;
4594}
4595
4596/* Find a BFD in DSYM_FILENAME which matches ARCH and UUID_CMD.
4597 The caller is responsible for closing the returned BFD object and
4598 its my_archive if the returned BFD is in a fat dSYM. */
4599
4600static bfd *
4601bfd_mach_o_find_dsym (const char *dsym_filename,
4602 const bfd_mach_o_uuid_command *uuid_cmd,
4603 const bfd_arch_info_type *arch)
4604{
4605 bfd *base_dsym_bfd, *dsym_bfd;
4606
4607 BFD_ASSERT (uuid_cmd);
4608
4609 base_dsym_bfd = bfd_openr (dsym_filename, NULL);
4610 if (base_dsym_bfd == NULL)
4611 return NULL;
4612
4613 dsym_bfd = bfd_mach_o_fat_extract (base_dsym_bfd, bfd_object, arch);
4614 if (bfd_mach_o_dsym_for_uuid_p (dsym_bfd, uuid_cmd))
4615 return dsym_bfd;
4616
4617 bfd_close (dsym_bfd);
4618 if (base_dsym_bfd != dsym_bfd)
4619 bfd_close (base_dsym_bfd);
4620
4621 return NULL;
4622}
4623
4624/* Return a BFD created from a dSYM file for ABFD.
4625 The caller is responsible for closing the returned BFD object, its
4626 filename, and its my_archive if the returned BFD is in a fat dSYM. */
4627
4628static bfd *
4629bfd_mach_o_follow_dsym (bfd *abfd)
4630{
4631 char *dsym_filename;
4632 bfd_mach_o_uuid_command *uuid_cmd;
4633 bfd *dsym_bfd, *base_bfd = abfd;
4634 const char *base_basename;
4635
4636 if (abfd == NULL || bfd_get_flavour (abfd) != bfd_target_mach_o_flavour)
4637 return NULL;
4638
4639 if (abfd->my_archive)
4640 base_bfd = abfd->my_archive;
4641 /* BFD may have been opened from a stream. */
4642 if (base_bfd->filename == NULL)
4643 {
4644 bfd_set_error (bfd_error_invalid_operation);
4645 return NULL;
4646 }
4647 base_basename = lbasename (base_bfd->filename);
4648
4649 uuid_cmd = bfd_mach_o_lookup_uuid_command (abfd);
4650 if (uuid_cmd == NULL)
4651 return NULL;
4652
4653 /* TODO: We assume the DWARF file has the same as the binary's.
4654 It seems apple's GDB checks all files in the dSYM bundle directory.
4655 http://opensource.apple.com/source/gdb/gdb-1708/src/gdb/macosx/macosx-tdep.c
4656 */
4657 dsym_filename = (char *)bfd_malloc (strlen (base_bfd->filename)
4658 + strlen (dsym_subdir) + 1
4659 + strlen (base_basename) + 1);
4660 sprintf (dsym_filename, "%s%s/%s",
4661 base_bfd->filename, dsym_subdir, base_basename);
4662
4663 dsym_bfd = bfd_mach_o_find_dsym (dsym_filename, uuid_cmd,
4664 bfd_get_arch_info (abfd));
4665 if (dsym_bfd == NULL)
4666 free (dsym_filename);
4667
4668 return dsym_bfd;
4669}
4670
d9071b0c
TG
4671bfd_boolean
4672bfd_mach_o_find_nearest_line (bfd *abfd,
4673 asection *section,
4674 asymbol **symbols,
4675 bfd_vma offset,
4676 const char **filename_ptr,
4677 const char **functionname_ptr,
4678 unsigned int *line_ptr)
4679{
4680 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2ca7691a 4681 if (mdata == NULL)
d9071b0c 4682 return FALSE;
2ca7691a
TG
4683 switch (mdata->header.filetype)
4684 {
4685 case BFD_MACH_O_MH_OBJECT:
4686 break;
4687 case BFD_MACH_O_MH_EXECUTE:
4688 case BFD_MACH_O_MH_DYLIB:
4689 case BFD_MACH_O_MH_BUNDLE:
4690 case BFD_MACH_O_MH_KEXT_BUNDLE:
4691 if (mdata->dwarf2_find_line_info == NULL)
4692 {
4693 mdata->dsym_bfd = bfd_mach_o_follow_dsym (abfd);
4694 /* When we couldn't find dSYM for this binary, we look for
4695 the debug information in the binary itself. In this way,
4696 we won't try finding separated dSYM again because
4697 mdata->dwarf2_find_line_info will be filled. */
4698 if (! mdata->dsym_bfd)
4699 break;
4700 if (! _bfd_dwarf2_slurp_debug_info (abfd, mdata->dsym_bfd,
4701 dwarf_debug_sections, symbols,
4702 &mdata->dwarf2_find_line_info))
4703 return FALSE;
4704 }
4705 break;
4706 default:
4707 return FALSE;
4708 }
d9071b0c
TG
4709 if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections,
4710 section, symbols, offset,
4711 filename_ptr, functionname_ptr,
4712 line_ptr, 0,
4713 &mdata->dwarf2_find_line_info))
4714 return TRUE;
4715 return FALSE;
4716}
4717
4718bfd_boolean
4719bfd_mach_o_close_and_cleanup (bfd *abfd)
4720{
4721 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
4722 if (bfd_get_format (abfd) == bfd_object && mdata != NULL)
4434114c
TG
4723 {
4724 _bfd_dwarf2_cleanup_debug_info (abfd, &mdata->dwarf2_find_line_info);
4725 bfd_mach_o_free_cached_info (abfd);
2ca7691a
TG
4726 if (mdata->dsym_bfd != NULL)
4727 {
4728 bfd *fat_bfd = mdata->dsym_bfd->my_archive;
4729 char *dsym_filename = (char *)(fat_bfd
4730 ? fat_bfd->filename
4731 : mdata->dsym_bfd->filename);
4732 bfd_close (mdata->dsym_bfd);
4733 mdata->dsym_bfd = NULL;
4734 if (fat_bfd)
4735 bfd_close (fat_bfd);
4736 free (dsym_filename);
4737 }
4434114c 4738 }
dff55db0 4739
d9071b0c
TG
4740 return _bfd_generic_close_and_cleanup (abfd);
4741}
4742
dff55db0
TG
4743bfd_boolean bfd_mach_o_free_cached_info (bfd *abfd)
4744{
4745 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
4746 asection *asect;
4747 free (mdata->dyn_reloc_cache);
4748 mdata->dyn_reloc_cache = NULL;
4749 for (asect = abfd->sections; asect != NULL; asect = asect->next)
4750 {
4751 free (asect->relocation);
4752 asect->relocation = NULL;
4753 }
4754
4755 return TRUE;
4756}
4757
92bc0e80
TG
4758#define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
4759#define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
4760
4761#define bfd_mach_o_swap_reloc_in NULL
4762#define bfd_mach_o_swap_reloc_out NULL
b32e07d7 4763#define bfd_mach_o_print_thread NULL
a4551119 4764#define bfd_mach_o_tgt_seg_table NULL
ab76eeaf 4765#define bfd_mach_o_section_type_valid_for_tgt NULL
92bc0e80 4766
116c20d2
NC
4767#define TARGET_NAME mach_o_be_vec
4768#define TARGET_STRING "mach-o-be"
42fa0891 4769#define TARGET_ARCHITECTURE bfd_arch_unknown
116c20d2
NC
4770#define TARGET_BIG_ENDIAN 1
4771#define TARGET_ARCHIVE 0
b93a1992 4772#define TARGET_PRIORITY 1
3af9a47b
NC
4773#include "mach-o-target.c"
4774
4775#undef TARGET_NAME
4776#undef TARGET_STRING
42fa0891 4777#undef TARGET_ARCHITECTURE
3af9a47b
NC
4778#undef TARGET_BIG_ENDIAN
4779#undef TARGET_ARCHIVE
b93a1992 4780#undef TARGET_PRIORITY
3af9a47b 4781
116c20d2
NC
4782#define TARGET_NAME mach_o_le_vec
4783#define TARGET_STRING "mach-o-le"
42fa0891 4784#define TARGET_ARCHITECTURE bfd_arch_unknown
116c20d2
NC
4785#define TARGET_BIG_ENDIAN 0
4786#define TARGET_ARCHIVE 0
b93a1992 4787#define TARGET_PRIORITY 1
3af9a47b
NC
4788
4789#include "mach-o-target.c"
4790
4791#undef TARGET_NAME
4792#undef TARGET_STRING
42fa0891 4793#undef TARGET_ARCHITECTURE
3af9a47b
NC
4794#undef TARGET_BIG_ENDIAN
4795#undef TARGET_ARCHIVE
b93a1992 4796#undef TARGET_PRIORITY
3af9a47b 4797
8f95b6e4
TG
4798/* Not yet handled: creating an archive. */
4799#define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive
4800
4801/* Not used. */
4802#define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr
4803#define bfd_mach_o_write_ar_hdr _bfd_noarchive_write_ar_hdr
4804#define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap
4805#define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
4806#define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
4807#define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname
4808#define bfd_mach_o_write_armap _bfd_noarchive_write_armap
4809#define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index
15bbba8d 4810#define bfd_mach_o_generic_stat_arch_elt bfd_mach_o_fat_stat_arch_elt
8f95b6e4
TG
4811#define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
4812
116c20d2
NC
4813#define TARGET_NAME mach_o_fat_vec
4814#define TARGET_STRING "mach-o-fat"
42fa0891 4815#define TARGET_ARCHITECTURE bfd_arch_unknown
116c20d2
NC
4816#define TARGET_BIG_ENDIAN 1
4817#define TARGET_ARCHIVE 1
b93a1992 4818#define TARGET_PRIORITY 0
3af9a47b
NC
4819
4820#include "mach-o-target.c"
4821
4822#undef TARGET_NAME
4823#undef TARGET_STRING
42fa0891 4824#undef TARGET_ARCHITECTURE
3af9a47b
NC
4825#undef TARGET_BIG_ENDIAN
4826#undef TARGET_ARCHIVE
b93a1992 4827#undef TARGET_PRIORITY
This page took 0.784151 seconds and 4 git commands to generate.