bfd:
[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
09903f4b
IS
2029 /* Append sections to the segment.
2030
2031 This is a little tedious, we have to honor the need to account zerofill
2032 sections after all the rest. This forces us to do the calculation of
2033 total vmsize in three passes so that any alignment increments are
2034 properly accounted. */
7f307238
IS
2035
2036 for (i = 0; i < mdata->nsects; ++i)
2037 {
2038 bfd_mach_o_section *s = mdata->sections[i];
2039 asection *sec = s->bfdsection;
2040
2041 /* If we're not making an MH_OBJECT, check whether this section is from
2042 our segment, and skip if not. Otherwise, just add all sections. */
2043 if (! is_mho
2044 && strncmp (segment, s->segname, BFD_MACH_O_SEGNAME_SIZE) != 0)
2045 continue;
2046
09903f4b
IS
2047 /* Although we account for zerofill section sizes in vm order, they are
2048 placed in the file in source sequence. */
7f307238 2049 bfd_mach_o_append_section_to_segment (seg, sec);
e5081f2f 2050 s->offset = 0;
e5081f2f
IS
2051
2052 /* Zerofill sections have zero file size & offset,
2053 and are not written. */
2054 if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) == BFD_MACH_O_S_ZEROFILL
2055 || (s->flags & BFD_MACH_O_SECTION_TYPE_MASK)
2056 == BFD_MACH_O_S_GB_ZEROFILL)
2057 continue;
2058
2059 if (s->size > 0)
7f307238 2060 {
09903f4b
IS
2061 seg->vmsize = FILE_ALIGN (seg->vmsize, s->align);
2062 seg->vmsize += s->size;
2063
2064 seg->filesize = FILE_ALIGN (seg->filesize, s->align);
2065 seg->filesize += s->size;
2066
7f307238
IS
2067 mdata->filelen = FILE_ALIGN (mdata->filelen, s->align);
2068 s->offset = mdata->filelen;
2069 }
2070
2071 sec->filepos = s->offset;
7f307238
IS
2072 mdata->filelen += s->size;
2073 }
2074
09903f4b
IS
2075 /* Now pass through again, for zerofill, only now we just update the vmsize. */
2076 for (i = 0; i < mdata->nsects; ++i)
2077 {
2078 bfd_mach_o_section *s = mdata->sections[i];
2079
2080 if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) != BFD_MACH_O_S_ZEROFILL)
2081 continue;
2082
2083 if (! is_mho
2084 && strncmp (segment, s->segname, BFD_MACH_O_SEGNAME_SIZE) != 0)
2085 continue;
2086
2087 if (s->size > 0)
2088 {
2089 seg->vmsize = FILE_ALIGN (seg->vmsize, s->align);
2090 seg->vmsize += s->size;
2091 }
2092 }
2093
2094 /* Now pass through again, for zerofill_GB. */
2095 for (i = 0; i < mdata->nsects; ++i)
2096 {
2097 bfd_mach_o_section *s = mdata->sections[i];
2098
2099 if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) != BFD_MACH_O_S_GB_ZEROFILL)
2100 continue;
2101
2102 if (! is_mho
2103 && strncmp (segment, s->segname, BFD_MACH_O_SEGNAME_SIZE) != 0)
2104 continue;
2105
2106 if (s->size > 0)
2107 {
2108 seg->vmsize = FILE_ALIGN (seg->vmsize, s->align);
2109 seg->vmsize += s->size;
2110 }
2111 }
bb76d940 2112
09903f4b 2113 /* Allocate space for the relocations. */
bb76d940
IS
2114 mdata->filelen = FILE_ALIGN(mdata->filelen, 2);
2115
2116 for (i = 0; i < mdata->nsects; ++i)
2117 {
2118 bfd_mach_o_section *ms = mdata->sections[i];
2119 asection *sec = ms->bfdsection;
2120
2121 if ((ms->nreloc = sec->reloc_count) == 0)
2122 {
2123 ms->reloff = 0;
2124 continue;
2125 }
2126 sec->rel_filepos = mdata->filelen;
2127 ms->reloff = sec->rel_filepos;
2128 mdata->filelen += sec->reloc_count * BFD_MACH_O_RELENT_SIZE;
2129 }
7f307238
IS
2130
2131 return TRUE;
2132}
2133
50d10658
IS
2134/* Count the number of indirect symbols in the image.
2135 Requires that the sections are in their final order. */
2136
2137static unsigned int
2138bfd_mach_o_count_indirect_symbols (bfd *abfd, bfd_mach_o_data_struct *mdata)
2139{
2140 unsigned int i;
2141 unsigned int nisyms = 0;
2142
2143 for (i = 0; i < mdata->nsects; ++i)
2144 {
2145 bfd_mach_o_section *sec = mdata->sections[i];
2146
2147 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
2148 {
2149 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
2150 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
2151 case BFD_MACH_O_S_SYMBOL_STUBS:
2152 nisyms += bfd_mach_o_section_get_nbr_indirect (abfd, sec);
2153 break;
2154 default:
2155 break;
2156 }
2157 }
2158 return nisyms;
2159}
2160
7f307238
IS
2161static bfd_boolean
2162bfd_mach_o_build_dysymtab_command (bfd *abfd,
2163 bfd_mach_o_data_struct *mdata,
2164 bfd_mach_o_load_command *cmd)
2165{
2166 bfd_mach_o_dysymtab_command *dsym = &cmd->command.dysymtab;
2167
2168 /* TODO:
2169 We are not going to try and fill these in yet and, moreover, we are
2170 going to bail if they are already set. */
2171 if (dsym->nmodtab != 0
2172 || dsym->ntoc != 0
2173 || dsym->nextrefsyms != 0)
2174 {
2175 (*_bfd_error_handler) (_("sorry: modtab, toc and extrefsyms are not yet"
2176 " implemented for dysymtab commands."));
2177 return FALSE;
2178 }
2179
2180 dsym->ilocalsym = 0;
7f307238 2181
b22161d6 2182 if (bfd_get_symcount (abfd) > 0)
7f307238 2183 {
b22161d6
IS
2184 asymbol **symbols = bfd_get_outsymbols (abfd);
2185 unsigned long i;
2186
2187 /* Count the number of each kind of symbol. */
2188 for (i = 0; i < bfd_get_symcount (abfd); ++i)
2189 {
2190 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
2191 if (s->n_type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT))
2192 break;
2193 }
2194 dsym->nlocalsym = i;
2195 dsym->iextdefsym = i;
2196 for (; i < bfd_get_symcount (abfd); ++i)
2197 {
2198 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
2199 if ((s->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_UNDF)
2200 break;
2201 }
2202 dsym->nextdefsym = i - dsym->nlocalsym;
2203 dsym->iundefsym = dsym->nextdefsym + dsym->iextdefsym;
2204 dsym->nundefsym = bfd_get_symcount (abfd)
2205 - dsym->nlocalsym
2206 - dsym->nextdefsym;
2207 }
2208 else
2209 {
2210 dsym->nlocalsym = 0;
2211 dsym->iextdefsym = 0;
2212 dsym->nextdefsym = 0;
2213 dsym->iundefsym = 0;
2214 dsym->nundefsym = 0;
2215 }
2216
50d10658 2217 dsym->nindirectsyms = bfd_mach_o_count_indirect_symbols (abfd, mdata);
b22161d6
IS
2218 if (dsym->nindirectsyms > 0)
2219 {
2220 unsigned i;
50d10658 2221 unsigned n;
7f307238
IS
2222
2223 mdata->filelen = FILE_ALIGN (mdata->filelen, 2);
2224 dsym->indirectsymoff = mdata->filelen;
b22161d6 2225 mdata->filelen += dsym->nindirectsyms * 4;
7f307238 2226
b22161d6 2227 dsym->indirect_syms = bfd_zalloc (abfd, dsym->nindirectsyms * 4);
7f307238
IS
2228 if (dsym->indirect_syms == NULL)
2229 return FALSE;
50d10658
IS
2230
2231 n = 0;
2232 for (i = 0; i < mdata->nsects; ++i)
7f307238 2233 {
50d10658
IS
2234 bfd_mach_o_section *sec = mdata->sections[i];
2235
2236 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
2237 {
2238 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
2239 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
2240 case BFD_MACH_O_S_SYMBOL_STUBS:
2241 {
2242 unsigned j, num;
2243 bfd_mach_o_asymbol **isyms = sec->indirect_syms;
2244
2245 num = bfd_mach_o_section_get_nbr_indirect (abfd, sec);
2246 if (isyms == NULL || num == 0)
2247 break;
2248 /* Record the starting index in the reserved1 field. */
2249 sec->reserved1 = n;
2250 for (j = 0; j < num; j++, n++)
2251 {
2252 if (isyms[j] == NULL)
2253 dsym->indirect_syms[n] = BFD_MACH_O_INDIRECT_SYM_LOCAL;
687be931
IS
2254 else if (isyms[j]->symbol.section == bfd_abs_section_ptr
2255 && ! (isyms[j]->n_type & BFD_MACH_O_N_EXT))
2256 dsym->indirect_syms[n] = BFD_MACH_O_INDIRECT_SYM_LOCAL
2257 | BFD_MACH_O_INDIRECT_SYM_ABS;
50d10658
IS
2258 else
2259 dsym->indirect_syms[n] = isyms[j]->symbol.udata.i;
2260 }
2261 }
2262 break;
2263 default:
2264 break;
2265 }
7f307238
IS
2266 }
2267 }
2268
2269 return TRUE;
2270}
2271
2272/* Build Mach-O load commands (currently assuming an MH_OBJECT file).
2273 TODO: Other file formats, rebuilding symtab/dysymtab commands for strip
2274 and copy functionality. */
154a1ee5
TG
2275
2276bfd_boolean
2277bfd_mach_o_build_commands (bfd *abfd)
2278{
046b007d 2279 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
bbd56171
IS
2280 unsigned wide = mach_o_wide_p (&mdata->header);
2281 int segcmd_idx = -1;
2282 int symtab_idx = -1;
2283 int dysymtab_idx = -1;
2284 unsigned long base_offset = 0;
154a1ee5 2285
7f307238 2286 /* Return now if commands are already present. */
154a1ee5
TG
2287 if (mdata->header.ncmds)
2288 return FALSE;
2289
7f307238 2290 /* Fill in the file type, if not already set. */
154a1ee5 2291
7f307238 2292 if (mdata->header.filetype == 0)
154a1ee5 2293 {
7f307238
IS
2294 if (abfd->flags & EXEC_P)
2295 mdata->header.filetype = BFD_MACH_O_MH_EXECUTE;
2296 else if (abfd->flags & DYNAMIC)
2297 mdata->header.filetype = BFD_MACH_O_MH_DYLIB;
2298 else
2299 mdata->header.filetype = BFD_MACH_O_MH_OBJECT;
154a1ee5 2300 }
7f307238
IS
2301
2302 /* If hasn't already been done, flatten sections list, and sort
2303 if/when required. Must be done before the symbol table is adjusted,
2304 since that depends on properly numbered sections. */
2305 if (mdata->nsects == 0 || mdata->sections == NULL)
2306 if (! bfd_mach_o_mangle_sections (abfd, mdata))
2307 return FALSE;
2308
2309 /* Order the symbol table, fill-in/check mach-o specific fields and
2310 partition out any indirect symbols. */
b22161d6 2311 if (!bfd_mach_o_mangle_symbols (abfd))
7f307238
IS
2312 return FALSE;
2313
bbd56171
IS
2314 /* Very simple command set (only really applicable to MH_OBJECTs):
2315 All the commands are optional - present only when there is suitable data.
2316 (i.e. it is valid to have an empty file)
2317
2318 a command (segment) to contain all the sections,
2319 command for the symbol table,
2320 a command for the dysymtab.
2321
2322 ??? maybe we should assert that this is an MH_OBJECT? */
2323
7f307238 2324 if (mdata->nsects > 0)
154a1ee5 2325 {
bbd56171 2326 segcmd_idx = 0;
7f307238 2327 mdata->header.ncmds = 1;
154a1ee5 2328 }
154a1ee5 2329
7f307238 2330 if (bfd_get_symcount (abfd) > 0)
bbd56171
IS
2331 {
2332 mdata->header.ncmds++;
2333 symtab_idx = segcmd_idx + 1; /* 0 if the seg command is absent. */
2334 }
c2f09c75 2335
bbd56171
IS
2336 /* FIXME:
2337 This is a rather crude test for whether we should build a dysymtab. */
2338 if (bfd_mach_o_should_emit_dysymtab ()
2339 && bfd_get_symcount (abfd))
2340 {
2341 mdata->header.ncmds++;
2342 /* If there should be a case where a dysymtab could be emitted without
2343 a symtab (seems improbable), this would need amending. */
2344 dysymtab_idx = symtab_idx + 1;
2345 }
154a1ee5 2346
bbd56171
IS
2347 if (wide)
2348 base_offset = BFD_MACH_O_HEADER_64_SIZE;
2349 else
2350 base_offset = BFD_MACH_O_HEADER_SIZE;
c2f09c75 2351
bbd56171
IS
2352 /* Well, we must have a header, at least. */
2353 mdata->filelen = base_offset;
f1bde64c 2354
bbd56171 2355 /* A bit unusual, but no content is valid;
7f307238
IS
2356 as -n empty.s -o empty.o */
2357 if (mdata->header.ncmds == 0)
2358 return TRUE;
f1bde64c 2359
7f307238
IS
2360 mdata->commands = bfd_zalloc (abfd, mdata->header.ncmds
2361 * sizeof (bfd_mach_o_load_command));
2362 if (mdata->commands == NULL)
2363 return FALSE;
2364
bbd56171 2365 if (segcmd_idx >= 0)
7f307238 2366 {
bbd56171
IS
2367 bfd_mach_o_load_command *cmd = &mdata->commands[segcmd_idx];
2368 bfd_mach_o_segment_command *seg = &cmd->command.segment;
7f307238
IS
2369
2370 /* Count the segctions in the special blank segment used for MH_OBJECT. */
2371 seg->nsects = bfd_mach_o_count_sections_for_seg (NULL, mdata);
2372 if (seg->nsects == (unsigned long) -1)
2373 return FALSE;
2374
2375 /* Init segment command. */
bbd56171 2376 cmd->offset = base_offset;
7f307238
IS
2377 if (wide)
2378 {
2379 cmd->type = BFD_MACH_O_LC_SEGMENT_64;
7f307238
IS
2380 cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
2381 + BFD_MACH_O_SECTION_64_SIZE * seg->nsects;
2382 }
92bc0e80 2383 else
7f307238
IS
2384 {
2385 cmd->type = BFD_MACH_O_LC_SEGMENT;
7f307238
IS
2386 cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
2387 + BFD_MACH_O_SECTION_SIZE * seg->nsects;
2388 }
bbd56171 2389
7f307238
IS
2390 cmd->type_required = FALSE;
2391 mdata->header.sizeofcmds = cmd->len;
bbd56171 2392 mdata->filelen += cmd->len;
7f307238 2393 }
f1bde64c 2394
bbd56171 2395 if (symtab_idx >= 0)
7f307238
IS
2396 {
2397 /* Init symtab command. */
bbd56171 2398 bfd_mach_o_load_command *cmd = &mdata->commands[symtab_idx];
7f307238 2399
bbd56171
IS
2400 cmd->type = BFD_MACH_O_LC_SYMTAB;
2401 cmd->offset = base_offset;
2402 if (segcmd_idx >= 0)
2403 cmd->offset += mdata->commands[segcmd_idx].len;
2404
2405 cmd->len = sizeof (struct mach_o_symtab_command_external)
2406 + BFD_MACH_O_LC_SIZE;
2407 cmd->type_required = FALSE;
2408 mdata->header.sizeofcmds += cmd->len;
2409 mdata->filelen += cmd->len;
7f307238 2410 }
154a1ee5 2411
bbd56171
IS
2412 /* If required, setup symtab command, see comment above about the quality
2413 of this test. */
2414 if (dysymtab_idx >= 0)
7f307238 2415 {
bbd56171
IS
2416 bfd_mach_o_load_command *cmd = &mdata->commands[dysymtab_idx];
2417
7f307238 2418 cmd->type = BFD_MACH_O_LC_DYSYMTAB;
bbd56171
IS
2419 if (symtab_idx >= 0)
2420 cmd->offset = mdata->commands[symtab_idx].offset
2421 + mdata->commands[symtab_idx].len;
2422 else if (segcmd_idx >= 0)
2423 cmd->offset = mdata->commands[segcmd_idx].offset
2424 + mdata->commands[segcmd_idx].len;
2425 else
2426 cmd->offset = base_offset;
2427
7f307238 2428 cmd->type_required = FALSE;
bbd56171
IS
2429 cmd->len = sizeof (struct mach_o_dysymtab_command_external)
2430 + BFD_MACH_O_LC_SIZE;
7f307238
IS
2431
2432 mdata->header.sizeofcmds += cmd->len;
2433 mdata->filelen += cmd->len;
154a1ee5 2434 }
154a1ee5 2435
7f307238
IS
2436 /* So, now we have sized the commands and the filelen set to that.
2437 Now we can build the segment command and set the section file offsets. */
bbd56171
IS
2438 if (segcmd_idx >= 0
2439 && ! bfd_mach_o_build_seg_command
2440 (NULL, mdata, &mdata->commands[segcmd_idx].command.segment))
7f307238
IS
2441 return FALSE;
2442
2443 /* If we're doing a dysymtab, cmd points to its load command. */
bbd56171 2444 if (dysymtab_idx >= 0
7f307238 2445 && ! bfd_mach_o_build_dysymtab_command (abfd, mdata,
bbd56171 2446 &mdata->commands[dysymtab_idx]))
7f307238
IS
2447 return FALSE;
2448
2449 /* The symtab command is filled in when the symtab is written. */
154a1ee5
TG
2450 return TRUE;
2451}
2452
2453/* Set the contents of a section. */
2454
2455bfd_boolean
2456bfd_mach_o_set_section_contents (bfd *abfd,
2457 asection *section,
2458 const void * location,
2459 file_ptr offset,
2460 bfd_size_type count)
2461{
2462 file_ptr pos;
2463
7f307238
IS
2464 /* Trying to write the first section contents will trigger the creation of
2465 the load commands if they are not already present. */
154a1ee5
TG
2466 if (! abfd->output_has_begun && ! bfd_mach_o_build_commands (abfd))
2467 return FALSE;
2468
2469 if (count == 0)
2470 return TRUE;
2471
2472 pos = section->filepos + offset;
2473 if (bfd_seek (abfd, pos, SEEK_SET) != 0
2474 || bfd_bwrite (location, count, abfd) != count)
2475 return FALSE;
2476
2477 return TRUE;
2478}
2479
2480int
116c20d2 2481bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
a6b96beb 2482 struct bfd_link_info *info ATTRIBUTE_UNUSED)
3af9a47b
NC
2483{
2484 return 0;
2485}
2486
2487/* Make an empty symbol. This is required only because
2488 bfd_make_section_anyway wants to create a symbol for the section. */
2489
154a1ee5 2490asymbol *
116c20d2 2491bfd_mach_o_make_empty_symbol (bfd *abfd)
3af9a47b 2492{
d3ce72d0
NC
2493 asymbol *new_symbol;
2494
2495 new_symbol = bfd_zalloc (abfd, sizeof (bfd_mach_o_asymbol));
2496 if (new_symbol == NULL)
2497 return new_symbol;
2498 new_symbol->the_bfd = abfd;
b22161d6 2499 new_symbol->udata.i = SYM_MACHO_FIELDS_UNSET;
d3ce72d0 2500 return new_symbol;
3af9a47b
NC
2501}
2502
154a1ee5 2503static bfd_boolean
116c20d2 2504bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
3af9a47b 2505{
46d1c23b 2506 struct mach_o_header_external raw;
1e8a024a 2507 unsigned int size;
edeb6e24 2508 bfd_vma (*get32) (const void *) = NULL;
3af9a47b 2509
1e8a024a 2510 /* Just read the magic number. */
c2f09c75 2511 if (bfd_seek (abfd, 0, SEEK_SET) != 0
46d1c23b 2512 || bfd_bread (raw.magic, sizeof (raw.magic), abfd) != 4)
154a1ee5 2513 return FALSE;
3af9a47b 2514
46d1c23b 2515 if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
3af9a47b
NC
2516 {
2517 header->byteorder = BFD_ENDIAN_BIG;
154a1ee5 2518 header->magic = BFD_MACH_O_MH_MAGIC;
1e8a024a 2519 header->version = 1;
3af9a47b
NC
2520 get32 = bfd_getb32;
2521 }
46d1c23b 2522 else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
3af9a47b 2523 {
a95a4550 2524 header->byteorder = BFD_ENDIAN_LITTLE;
154a1ee5 2525 header->magic = BFD_MACH_O_MH_MAGIC;
1e8a024a
TG
2526 header->version = 1;
2527 get32 = bfd_getl32;
2528 }
46d1c23b 2529 else if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
1e8a024a
TG
2530 {
2531 header->byteorder = BFD_ENDIAN_BIG;
154a1ee5 2532 header->magic = BFD_MACH_O_MH_MAGIC_64;
1e8a024a
TG
2533 header->version = 2;
2534 get32 = bfd_getb32;
2535 }
46d1c23b 2536 else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
1e8a024a
TG
2537 {
2538 header->byteorder = BFD_ENDIAN_LITTLE;
154a1ee5 2539 header->magic = BFD_MACH_O_MH_MAGIC_64;
1e8a024a 2540 header->version = 2;
3af9a47b
NC
2541 get32 = bfd_getl32;
2542 }
2543 else
2544 {
2545 header->byteorder = BFD_ENDIAN_UNKNOWN;
154a1ee5 2546 return FALSE;
3af9a47b 2547 }
a95a4550 2548
1e8a024a 2549 /* Once the size of the header is known, read the full header. */
c2f09c75 2550 size = mach_o_wide_p (header) ?
154a1ee5 2551 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
1e8a024a 2552
c2f09c75 2553 if (bfd_seek (abfd, 0, SEEK_SET) != 0
46d1c23b 2554 || bfd_bread (&raw, size, abfd) != size)
154a1ee5 2555 return FALSE;
1e8a024a 2556
46d1c23b
TG
2557 header->cputype = (*get32) (raw.cputype);
2558 header->cpusubtype = (*get32) (raw.cpusubtype);
2559 header->filetype = (*get32) (raw.filetype);
2560 header->ncmds = (*get32) (raw.ncmds);
2561 header->sizeofcmds = (*get32) (raw.sizeofcmds);
2562 header->flags = (*get32) (raw.flags);
3af9a47b 2563
c2f09c75 2564 if (mach_o_wide_p (header))
46d1c23b 2565 header->reserved = (*get32) (raw.reserved);
facf03f2
TG
2566 else
2567 header->reserved = 0;
1e8a024a 2568
154a1ee5 2569 return TRUE;
3af9a47b
NC
2570}
2571
f1bde64c
TG
2572bfd_boolean
2573bfd_mach_o_new_section_hook (bfd *abfd, asection *sec)
2574{
2575 bfd_mach_o_section *s;
a4551119 2576 unsigned bfdalign = bfd_get_section_alignment (abfd, sec);
f1bde64c
TG
2577
2578 s = bfd_mach_o_get_mach_o_section (sec);
2579 if (s == NULL)
2580 {
2581 flagword bfd_flags;
a4551119 2582 static const mach_o_section_name_xlat * xlat;
f1bde64c
TG
2583
2584 s = (bfd_mach_o_section *) bfd_zalloc (abfd, sizeof (*s));
2585 if (s == NULL)
2586 return FALSE;
2587 sec->used_by_bfd = s;
2588 s->bfdsection = sec;
2589
a4551119
TG
2590 /* Create the Darwin seg/sect name pair from the bfd name.
2591 If this is a canonical name for which a specific paiting exists
2592 there will also be defined flags, type, attribute and alignment
2593 values. */
2594 xlat = bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, s);
2595 if (xlat != NULL)
2596 {
2597 s->flags = xlat->macho_sectype | xlat->macho_secattr;
2598 s->align = xlat->sectalign > bfdalign ? xlat->sectalign
2599 : bfdalign;
2600 bfd_set_section_alignment (abfd, sec, s->align);
2601 bfd_flags = bfd_get_section_flags (abfd, sec);
2602 if (bfd_flags == SEC_NO_FLAGS)
2603 bfd_set_section_flags (abfd, sec, xlat->bfd_flags);
2604 }
f1bde64c 2605 else
a4551119
TG
2606 /* Create default flags. */
2607 bfd_mach_o_set_section_flags_from_bfd (abfd, sec);
f1bde64c
TG
2608 }
2609
2610 return _bfd_generic_new_section_hook (abfd, sec);
2611}
2612
2613static void
2614bfd_mach_o_init_section_from_mach_o (bfd *abfd, asection *sec,
2615 unsigned long prot)
3af9a47b 2616{
117ed4f8 2617 flagword flags;
f1bde64c 2618 bfd_mach_o_section *section;
3af9a47b 2619
f1bde64c
TG
2620 flags = bfd_get_section_flags (abfd, sec);
2621 section = bfd_mach_o_get_mach_o_section (sec);
3af9a47b 2622
a4551119
TG
2623 /* TODO: see if we should use the xlat system for doing this by
2624 preference and fall back to this for unknown sections. */
2625
8462aec7 2626 if (flags == SEC_NO_FLAGS)
ef17cb22 2627 {
8462aec7
TG
2628 /* Try to guess flags. */
2629 if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
2630 flags = SEC_DEBUGGING;
2631 else
2632 {
2633 flags = SEC_ALLOC;
2634 if ((section->flags & BFD_MACH_O_SECTION_TYPE_MASK)
2635 != BFD_MACH_O_S_ZEROFILL)
2636 {
2637 flags |= SEC_LOAD;
2638 if (prot & BFD_MACH_O_PROT_EXECUTE)
2639 flags |= SEC_CODE;
2640 if (prot & BFD_MACH_O_PROT_WRITE)
2641 flags |= SEC_DATA;
2642 else if (prot & BFD_MACH_O_PROT_READ)
2643 flags |= SEC_READONLY;
2644 }
2645 }
ef17cb22 2646 }
15e1c58a
TG
2647 else
2648 {
8462aec7
TG
2649 if ((flags & SEC_DEBUGGING) == 0)
2650 flags |= SEC_ALLOC;
15e1c58a 2651 }
8462aec7
TG
2652
2653 if (section->offset != 0)
2654 flags |= SEC_HAS_CONTENTS;
92bc0e80
TG
2655 if (section->nreloc != 0)
2656 flags |= SEC_RELOC;
2657
f1bde64c
TG
2658 bfd_set_section_flags (abfd, sec, flags);
2659
2660 sec->vma = section->addr;
2661 sec->lma = section->addr;
2662 sec->size = section->size;
2663 sec->filepos = section->offset;
2664 sec->alignment_power = section->align;
2665 sec->segment_mark = 0;
2666 sec->reloc_count = section->nreloc;
2667 sec->rel_filepos = section->reloff;
2668}
2669
2670static asection *
2671bfd_mach_o_make_bfd_section (bfd *abfd,
2672 const unsigned char *segname,
2673 const unsigned char *sectname)
2674{
2675 const char *sname;
2676 flagword flags;
a95a4550 2677
f1bde64c
TG
2678 bfd_mach_o_convert_section_name_to_bfd
2679 (abfd, (const char *)segname, (const char *)sectname, &sname, &flags);
2680 if (sname == NULL)
2681 return NULL;
3af9a47b 2682
f1bde64c 2683 return bfd_make_section_anyway_with_flags (abfd, sname, flags);
3af9a47b
NC
2684}
2685
f1bde64c 2686static asection *
ab273af8 2687bfd_mach_o_read_section_32 (bfd *abfd,
ab273af8
TG
2688 unsigned int offset,
2689 unsigned long prot)
3af9a47b 2690{
46d1c23b 2691 struct mach_o_section_32_external raw;
f1bde64c
TG
2692 asection *sec;
2693 bfd_mach_o_section *section;
3af9a47b 2694
c2f09c75 2695 if (bfd_seek (abfd, offset, SEEK_SET) != 0
46d1c23b 2696 || (bfd_bread (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
c2f09c75 2697 != BFD_MACH_O_SECTION_SIZE))
f1bde64c 2698 return NULL;
a95a4550 2699
5a5cbf72 2700 sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
f1bde64c
TG
2701 if (sec == NULL)
2702 return NULL;
2703
2704 section = bfd_mach_o_get_mach_o_section (sec);
2705 memcpy (section->segname, raw.segname, sizeof (raw.segname));
2706 section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
2707 memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
69499dca 2708 section->sectname[BFD_MACH_O_SECTNAME_SIZE] = 0;
46d1c23b
TG
2709 section->addr = bfd_h_get_32 (abfd, raw.addr);
2710 section->size = bfd_h_get_32 (abfd, raw.size);
2711 section->offset = bfd_h_get_32 (abfd, raw.offset);
2712 section->align = bfd_h_get_32 (abfd, raw.align);
2713 section->reloff = bfd_h_get_32 (abfd, raw.reloff);
2714 section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
2715 section->flags = bfd_h_get_32 (abfd, raw.flags);
2716 section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
2717 section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
1e8a024a 2718 section->reserved3 = 0;
1e8a024a 2719
f1bde64c 2720 bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
1e8a024a 2721
f1bde64c 2722 return sec;
1e8a024a
TG
2723}
2724
f1bde64c 2725static asection *
ab273af8 2726bfd_mach_o_read_section_64 (bfd *abfd,
ab273af8
TG
2727 unsigned int offset,
2728 unsigned long prot)
1e8a024a 2729{
46d1c23b 2730 struct mach_o_section_64_external raw;
f1bde64c
TG
2731 asection *sec;
2732 bfd_mach_o_section *section;
1e8a024a 2733
c2f09c75 2734 if (bfd_seek (abfd, offset, SEEK_SET) != 0
46d1c23b 2735 || (bfd_bread (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
c2f09c75 2736 != BFD_MACH_O_SECTION_64_SIZE))
f1bde64c
TG
2737 return NULL;
2738
5a5cbf72 2739 sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
f1bde64c
TG
2740 if (sec == NULL)
2741 return NULL;
1e8a024a 2742
f1bde64c
TG
2743 section = bfd_mach_o_get_mach_o_section (sec);
2744 memcpy (section->segname, raw.segname, sizeof (raw.segname));
2745 section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
2746 memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
69499dca 2747 section->sectname[BFD_MACH_O_SECTNAME_SIZE] = 0;
46d1c23b
TG
2748 section->addr = bfd_h_get_64 (abfd, raw.addr);
2749 section->size = bfd_h_get_64 (abfd, raw.size);
2750 section->offset = bfd_h_get_32 (abfd, raw.offset);
2751 section->align = bfd_h_get_32 (abfd, raw.align);
2752 section->reloff = bfd_h_get_32 (abfd, raw.reloff);
2753 section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
2754 section->flags = bfd_h_get_32 (abfd, raw.flags);
2755 section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
2756 section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
2757 section->reserved3 = bfd_h_get_32 (abfd, raw.reserved3);
3af9a47b 2758
f1bde64c 2759 bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
3af9a47b 2760
f1bde64c 2761 return sec;
3af9a47b
NC
2762}
2763
f1bde64c 2764static asection *
ab273af8 2765bfd_mach_o_read_section (bfd *abfd,
ab273af8
TG
2766 unsigned int offset,
2767 unsigned long prot,
2768 unsigned int wide)
1e8a024a
TG
2769{
2770 if (wide)
f1bde64c 2771 return bfd_mach_o_read_section_64 (abfd, offset, prot);
1e8a024a 2772 else
f1bde64c 2773 return bfd_mach_o_read_section_32 (abfd, offset, prot);
1e8a024a
TG
2774}
2775
afbb9e17 2776static bfd_boolean
ab273af8
TG
2777bfd_mach_o_read_symtab_symbol (bfd *abfd,
2778 bfd_mach_o_symtab_command *sym,
2779 bfd_mach_o_asymbol *s,
2780 unsigned long i)
3af9a47b 2781{
046b007d 2782 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
c2f09c75 2783 unsigned int wide = mach_o_wide_p (&mdata->header);
046b007d
TG
2784 unsigned int symwidth =
2785 wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
92bc0e80 2786 unsigned int symoff = sym->symoff + (i * symwidth);
46d1c23b 2787 struct mach_o_nlist_64_external raw;
3af9a47b
NC
2788 unsigned char type = -1;
2789 unsigned char section = -1;
2790 short desc = -1;
1e8a024a 2791 symvalue value = -1;
3af9a47b
NC
2792 unsigned long stroff = -1;
2793 unsigned int symtype = -1;
2794
2795 BFD_ASSERT (sym->strtab != NULL);
2796
c2f09c75 2797 if (bfd_seek (abfd, symoff, SEEK_SET) != 0
46d1c23b 2798 || bfd_bread (&raw, symwidth, abfd) != symwidth)
3af9a47b 2799 {
46d1c23b
TG
2800 (*_bfd_error_handler)
2801 (_("bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"),
2802 symwidth, (unsigned long) symoff);
afbb9e17 2803 return FALSE;
3af9a47b
NC
2804 }
2805
46d1c23b
TG
2806 stroff = bfd_h_get_32 (abfd, raw.n_strx);
2807 type = bfd_h_get_8 (abfd, raw.n_type);
c2f09c75 2808 symtype = type & BFD_MACH_O_N_TYPE;
46d1c23b
TG
2809 section = bfd_h_get_8 (abfd, raw.n_sect);
2810 desc = bfd_h_get_16 (abfd, raw.n_desc);
1e8a024a 2811 if (wide)
46d1c23b 2812 value = bfd_h_get_64 (abfd, raw.n_value);
1e8a024a 2813 else
46d1c23b 2814 value = bfd_h_get_32 (abfd, raw.n_value);
3af9a47b
NC
2815
2816 if (stroff >= sym->strsize)
2817 {
46d1c23b
TG
2818 (*_bfd_error_handler)
2819 (_("bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"),
2820 (unsigned long) stroff,
2821 (unsigned long) sym->strsize);
afbb9e17 2822 return FALSE;
3af9a47b
NC
2823 }
2824
92bc0e80
TG
2825 s->symbol.the_bfd = abfd;
2826 s->symbol.name = sym->strtab + stroff;
2827 s->symbol.value = value;
2828 s->symbol.flags = 0x0;
b22161d6 2829 s->symbol.udata.i = i;
92bc0e80
TG
2830 s->n_type = type;
2831 s->n_sect = section;
2832 s->n_desc = desc;
3af9a47b
NC
2833
2834 if (type & BFD_MACH_O_N_STAB)
2835 {
92bc0e80
TG
2836 s->symbol.flags |= BSF_DEBUGGING;
2837 s->symbol.section = bfd_und_section_ptr;
15e1c58a
TG
2838 switch (type)
2839 {
2840 case N_FUN:
2841 case N_STSYM:
2842 case N_LCSYM:
2843 case N_BNSYM:
2844 case N_SLINE:
2845 case N_ENSYM:
2846 case N_ECOMM:
2847 case N_ECOML:
2848 case N_GSYM:
2849 if ((section > 0) && (section <= mdata->nsects))
2850 {
92bc0e80
TG
2851 s->symbol.section = mdata->sections[section - 1]->bfdsection;
2852 s->symbol.value =
2853 s->symbol.value - mdata->sections[section - 1]->addr;
15e1c58a
TG
2854 }
2855 break;
2856 }
3af9a47b
NC
2857 }
2858 else
2859 {
b22161d6 2860 if (type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT))
92bc0e80 2861 s->symbol.flags |= BSF_GLOBAL;
b22161d6 2862 else
92bc0e80 2863 s->symbol.flags |= BSF_LOCAL;
3af9a47b
NC
2864
2865 switch (symtype)
2866 {
2867 case BFD_MACH_O_N_UNDF:
c2f09c75 2868 if (type == (BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT)
92bc0e80 2869 && s->symbol.value != 0)
c2f09c75
TG
2870 {
2871 /* A common symbol. */
92bc0e80
TG
2872 s->symbol.section = bfd_com_section_ptr;
2873 s->symbol.flags = BSF_NO_FLAGS;
c2f09c75
TG
2874 }
2875 else
92bc0e80
TG
2876 {
2877 s->symbol.section = bfd_und_section_ptr;
2878 if (s->n_desc & BFD_MACH_O_N_WEAK_REF)
2879 s->symbol.flags |= BSF_WEAK;
2880 }
3af9a47b
NC
2881 break;
2882 case BFD_MACH_O_N_PBUD:
92bc0e80 2883 s->symbol.section = bfd_und_section_ptr;
3af9a47b
NC
2884 break;
2885 case BFD_MACH_O_N_ABS:
92bc0e80 2886 s->symbol.section = bfd_abs_section_ptr;
3af9a47b
NC
2887 break;
2888 case BFD_MACH_O_N_SECT:
2889 if ((section > 0) && (section <= mdata->nsects))
2890 {
92bc0e80
TG
2891 s->symbol.section = mdata->sections[section - 1]->bfdsection;
2892 s->symbol.value =
2893 s->symbol.value - mdata->sections[section - 1]->addr;
3af9a47b
NC
2894 }
2895 else
2896 {
2897 /* Mach-O uses 0 to mean "no section"; not an error. */
2898 if (section != 0)
2899 {
4a97a0e5
AM
2900 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
2901 "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"),
2902 s->symbol.name, section, mdata->nsects);
3af9a47b 2903 }
92bc0e80 2904 s->symbol.section = bfd_und_section_ptr;
3af9a47b
NC
2905 }
2906 break;
2907 case BFD_MACH_O_N_INDR:
0596a831
TG
2908 /* FIXME: we don't follow the BFD convention as this indirect symbol
2909 won't be followed by the referenced one. This looks harmless
2910 unless we start using the linker. */
2911 s->symbol.flags |= BSF_INDIRECT;
2912 s->symbol.section = bfd_ind_section_ptr;
2913 s->symbol.value = 0;
3af9a47b
NC
2914 break;
2915 default:
4a97a0e5
AM
2916 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
2917 "symbol \"%s\" specified invalid type field 0x%x: setting to undefined"),
2918 s->symbol.name, symtype);
92bc0e80 2919 s->symbol.section = bfd_und_section_ptr;
3af9a47b
NC
2920 break;
2921 }
2922 }
2923
afbb9e17 2924 return TRUE;
3af9a47b
NC
2925}
2926
c5012cd8 2927bfd_boolean
ab273af8 2928bfd_mach_o_read_symtab_strtab (bfd *abfd)
3af9a47b 2929{
046b007d
TG
2930 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2931 bfd_mach_o_symtab_command *sym = mdata->symtab;
2932
2933 /* Fail if there is no symtab. */
2934 if (sym == NULL)
afbb9e17 2935 return FALSE;
046b007d
TG
2936
2937 /* Success if already loaded. */
2938 if (sym->strtab)
afbb9e17 2939 return TRUE;
3af9a47b
NC
2940
2941 if (abfd->flags & BFD_IN_MEMORY)
2942 {
2943 struct bfd_in_memory *b;
2944
2945 b = (struct bfd_in_memory *) abfd->iostream;
2946
2947 if ((sym->stroff + sym->strsize) > b->size)
2948 {
2949 bfd_set_error (bfd_error_file_truncated);
afbb9e17 2950 return FALSE;
3af9a47b 2951 }
f075ee0c 2952 sym->strtab = (char *) b->buffer + sym->stroff;
3af9a47b 2953 }
046b007d 2954 else
3af9a47b 2955 {
046b007d
TG
2956 sym->strtab = bfd_alloc (abfd, sym->strsize);
2957 if (sym->strtab == NULL)
afbb9e17 2958 return FALSE;
046b007d
TG
2959
2960 if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0
afbb9e17 2961 || bfd_bread (sym->strtab, sym->strsize, abfd) != sym->strsize)
046b007d
TG
2962 {
2963 bfd_set_error (bfd_error_file_truncated);
afbb9e17 2964 return FALSE;
046b007d 2965 }
3af9a47b
NC
2966 }
2967
afbb9e17 2968 return TRUE;
3af9a47b
NC
2969}
2970
c5012cd8 2971bfd_boolean
ab273af8 2972bfd_mach_o_read_symtab_symbols (bfd *abfd)
3af9a47b 2973{
046b007d
TG
2974 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2975 bfd_mach_o_symtab_command *sym = mdata->symtab;
3af9a47b 2976 unsigned long i;
3af9a47b 2977
092d27ff
TG
2978 if (sym == NULL || sym->symbols)
2979 {
2980 /* Return now if there are no symbols or if already loaded. */
afbb9e17 2981 return TRUE;
092d27ff 2982 }
046b007d 2983
92bc0e80 2984 sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
3af9a47b
NC
2985
2986 if (sym->symbols == NULL)
2987 {
4a97a0e5 2988 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"));
afbb9e17 2989 return FALSE;
3af9a47b 2990 }
a95a4550 2991
afbb9e17
TG
2992 if (!bfd_mach_o_read_symtab_strtab (abfd))
2993 return FALSE;
3af9a47b
NC
2994
2995 for (i = 0; i < sym->nsyms; i++)
2996 {
afbb9e17
TG
2997 if (!bfd_mach_o_read_symtab_symbol (abfd, sym, &sym->symbols[i], i))
2998 return FALSE;
3af9a47b 2999 }
a95a4550 3000
afbb9e17 3001 return TRUE;
3af9a47b
NC
3002}
3003
3004static const char *
116c20d2 3005bfd_mach_o_i386_flavour_string (unsigned int flavour)
3af9a47b
NC
3006{
3007 switch ((int) flavour)
3008 {
15e1c58a
TG
3009 case BFD_MACH_O_x86_THREAD_STATE32: return "x86_THREAD_STATE32";
3010 case BFD_MACH_O_x86_FLOAT_STATE32: return "x86_FLOAT_STATE32";
3011 case BFD_MACH_O_x86_EXCEPTION_STATE32: return "x86_EXCEPTION_STATE32";
3012 case BFD_MACH_O_x86_THREAD_STATE64: return "x86_THREAD_STATE64";
3013 case BFD_MACH_O_x86_FLOAT_STATE64: return "x86_FLOAT_STATE64";
3014 case BFD_MACH_O_x86_EXCEPTION_STATE64: return "x86_EXCEPTION_STATE64";
3015 case BFD_MACH_O_x86_THREAD_STATE: return "x86_THREAD_STATE";
3016 case BFD_MACH_O_x86_FLOAT_STATE: return "x86_FLOAT_STATE";
3017 case BFD_MACH_O_x86_EXCEPTION_STATE: return "x86_EXCEPTION_STATE";
3018 case BFD_MACH_O_x86_DEBUG_STATE32: return "x86_DEBUG_STATE32";
3019 case BFD_MACH_O_x86_DEBUG_STATE64: return "x86_DEBUG_STATE64";
3020 case BFD_MACH_O_x86_DEBUG_STATE: return "x86_DEBUG_STATE";
b32e07d7 3021 case BFD_MACH_O_x86_THREAD_STATE_NONE: return "x86_THREAD_STATE_NONE";
3af9a47b
NC
3022 default: return "UNKNOWN";
3023 }
3024}
3025
3026static const char *
116c20d2 3027bfd_mach_o_ppc_flavour_string (unsigned int flavour)
3af9a47b
NC
3028{
3029 switch ((int) flavour)
3030 {
b32e07d7
TG
3031 case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
3032 case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
3033 case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
3034 case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
3035 case BFD_MACH_O_PPC_THREAD_STATE64: return "PPC_THREAD_STATE64";
3036 case BFD_MACH_O_PPC_EXCEPTION_STATE64: return "PPC_EXCEPTION_STATE64";
3af9a47b
NC
3037 default: return "UNKNOWN";
3038 }
3039}
3040
3041static int
ab273af8 3042bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b
NC
3043{
3044 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
46d1c23b 3045 struct mach_o_str_command_external raw;
3af9a47b 3046 unsigned int nameoff;
3af9a47b
NC
3047
3048 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
3049 || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
3050
46d1c23b
TG
3051 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3052 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
3053 return -1;
3054
46d1c23b 3055 nameoff = bfd_h_get_32 (abfd, raw.str);
3af9a47b
NC
3056
3057 cmd->name_offset = command->offset + nameoff;
3058 cmd->name_len = command->len - nameoff;
b32e07d7
TG
3059 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
3060 if (cmd->name_str == NULL)
3af9a47b 3061 return -1;
b32e07d7
TG
3062 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
3063 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
3af9a47b 3064 return -1;
3af9a47b
NC
3065 return 0;
3066}
3067
3068static int
ab273af8 3069bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b
NC
3070{
3071 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
46d1c23b 3072 struct mach_o_dylib_command_external raw;
3af9a47b 3073 unsigned int nameoff;
3af9a47b 3074
046b007d
TG
3075 switch (command->type)
3076 {
3077 case BFD_MACH_O_LC_LOAD_DYLIB:
046b007d 3078 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
046b007d 3079 case BFD_MACH_O_LC_ID_DYLIB:
046b007d 3080 case BFD_MACH_O_LC_REEXPORT_DYLIB:
73017762 3081 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
046b007d
TG
3082 break;
3083 default:
b32e07d7
TG
3084 BFD_FAIL ();
3085 return -1;
046b007d 3086 }
3af9a47b 3087
46d1c23b
TG
3088 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3089 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
3090 return -1;
3091
46d1c23b
TG
3092 nameoff = bfd_h_get_32 (abfd, raw.name);
3093 cmd->timestamp = bfd_h_get_32 (abfd, raw.timestamp);
3094 cmd->current_version = bfd_h_get_32 (abfd, raw.current_version);
3095 cmd->compatibility_version = bfd_h_get_32 (abfd, raw.compatibility_version);
3af9a47b
NC
3096
3097 cmd->name_offset = command->offset + nameoff;
3098 cmd->name_len = command->len - nameoff;
b32e07d7
TG
3099 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
3100 if (cmd->name_str == NULL)
3af9a47b 3101 return -1;
b32e07d7
TG
3102 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
3103 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
3af9a47b 3104 return -1;
3af9a47b
NC
3105 return 0;
3106}
3107
3108static int
ab273af8
TG
3109bfd_mach_o_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
3110 bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
3af9a47b
NC
3111{
3112 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
3113
3114 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
3115 return 0;
3116}
3117
9f4a5bd1
TG
3118static int
3119bfd_mach_o_read_fvmlib (bfd *abfd, bfd_mach_o_load_command *command)
3120{
3121 bfd_mach_o_fvmlib_command *fvm = &command->command.fvmlib;
3122 struct mach_o_fvmlib_command_external raw;
3123 unsigned int nameoff;
3124
3125 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3126 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3127 return -1;
3128
3129 nameoff = bfd_h_get_32 (abfd, raw.name);
3130 fvm->minor_version = bfd_h_get_32 (abfd, raw.minor_version);
3131 fvm->header_addr = bfd_h_get_32 (abfd, raw.header_addr);
3132
3133 fvm->name_offset = command->offset + nameoff;
3134 fvm->name_len = command->len - nameoff;
3135 fvm->name_str = bfd_alloc (abfd, fvm->name_len);
3136 if (fvm->name_str == NULL)
3137 return -1;
3138 if (bfd_seek (abfd, fvm->name_offset, SEEK_SET) != 0
3139 || bfd_bread (fvm->name_str, fvm->name_len, abfd) != fvm->name_len)
3140 return -1;
3141 return 0;
3142}
3143
3af9a47b 3144static int
ab273af8 3145bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 3146{
b32e07d7 3147 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 3148 bfd_mach_o_thread_command *cmd = &command->command.thread;
92bc0e80 3149 unsigned int offset;
3af9a47b
NC
3150 unsigned int nflavours;
3151 unsigned int i;
3152
3153 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
3154 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
3155
b32e07d7 3156 /* Count the number of threads. */
3af9a47b
NC
3157 offset = 8;
3158 nflavours = 0;
3159 while (offset != command->len)
3160 {
46d1c23b
TG
3161 struct mach_o_thread_command_external raw;
3162
3af9a47b
NC
3163 if (offset >= command->len)
3164 return -1;
3165
c2f09c75 3166 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
46d1c23b 3167 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
3168 return -1;
3169
46d1c23b 3170 offset += sizeof (raw) + bfd_h_get_32 (abfd, raw.count) * 4;
3af9a47b
NC
3171 nflavours++;
3172 }
3173
b32e07d7
TG
3174 /* Allocate threads. */
3175 cmd->flavours = bfd_alloc
3176 (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
3af9a47b
NC
3177 if (cmd->flavours == NULL)
3178 return -1;
3179 cmd->nflavours = nflavours;
3180
3181 offset = 8;
3182 nflavours = 0;
3183 while (offset != command->len)
3184 {
46d1c23b
TG
3185 struct mach_o_thread_command_external raw;
3186
3af9a47b
NC
3187 if (offset >= command->len)
3188 return -1;
3189
3190 if (nflavours >= cmd->nflavours)
3191 return -1;
3192
c2f09c75 3193 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
46d1c23b 3194 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
3195 return -1;
3196
46d1c23b
TG
3197 cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, raw.flavour);
3198 cmd->flavours[nflavours].offset = command->offset + offset + sizeof (raw);
3199 cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, raw.count) * 4;
3200 offset += cmd->flavours[nflavours].size + sizeof (raw);
3af9a47b
NC
3201 nflavours++;
3202 }
3203
3204 for (i = 0; i < nflavours; i++)
3205 {
3206 asection *bfdsec;
3207 unsigned int snamelen;
3208 char *sname;
3209 const char *flavourstr;
3210 const char *prefix = "LC_THREAD";
a95a4550
AM
3211 unsigned int j = 0;
3212
3af9a47b
NC
3213 switch (mdata->header.cputype)
3214 {
3215 case BFD_MACH_O_CPU_TYPE_POWERPC:
1e8a024a 3216 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
3af9a47b
NC
3217 flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
3218 break;
3219 case BFD_MACH_O_CPU_TYPE_I386:
1e8a024a 3220 case BFD_MACH_O_CPU_TYPE_X86_64:
3af9a47b
NC
3221 flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
3222 break;
3223 default:
3224 flavourstr = "UNKNOWN_ARCHITECTURE";
3225 break;
3226 }
a95a4550 3227
3af9a47b 3228 snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
116c20d2 3229 sname = bfd_alloc (abfd, snamelen);
3af9a47b
NC
3230 if (sname == NULL)
3231 return -1;
3232
3233 for (;;)
3234 {
a95a4550
AM
3235 sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
3236 if (bfd_get_section_by_name (abfd, sname) == NULL)
3af9a47b 3237 break;
a95a4550 3238 j++;
3af9a47b
NC
3239 }
3240
117ed4f8 3241 bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
a95a4550 3242
3af9a47b
NC
3243 bfdsec->vma = 0;
3244 bfdsec->lma = 0;
eea6121a 3245 bfdsec->size = cmd->flavours[i].size;
3af9a47b
NC
3246 bfdsec->filepos = cmd->flavours[i].offset;
3247 bfdsec->alignment_power = 0x0;
3af9a47b
NC
3248
3249 cmd->section = bfdsec;
3250 }
3251
3252 return 0;
3253}
3254
a95a4550 3255static int
ab273af8 3256bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 3257{
046b007d 3258 bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
b32e07d7 3259 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b
NC
3260
3261 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
3262
46d1c23b
TG
3263 {
3264 struct mach_o_dysymtab_command_external raw;
3265
3266 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3267 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3268 return -1;
3af9a47b 3269
46d1c23b
TG
3270 cmd->ilocalsym = bfd_h_get_32 (abfd, raw.ilocalsym);
3271 cmd->nlocalsym = bfd_h_get_32 (abfd, raw.nlocalsym);
3272 cmd->iextdefsym = bfd_h_get_32 (abfd, raw.iextdefsym);
3273 cmd->nextdefsym = bfd_h_get_32 (abfd, raw.nextdefsym);
3274 cmd->iundefsym = bfd_h_get_32 (abfd, raw.iundefsym);
3275 cmd->nundefsym = bfd_h_get_32 (abfd, raw.nundefsym);
3276 cmd->tocoff = bfd_h_get_32 (abfd, raw.tocoff);
3277 cmd->ntoc = bfd_h_get_32 (abfd, raw.ntoc);
3278 cmd->modtaboff = bfd_h_get_32 (abfd, raw.modtaboff);
3279 cmd->nmodtab = bfd_h_get_32 (abfd, raw.nmodtab);
3280 cmd->extrefsymoff = bfd_h_get_32 (abfd, raw.extrefsymoff);
3281 cmd->nextrefsyms = bfd_h_get_32 (abfd, raw.nextrefsyms);
3282 cmd->indirectsymoff = bfd_h_get_32 (abfd, raw.indirectsymoff);
3283 cmd->nindirectsyms = bfd_h_get_32 (abfd, raw.nindirectsyms);
3284 cmd->extreloff = bfd_h_get_32 (abfd, raw.extreloff);
3285 cmd->nextrel = bfd_h_get_32 (abfd, raw.nextrel);
3286 cmd->locreloff = bfd_h_get_32 (abfd, raw.locreloff);
3287 cmd->nlocrel = bfd_h_get_32 (abfd, raw.nlocrel);
3288 }
046b007d
TG
3289
3290 if (cmd->nmodtab != 0)
3291 {
046b007d
TG
3292 unsigned int i;
3293 int wide = bfd_mach_o_wide_p (abfd);
3294 unsigned int module_len = wide ? 56 : 52;
3295
3296 cmd->dylib_module =
3297 bfd_alloc (abfd, cmd->nmodtab * sizeof (bfd_mach_o_dylib_module));
3298 if (cmd->dylib_module == NULL)
3299 return -1;
3300
3301 if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0)
3302 return -1;
3303
3304 for (i = 0; i < cmd->nmodtab; i++)
3305 {
3306 bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
3307 unsigned long v;
46d1c23b 3308 unsigned char buf[56];
046b007d 3309
91d6fa6a 3310 if (bfd_bread ((void *) buf, module_len, abfd) != module_len)
046b007d
TG
3311 return -1;
3312
3313 module->module_name_idx = bfd_h_get_32 (abfd, buf + 0);
3314 module->iextdefsym = bfd_h_get_32 (abfd, buf + 4);
3315 module->nextdefsym = bfd_h_get_32 (abfd, buf + 8);
3316 module->irefsym = bfd_h_get_32 (abfd, buf + 12);
3317 module->nrefsym = bfd_h_get_32 (abfd, buf + 16);
3318 module->ilocalsym = bfd_h_get_32 (abfd, buf + 20);
3319 module->nlocalsym = bfd_h_get_32 (abfd, buf + 24);
3320 module->iextrel = bfd_h_get_32 (abfd, buf + 28);
3321 module->nextrel = bfd_h_get_32 (abfd, buf + 32);
3322 v = bfd_h_get_32 (abfd, buf +36);
3323 module->iinit = v & 0xffff;
3324 module->iterm = (v >> 16) & 0xffff;
3325 v = bfd_h_get_32 (abfd, buf + 40);
3326 module->ninit = v & 0xffff;
3327 module->nterm = (v >> 16) & 0xffff;
3328 if (wide)
3329 {
3330 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 44);
3331 module->objc_module_info_addr = bfd_h_get_64 (abfd, buf + 48);
3332 }
3333 else
3334 {
3335 module->objc_module_info_addr = bfd_h_get_32 (abfd, buf + 44);
3336 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 48);
3337 }
3338 }
3339 }
afbb9e17 3340
046b007d
TG
3341 if (cmd->ntoc != 0)
3342 {
046b007d
TG
3343 unsigned int i;
3344
3345 cmd->dylib_toc = bfd_alloc
3346 (abfd, cmd->ntoc * sizeof (bfd_mach_o_dylib_table_of_content));
3347 if (cmd->dylib_toc == NULL)
3348 return -1;
3349
3350 if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
3351 return -1;
3352
3353 for (i = 0; i < cmd->ntoc; i++)
3354 {
46d1c23b 3355 struct mach_o_dylib_table_of_contents_external raw;
046b007d
TG
3356 bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
3357
46d1c23b 3358 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
3359 return -1;
3360
46d1c23b
TG
3361 toc->symbol_index = bfd_h_get_32 (abfd, raw.symbol_index);
3362 toc->module_index = bfd_h_get_32 (abfd, raw.module_index);
046b007d
TG
3363 }
3364 }
3365
3366 if (cmd->nindirectsyms != 0)
3367 {
046b007d
TG
3368 unsigned int i;
3369
3370 cmd->indirect_syms = bfd_alloc
3371 (abfd, cmd->nindirectsyms * sizeof (unsigned int));
3372 if (cmd->indirect_syms == NULL)
3373 return -1;
3374
3375 if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
3376 return -1;
3377
3378 for (i = 0; i < cmd->nindirectsyms; i++)
3379 {
46d1c23b 3380 unsigned char raw[4];
046b007d
TG
3381 unsigned int *is = &cmd->indirect_syms[i];
3382
46d1c23b 3383 if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
3384 return -1;
3385
46d1c23b 3386 *is = bfd_h_get_32 (abfd, raw);
046b007d
TG
3387 }
3388 }
3389
3390 if (cmd->nextrefsyms != 0)
3391 {
046b007d
TG
3392 unsigned long v;
3393 unsigned int i;
3394
3395 cmd->ext_refs = bfd_alloc
3396 (abfd, cmd->nextrefsyms * sizeof (bfd_mach_o_dylib_reference));
3397 if (cmd->ext_refs == NULL)
3398 return -1;
3399
3400 if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
3401 return -1;
3402
3403 for (i = 0; i < cmd->nextrefsyms; i++)
3404 {
46d1c23b 3405 unsigned char raw[4];
046b007d
TG
3406 bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
3407
46d1c23b 3408 if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
3409 return -1;
3410
b32e07d7
TG
3411 /* Fields isym and flags are written as bit-fields, thus we need
3412 a specific processing for endianness. */
46d1c23b 3413 v = bfd_h_get_32 (abfd, raw);
b32e07d7
TG
3414 if (bfd_big_endian (abfd))
3415 {
3416 ref->isym = (v >> 8) & 0xffffff;
3417 ref->flags = v & 0xff;
3418 }
3419 else
3420 {
3421 ref->isym = v & 0xffffff;
3422 ref->flags = (v >> 24) & 0xff;
3423 }
046b007d
TG
3424 }
3425 }
3af9a47b 3426
b32e07d7
TG
3427 if (mdata->dysymtab)
3428 return -1;
3429 mdata->dysymtab = cmd;
3430
3af9a47b
NC
3431 return 0;
3432}
3433
a95a4550 3434static int
ab273af8 3435bfd_mach_o_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 3436{
046b007d
TG
3437 bfd_mach_o_symtab_command *symtab = &command->command.symtab;
3438 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
46d1c23b 3439 struct mach_o_symtab_command_external raw;
3af9a47b
NC
3440
3441 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
3442
46d1c23b
TG
3443 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3444 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b 3445 return -1;
a95a4550 3446
46d1c23b
TG
3447 symtab->symoff = bfd_h_get_32 (abfd, raw.symoff);
3448 symtab->nsyms = bfd_h_get_32 (abfd, raw.nsyms);
3449 symtab->stroff = bfd_h_get_32 (abfd, raw.stroff);
3450 symtab->strsize = bfd_h_get_32 (abfd, raw.strsize);
046b007d
TG
3451 symtab->symbols = NULL;
3452 symtab->strtab = NULL;
3af9a47b 3453
046b007d 3454 if (symtab->nsyms != 0)
15e1c58a
TG
3455 abfd->flags |= HAS_SYMS;
3456
046b007d
TG
3457 if (mdata->symtab)
3458 return -1;
3459 mdata->symtab = symtab;
3af9a47b
NC
3460 return 0;
3461}
3462
15e1c58a 3463static int
ab273af8 3464bfd_mach_o_read_uuid (bfd *abfd, bfd_mach_o_load_command *command)
15e1c58a
TG
3465{
3466 bfd_mach_o_uuid_command *cmd = &command->command.uuid;
15e1c58a
TG
3467
3468 BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
3469
46d1c23b
TG
3470 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3471 || bfd_bread (cmd->uuid, 16, abfd) != 16)
15e1c58a
TG
3472 return -1;
3473
15e1c58a
TG
3474 return 0;
3475}
3476
046b007d 3477static int
ab273af8 3478bfd_mach_o_read_linkedit (bfd *abfd, bfd_mach_o_load_command *command)
046b007d
TG
3479{
3480 bfd_mach_o_linkedit_command *cmd = &command->command.linkedit;
46d1c23b 3481 struct mach_o_linkedit_data_command_external raw;
046b007d 3482
46d1c23b
TG
3483 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3484 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
3485 return -1;
3486
46d1c23b
TG
3487 cmd->dataoff = bfd_get_32 (abfd, raw.dataoff);
3488 cmd->datasize = bfd_get_32 (abfd, raw.datasize);
046b007d
TG
3489 return 0;
3490}
3491
3492static int
ab273af8 3493bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command)
046b007d
TG
3494{
3495 bfd_mach_o_str_command *cmd = &command->command.str;
46d1c23b 3496 struct mach_o_str_command_external raw;
046b007d
TG
3497 unsigned long off;
3498
46d1c23b
TG
3499 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3500 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
3501 return -1;
3502
46d1c23b 3503 off = bfd_get_32 (abfd, raw.str);
046b007d
TG
3504 cmd->stroff = command->offset + off;
3505 cmd->str_len = command->len - off;
3506 cmd->str = bfd_alloc (abfd, cmd->str_len);
3507 if (cmd->str == NULL)
3508 return -1;
3509 if (bfd_seek (abfd, cmd->stroff, SEEK_SET) != 0
91d6fa6a 3510 || bfd_bread ((void *) cmd->str, cmd->str_len, abfd) != cmd->str_len)
046b007d
TG
3511 return -1;
3512 return 0;
3513}
3514
ad86f1fb 3515static int
ab273af8 3516bfd_mach_o_read_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
ad86f1fb
TG
3517{
3518 bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
46d1c23b 3519 struct mach_o_dyld_info_command_external raw;
ad86f1fb 3520
46d1c23b
TG
3521 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3522 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
ad86f1fb
TG
3523 return -1;
3524
46d1c23b
TG
3525 cmd->rebase_off = bfd_get_32 (abfd, raw.rebase_off);
3526 cmd->rebase_size = bfd_get_32 (abfd, raw.rebase_size);
3527 cmd->bind_off = bfd_get_32 (abfd, raw.bind_off);
3528 cmd->bind_size = bfd_get_32 (abfd, raw.bind_size);
3529 cmd->weak_bind_off = bfd_get_32 (abfd, raw.weak_bind_off);
3530 cmd->weak_bind_size = bfd_get_32 (abfd, raw.weak_bind_size);
3531 cmd->lazy_bind_off = bfd_get_32 (abfd, raw.lazy_bind_off);
3532 cmd->lazy_bind_size = bfd_get_32 (abfd, raw.lazy_bind_size);
3533 cmd->export_off = bfd_get_32 (abfd, raw.export_off);
3534 cmd->export_size = bfd_get_32 (abfd, raw.export_size);
ad86f1fb
TG
3535 return 0;
3536}
3537
edbdea0e
TG
3538static bfd_boolean
3539bfd_mach_o_read_version_min (bfd *abfd, bfd_mach_o_load_command *command)
3540{
3541 bfd_mach_o_version_min_command *cmd = &command->command.version_min;
3542 struct mach_o_version_min_command_external raw;
3543 unsigned int ver;
3544
3545 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3546 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3547 return FALSE;
3548
3549 ver = bfd_get_32 (abfd, raw.version);
3550 cmd->rel = ver >> 16;
3551 cmd->maj = ver >> 8;
3552 cmd->min = ver;
3553 cmd->reserved = bfd_get_32 (abfd, raw.reserved);
3554 return TRUE;
3555}
3556
fc55a902
TG
3557static bfd_boolean
3558bfd_mach_o_read_encryption_info (bfd *abfd, bfd_mach_o_load_command *command)
3559{
3560 bfd_mach_o_encryption_info_command *cmd = &command->command.encryption_info;
3561 struct mach_o_encryption_info_command_external raw;
3562
3563 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3564 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3565 return FALSE;
3566
3567 cmd->cryptoff = bfd_get_32 (abfd, raw.cryptoff);
3568 cmd->cryptsize = bfd_get_32 (abfd, raw.cryptsize);
3569 cmd->cryptid = bfd_get_32 (abfd, raw.cryptid);
3570 return TRUE;
3571}
3572
3af9a47b 3573static int
ab273af8
TG
3574bfd_mach_o_read_segment (bfd *abfd,
3575 bfd_mach_o_load_command *command,
3576 unsigned int wide)
3af9a47b 3577{
3af9a47b
NC
3578 bfd_mach_o_segment_command *seg = &command->command.segment;
3579 unsigned long i;
a95a4550 3580
1e8a024a
TG
3581 if (wide)
3582 {
46d1c23b
TG
3583 struct mach_o_segment_command_64_external raw;
3584
1e8a024a 3585 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
3af9a47b 3586
46d1c23b
TG
3587 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3588 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3589 return -1;
3af9a47b 3590
46d1c23b 3591 memcpy (seg->segname, raw.segname, 16);
15e1c58a 3592 seg->segname[16] = '\0';
1e8a024a 3593
46d1c23b
TG
3594 seg->vmaddr = bfd_h_get_64 (abfd, raw.vmaddr);
3595 seg->vmsize = bfd_h_get_64 (abfd, raw.vmsize);
3596 seg->fileoff = bfd_h_get_64 (abfd, raw.fileoff);
3597 seg->filesize = bfd_h_get_64 (abfd, raw.filesize);
3598 seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
3599 seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
3600 seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
3601 seg->flags = bfd_h_get_32 (abfd, raw.flags);
1e8a024a
TG
3602 }
3603 else
3604 {
46d1c23b
TG
3605 struct mach_o_segment_command_32_external raw;
3606
1e8a024a
TG
3607 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
3608
46d1c23b
TG
3609 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3610 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3611 return -1;
1e8a024a 3612
46d1c23b 3613 memcpy (seg->segname, raw.segname, 16);
15e1c58a 3614 seg->segname[16] = '\0';
1e8a024a 3615
46d1c23b
TG
3616 seg->vmaddr = bfd_h_get_32 (abfd, raw.vmaddr);
3617 seg->vmsize = bfd_h_get_32 (abfd, raw.vmsize);
3618 seg->fileoff = bfd_h_get_32 (abfd, raw.fileoff);
3619 seg->filesize = bfd_h_get_32 (abfd, raw.filesize);
3620 seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
3621 seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
3622 seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
3623 seg->flags = bfd_h_get_32 (abfd, raw.flags);
1e8a024a 3624 }
9d4b6009
TG
3625 seg->sect_head = NULL;
3626 seg->sect_tail = NULL;
3af9a47b 3627
f1bde64c 3628 for (i = 0; i < seg->nsects; i++)
3af9a47b 3629 {
f1bde64c
TG
3630 bfd_vma segoff;
3631 asection *sec;
a95a4550 3632
f1bde64c
TG
3633 if (wide)
3634 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
3635 + (i * BFD_MACH_O_SECTION_64_SIZE);
3636 else
3637 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
3638 + (i * BFD_MACH_O_SECTION_SIZE);
3af9a47b 3639
f1bde64c
TG
3640 sec = bfd_mach_o_read_section (abfd, segoff, seg->initprot, wide);
3641 if (sec == NULL)
3642 return -1;
3643
3644 bfd_mach_o_append_section_to_segment (seg, sec);
3af9a47b
NC
3645 }
3646
3647 return 0;
3648}
3649
1e8a024a 3650static int
ab273af8 3651bfd_mach_o_read_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 3652{
ab273af8 3653 return bfd_mach_o_read_segment (abfd, command, 0);
1e8a024a
TG
3654}
3655
3656static int
ab273af8 3657bfd_mach_o_read_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 3658{
ab273af8 3659 return bfd_mach_o_read_segment (abfd, command, 1);
1e8a024a
TG
3660}
3661
3af9a47b 3662static int
ab273af8 3663bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 3664{
46d1c23b
TG
3665 struct mach_o_load_command_external raw;
3666 unsigned int cmd;
3af9a47b 3667
046b007d 3668 /* Read command type and length. */
c2f09c75 3669 if (bfd_seek (abfd, command->offset, SEEK_SET) != 0
46d1c23b 3670 || bfd_bread (&raw, BFD_MACH_O_LC_SIZE, abfd) != BFD_MACH_O_LC_SIZE)
3af9a47b
NC
3671 return -1;
3672
46d1c23b
TG
3673 cmd = bfd_h_get_32 (abfd, raw.cmd);
3674 command->type = cmd & ~BFD_MACH_O_LC_REQ_DYLD;
3675 command->type_required = cmd & BFD_MACH_O_LC_REQ_DYLD ? TRUE : FALSE;
3676 command->len = bfd_h_get_32 (abfd, raw.cmdsize);
3af9a47b
NC
3677
3678 switch (command->type)
3679 {
3680 case BFD_MACH_O_LC_SEGMENT:
ab273af8 3681 if (bfd_mach_o_read_segment_32 (abfd, command) != 0)
1e8a024a
TG
3682 return -1;
3683 break;
3684 case BFD_MACH_O_LC_SEGMENT_64:
ab273af8 3685 if (bfd_mach_o_read_segment_64 (abfd, command) != 0)
3af9a47b
NC
3686 return -1;
3687 break;
3688 case BFD_MACH_O_LC_SYMTAB:
ab273af8 3689 if (bfd_mach_o_read_symtab (abfd, command) != 0)
3af9a47b
NC
3690 return -1;
3691 break;
3692 case BFD_MACH_O_LC_SYMSEG:
3693 break;
3694 case BFD_MACH_O_LC_THREAD:
3695 case BFD_MACH_O_LC_UNIXTHREAD:
ab273af8 3696 if (bfd_mach_o_read_thread (abfd, command) != 0)
3af9a47b
NC
3697 return -1;
3698 break;
3699 case BFD_MACH_O_LC_LOAD_DYLINKER:
3700 case BFD_MACH_O_LC_ID_DYLINKER:
ab273af8 3701 if (bfd_mach_o_read_dylinker (abfd, command) != 0)
3af9a47b
NC
3702 return -1;
3703 break;
3704 case BFD_MACH_O_LC_LOAD_DYLIB:
3705 case BFD_MACH_O_LC_ID_DYLIB:
3706 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
046b007d 3707 case BFD_MACH_O_LC_REEXPORT_DYLIB:
73017762 3708 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
ab273af8 3709 if (bfd_mach_o_read_dylib (abfd, command) != 0)
3af9a47b
NC
3710 return -1;
3711 break;
3712 case BFD_MACH_O_LC_PREBOUND_DYLIB:
ab273af8 3713 if (bfd_mach_o_read_prebound_dylib (abfd, command) != 0)
3af9a47b
NC
3714 return -1;
3715 break;
3716 case BFD_MACH_O_LC_LOADFVMLIB:
3717 case BFD_MACH_O_LC_IDFVMLIB:
9f4a5bd1
TG
3718 if (bfd_mach_o_read_fvmlib (abfd, command) != 0)
3719 return -1;
3720 break;
3af9a47b
NC
3721 case BFD_MACH_O_LC_IDENT:
3722 case BFD_MACH_O_LC_FVMFILE:
3723 case BFD_MACH_O_LC_PREPAGE:
3724 case BFD_MACH_O_LC_ROUTINES:
9b02d212 3725 case BFD_MACH_O_LC_ROUTINES_64:
046b007d 3726 break;
3af9a47b 3727 case BFD_MACH_O_LC_SUB_FRAMEWORK:
046b007d
TG
3728 case BFD_MACH_O_LC_SUB_UMBRELLA:
3729 case BFD_MACH_O_LC_SUB_LIBRARY:
3730 case BFD_MACH_O_LC_SUB_CLIENT:
0c9b2b4c 3731 case BFD_MACH_O_LC_RPATH:
ab273af8 3732 if (bfd_mach_o_read_str (abfd, command) != 0)
046b007d 3733 return -1;
3af9a47b
NC
3734 break;
3735 case BFD_MACH_O_LC_DYSYMTAB:
ab273af8 3736 if (bfd_mach_o_read_dysymtab (abfd, command) != 0)
3af9a47b
NC
3737 return -1;
3738 break;
3af9a47b
NC
3739 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
3740 case BFD_MACH_O_LC_PREBIND_CKSUM:
3741 break;
15e1c58a 3742 case BFD_MACH_O_LC_UUID:
ab273af8 3743 if (bfd_mach_o_read_uuid (abfd, command) != 0)
15e1c58a
TG
3744 return -1;
3745 break;
3746 case BFD_MACH_O_LC_CODE_SIGNATURE:
846b9259 3747 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
edbdea0e 3748 case BFD_MACH_O_LC_FUNCTION_STARTS:
ab273af8 3749 if (bfd_mach_o_read_linkedit (abfd, command) != 0)
046b007d 3750 return -1;
15e1c58a 3751 break;
fc55a902
TG
3752 case BFD_MACH_O_LC_ENCRYPTION_INFO:
3753 if (!bfd_mach_o_read_encryption_info (abfd, command))
3754 return -1;
3755 break;
ad86f1fb 3756 case BFD_MACH_O_LC_DYLD_INFO:
ab273af8 3757 if (bfd_mach_o_read_dyld_info (abfd, command) != 0)
ad86f1fb
TG
3758 return -1;
3759 break;
edbdea0e
TG
3760 case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
3761 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
3762 if (!bfd_mach_o_read_version_min (abfd, command))
3763 return -1;
3764 break;
3af9a47b 3765 default:
fc55a902 3766 (*_bfd_error_handler)(_("%B: unknown load command 0x%lx"),
c0d9d051 3767 abfd, (unsigned long) command->type);
3af9a47b
NC
3768 break;
3769 }
3770
3771 return 0;
3772}
3773
3774static void
116c20d2 3775bfd_mach_o_flatten_sections (bfd *abfd)
3af9a47b 3776{
046b007d 3777 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 3778 long csect = 0;
f1bde64c 3779 unsigned long i;
a95a4550 3780
15e1c58a 3781 /* Count total number of sections. */
3af9a47b
NC
3782 mdata->nsects = 0;
3783
3784 for (i = 0; i < mdata->header.ncmds; i++)
3785 {
1e8a024a
TG
3786 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
3787 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
3af9a47b 3788 {
e84d6fca
AM
3789 bfd_mach_o_segment_command *seg;
3790
3791 seg = &mdata->commands[i].command.segment;
3af9a47b
NC
3792 mdata->nsects += seg->nsects;
3793 }
3794 }
3795
15e1c58a 3796 /* Allocate sections array. */
e84d6fca
AM
3797 mdata->sections = bfd_alloc (abfd,
3798 mdata->nsects * sizeof (bfd_mach_o_section *));
15e1c58a
TG
3799
3800 /* Fill the array. */
3af9a47b
NC
3801 csect = 0;
3802
3803 for (i = 0; i < mdata->header.ncmds; i++)
3804 {
1e8a024a
TG
3805 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
3806 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
3af9a47b 3807 {
e84d6fca 3808 bfd_mach_o_segment_command *seg;
f1bde64c 3809 bfd_mach_o_section *sec;
3af9a47b 3810
e84d6fca 3811 seg = &mdata->commands[i].command.segment;
3af9a47b
NC
3812 BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
3813
f1bde64c
TG
3814 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
3815 mdata->sections[csect++] = sec;
3af9a47b
NC
3816 }
3817 }
3818}
3819
afbb9e17 3820static bfd_boolean
116c20d2 3821bfd_mach_o_scan_start_address (bfd *abfd)
3af9a47b 3822{
046b007d 3823 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b
NC
3824 bfd_mach_o_thread_command *cmd = NULL;
3825 unsigned long i;
3826
3827 for (i = 0; i < mdata->header.ncmds; i++)
afbb9e17
TG
3828 if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
3829 (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
3830 {
3831 cmd = &mdata->commands[i].command.thread;
3832 break;
3833 }
3af9a47b
NC
3834
3835 if (cmd == NULL)
afbb9e17 3836 return FALSE;
3af9a47b 3837
afbb9e17 3838 /* FIXME: create a subtarget hook ? */
3af9a47b
NC
3839 for (i = 0; i < cmd->nflavours; i++)
3840 {
a95a4550 3841 if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
e84d6fca 3842 && (cmd->flavours[i].flavour
15e1c58a 3843 == (unsigned long) BFD_MACH_O_x86_THREAD_STATE32))
3af9a47b
NC
3844 {
3845 unsigned char buf[4];
3846
c2f09c75
TG
3847 if (bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET) != 0
3848 || bfd_bread (buf, 4, abfd) != 4)
afbb9e17 3849 return FALSE;
3af9a47b
NC
3850
3851 abfd->start_address = bfd_h_get_32 (abfd, buf);
3852 }
a95a4550 3853 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
3af9a47b
NC
3854 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
3855 {
3856 unsigned char buf[4];
3857
c2f09c75
TG
3858 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
3859 || bfd_bread (buf, 4, abfd) != 4)
afbb9e17 3860 return FALSE;
3af9a47b
NC
3861
3862 abfd->start_address = bfd_h_get_32 (abfd, buf);
3863 }
1e8a024a 3864 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
b32e07d7 3865 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE64))
1e8a024a
TG
3866 {
3867 unsigned char buf[8];
3868
c2f09c75
TG
3869 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
3870 || bfd_bread (buf, 8, abfd) != 8)
afbb9e17 3871 return FALSE;
1e8a024a
TG
3872
3873 abfd->start_address = bfd_h_get_64 (abfd, buf);
3874 }
3875 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
3876 && (cmd->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE64))
3877 {
3878 unsigned char buf[8];
3879
c2f09c75
TG
3880 if (bfd_seek (abfd, cmd->flavours[i].offset + (16 * 8), SEEK_SET) != 0
3881 || bfd_bread (buf, 8, abfd) != 8)
afbb9e17 3882 return FALSE;
1e8a024a
TG
3883
3884 abfd->start_address = bfd_h_get_64 (abfd, buf);
3885 }
3af9a47b
NC
3886 }
3887
afbb9e17 3888 return TRUE;
3af9a47b
NC
3889}
3890
42fa0891
TG
3891bfd_boolean
3892bfd_mach_o_set_arch_mach (bfd *abfd,
3893 enum bfd_architecture arch,
3894 unsigned long machine)
3895{
3896 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
3897
3898 /* If this isn't the right architecture for this backend, and this
3899 isn't the generic backend, fail. */
3900 if (arch != bed->arch
3901 && arch != bfd_arch_unknown
3902 && bed->arch != bfd_arch_unknown)
3903 return FALSE;
3904
3905 return bfd_default_set_arch_mach (abfd, arch, machine);
3906}
3907
afbb9e17 3908static bfd_boolean
116c20d2
NC
3909bfd_mach_o_scan (bfd *abfd,
3910 bfd_mach_o_header *header,
3911 bfd_mach_o_data_struct *mdata)
3af9a47b
NC
3912{
3913 unsigned int i;
3af9a47b
NC
3914 enum bfd_architecture cputype;
3915 unsigned long cpusubtype;
1e8a024a
TG
3916 unsigned int hdrsize;
3917
c2f09c75 3918 hdrsize = mach_o_wide_p (header) ?
154a1ee5 3919 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
3af9a47b 3920
3af9a47b 3921 mdata->header = *header;
3af9a47b 3922
154a1ee5 3923 abfd->flags = abfd->flags & BFD_IN_MEMORY;
15e1c58a
TG
3924 switch (header->filetype)
3925 {
3926 case BFD_MACH_O_MH_OBJECT:
3927 abfd->flags |= HAS_RELOC;
3928 break;
3929 case BFD_MACH_O_MH_EXECUTE:
3930 abfd->flags |= EXEC_P;
3931 break;
3932 case BFD_MACH_O_MH_DYLIB:
3933 case BFD_MACH_O_MH_BUNDLE:
3934 abfd->flags |= DYNAMIC;
3935 break;
3936 }
3937
3af9a47b
NC
3938 abfd->tdata.mach_o_data = mdata;
3939
e84d6fca
AM
3940 bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
3941 &cputype, &cpusubtype);
3af9a47b
NC
3942 if (cputype == bfd_arch_unknown)
3943 {
afbb9e17
TG
3944 (*_bfd_error_handler)
3945 (_("bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"),
3946 header->cputype, header->cpusubtype);
3947 return FALSE;
3af9a47b
NC
3948 }
3949
3950 bfd_set_arch_mach (abfd, cputype, cpusubtype);
a95a4550 3951
3af9a47b
NC
3952 if (header->ncmds != 0)
3953 {
046b007d
TG
3954 mdata->commands = bfd_alloc
3955 (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
3af9a47b 3956 if (mdata->commands == NULL)
afbb9e17 3957 return FALSE;
a95a4550 3958
3af9a47b
NC
3959 for (i = 0; i < header->ncmds; i++)
3960 {
3961 bfd_mach_o_load_command *cur = &mdata->commands[i];
3962
3963 if (i == 0)
1e8a024a 3964 cur->offset = hdrsize;
3af9a47b
NC
3965 else
3966 {
3967 bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
3968 cur->offset = prev->offset + prev->len;
3969 }
3970
ab273af8 3971 if (bfd_mach_o_read_command (abfd, cur) < 0)
afbb9e17 3972 return FALSE;
a95a4550 3973 }
3af9a47b
NC
3974 }
3975
3976 if (bfd_mach_o_scan_start_address (abfd) < 0)
afbb9e17 3977 return FALSE;
3af9a47b
NC
3978
3979 bfd_mach_o_flatten_sections (abfd);
afbb9e17 3980 return TRUE;
3af9a47b
NC
3981}
3982
b34976b6 3983bfd_boolean
154a1ee5 3984bfd_mach_o_mkobject_init (bfd *abfd)
3af9a47b
NC
3985{
3986 bfd_mach_o_data_struct *mdata = NULL;
3987
116c20d2 3988 mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
3af9a47b 3989 if (mdata == NULL)
b34976b6 3990 return FALSE;
3af9a47b
NC
3991 abfd->tdata.mach_o_data = mdata;
3992
3993 mdata->header.magic = 0;
3994 mdata->header.cputype = 0;
3995 mdata->header.cpusubtype = 0;
3996 mdata->header.filetype = 0;
3997 mdata->header.ncmds = 0;
3998 mdata->header.sizeofcmds = 0;
3999 mdata->header.flags = 0;
4000 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
4001 mdata->commands = NULL;
3af9a47b
NC
4002 mdata->nsects = 0;
4003 mdata->sections = NULL;
4434114c 4004 mdata->dyn_reloc_cache = NULL;
3af9a47b 4005
b34976b6 4006 return TRUE;
3af9a47b
NC
4007}
4008
42fa0891
TG
4009static bfd_boolean
4010bfd_mach_o_gen_mkobject (bfd *abfd)
4011{
4012 bfd_mach_o_data_struct *mdata;
4013
4014 if (!bfd_mach_o_mkobject_init (abfd))
4015 return FALSE;
4016
4017 mdata = bfd_mach_o_get_data (abfd);
4018 mdata->header.magic = BFD_MACH_O_MH_MAGIC;
4019 mdata->header.cputype = 0;
4020 mdata->header.cpusubtype = 0;
4021 mdata->header.byteorder = abfd->xvec->byteorder;
4022 mdata->header.version = 1;
4023
4024 return TRUE;
4025}
4026
3af9a47b 4027const bfd_target *
154a1ee5
TG
4028bfd_mach_o_header_p (bfd *abfd,
4029 bfd_mach_o_filetype filetype,
4030 bfd_mach_o_cpu_type cputype)
3af9a47b 4031{
e84d6fca 4032 struct bfd_preserve preserve;
3af9a47b
NC
4033 bfd_mach_o_header header;
4034
e84d6fca 4035 preserve.marker = NULL;
154a1ee5 4036 if (!bfd_mach_o_read_header (abfd, &header))
e84d6fca 4037 goto wrong;
3af9a47b 4038
e84d6fca
AM
4039 if (! (header.byteorder == BFD_ENDIAN_BIG
4040 || header.byteorder == BFD_ENDIAN_LITTLE))
3af9a47b 4041 {
4a97a0e5
AM
4042 (*_bfd_error_handler) (_("unknown header byte-order value 0x%lx"),
4043 (unsigned long) header.byteorder);
e84d6fca 4044 goto wrong;
3af9a47b
NC
4045 }
4046
e84d6fca
AM
4047 if (! ((header.byteorder == BFD_ENDIAN_BIG
4048 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
4049 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
4050 || (header.byteorder == BFD_ENDIAN_LITTLE
4051 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
4052 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
4053 goto wrong;
3af9a47b 4054
154a1ee5
TG
4055 /* Check cputype and filetype.
4056 In case of wildcard, do not accept magics that are handled by existing
4057 targets. */
4058 if (cputype)
4059 {
4060 if (header.cputype != cputype)
4061 goto wrong;
4062 }
b22161d6 4063
154a1ee5
TG
4064 if (filetype)
4065 {
4066 if (header.filetype != filetype)
4067 goto wrong;
4068 }
4069 else
4070 {
4071 switch (header.filetype)
4072 {
4073 case BFD_MACH_O_MH_CORE:
4074 /* Handled by core_p */
4075 goto wrong;
4076 default:
4077 break;
4078 }
4079 }
4080
e84d6fca
AM
4081 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
4082 if (preserve.marker == NULL
4083 || !bfd_preserve_save (abfd, &preserve))
4084 goto fail;
3af9a47b 4085
afbb9e17
TG
4086 if (!bfd_mach_o_scan (abfd, &header,
4087 (bfd_mach_o_data_struct *) preserve.marker))
e84d6fca 4088 goto wrong;
a95a4550 4089
e84d6fca 4090 bfd_preserve_finish (abfd, &preserve);
3af9a47b 4091 return abfd->xvec;
e84d6fca
AM
4092
4093 wrong:
4094 bfd_set_error (bfd_error_wrong_format);
4095
4096 fail:
4097 if (preserve.marker != NULL)
4098 bfd_preserve_restore (abfd, &preserve);
4099 return NULL;
3af9a47b
NC
4100}
4101
154a1ee5
TG
4102static const bfd_target *
4103bfd_mach_o_gen_object_p (bfd *abfd)
3af9a47b 4104{
154a1ee5
TG
4105 return bfd_mach_o_header_p (abfd, 0, 0);
4106}
e84d6fca 4107
154a1ee5
TG
4108static const bfd_target *
4109bfd_mach_o_gen_core_p (bfd *abfd)
4110{
4111 return bfd_mach_o_header_p (abfd, BFD_MACH_O_MH_CORE, 0);
3af9a47b
NC
4112}
4113
4114typedef struct mach_o_fat_archentry
4115{
4116 unsigned long cputype;
4117 unsigned long cpusubtype;
4118 unsigned long offset;
4119 unsigned long size;
4120 unsigned long align;
3af9a47b
NC
4121} mach_o_fat_archentry;
4122
4123typedef struct mach_o_fat_data_struct
4124{
4125 unsigned long magic;
4126 unsigned long nfat_arch;
4127 mach_o_fat_archentry *archentries;
4128} mach_o_fat_data_struct;
4129
4130const bfd_target *
116c20d2 4131bfd_mach_o_archive_p (bfd *abfd)
3af9a47b 4132{
e84d6fca 4133 mach_o_fat_data_struct *adata = NULL;
46d1c23b 4134 struct mach_o_fat_header_external hdr;
3af9a47b
NC
4135 unsigned long i;
4136
c2f09c75 4137 if (bfd_seek (abfd, 0, SEEK_SET) != 0
46d1c23b 4138 || bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
e84d6fca 4139 goto error;
3af9a47b 4140
116c20d2 4141 adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
3af9a47b 4142 if (adata == NULL)
e84d6fca 4143 goto error;
a95a4550 4144
46d1c23b
TG
4145 adata->magic = bfd_getb32 (hdr.magic);
4146 adata->nfat_arch = bfd_getb32 (hdr.nfat_arch);
3af9a47b 4147 if (adata->magic != 0xcafebabe)
e84d6fca 4148 goto error;
27cc28f9
AS
4149 /* Avoid matching Java bytecode files, which have the same magic number.
4150 In the Java bytecode file format this field contains the JVM version,
4151 which starts at 43.0. */
4152 if (adata->nfat_arch > 30)
4153 goto error;
3af9a47b 4154
c2f09c75 4155 adata->archentries =
3af9a47b
NC
4156 bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
4157 if (adata->archentries == NULL)
e84d6fca 4158 goto error;
3af9a47b
NC
4159
4160 for (i = 0; i < adata->nfat_arch; i++)
4161 {
46d1c23b
TG
4162 struct mach_o_fat_arch_external arch;
4163 if (bfd_bread (&arch, sizeof (arch), abfd) != sizeof (arch))
e84d6fca 4164 goto error;
46d1c23b
TG
4165 adata->archentries[i].cputype = bfd_getb32 (arch.cputype);
4166 adata->archentries[i].cpusubtype = bfd_getb32 (arch.cpusubtype);
4167 adata->archentries[i].offset = bfd_getb32 (arch.offset);
4168 adata->archentries[i].size = bfd_getb32 (arch.size);
4169 adata->archentries[i].align = bfd_getb32 (arch.align);
3af9a47b
NC
4170 }
4171
4172 abfd->tdata.mach_o_fat_data = adata;
4173 return abfd->xvec;
e84d6fca
AM
4174
4175 error:
4176 if (adata != NULL)
4177 bfd_release (abfd, adata);
4178 bfd_set_error (bfd_error_wrong_format);
4179 return NULL;
3af9a47b
NC
4180}
4181
a4e241ca
TG
4182/* Set the filename for a fat binary member ABFD, whose bfd architecture is
4183 ARCH_TYPE/ARCH_SUBTYPE and corresponding entry in header is ENTRY.
4184 Set arelt_data and origin fields too. */
4185
4186static void
4187bfd_mach_o_fat_member_init (bfd *abfd,
4188 enum bfd_architecture arch_type,
4189 unsigned long arch_subtype,
4190 mach_o_fat_archentry *entry)
4191{
4192 struct areltdata *areltdata;
4193 /* Create the member filename. Use ARCH_NAME. */
4194 const bfd_arch_info_type *ap = bfd_lookup_arch (arch_type, arch_subtype);
4195
4196 if (ap)
4197 {
4198 /* Use the architecture name if known. */
4199 abfd->filename = ap->printable_name;
4200 }
4201 else
4202 {
4203 /* Forge a uniq id. */
4204 const size_t namelen = 2 + 8 + 1 + 2 + 8 + 1;
4205 char *name = bfd_alloc (abfd, namelen);
4206 snprintf (name, namelen, "0x%lx-0x%lx",
4207 entry->cputype, entry->cpusubtype);
4208 abfd->filename = name;
4209 }
4210
4211 areltdata = bfd_zalloc (abfd, sizeof (struct areltdata));
4212 areltdata->parsed_size = entry->size;
4213 abfd->arelt_data = areltdata;
4214 abfd->iostream = NULL;
4215 abfd->origin = entry->offset;
4216}
4217
3af9a47b 4218bfd *
116c20d2 4219bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
3af9a47b 4220{
e84d6fca 4221 mach_o_fat_data_struct *adata;
3af9a47b
NC
4222 mach_o_fat_archentry *entry = NULL;
4223 unsigned long i;
15e1c58a 4224 bfd *nbfd;
15e1c58a
TG
4225 enum bfd_architecture arch_type;
4226 unsigned long arch_subtype;
3af9a47b 4227
e84d6fca 4228 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
3af9a47b
NC
4229 BFD_ASSERT (adata != NULL);
4230
4231 /* Find index of previous entry. */
4232 if (prev == NULL)
a4e241ca
TG
4233 {
4234 /* Start at first one. */
4235 i = 0;
4236 }
3af9a47b
NC
4237 else
4238 {
a4e241ca 4239 /* Find index of PREV. */
3af9a47b
NC
4240 for (i = 0; i < adata->nfat_arch; i++)
4241 {
15e1c58a 4242 if (adata->archentries[i].offset == prev->origin)
3af9a47b
NC
4243 break;
4244 }
4245
4246 if (i == adata->nfat_arch)
4247 {
4248 /* Not found. */
4249 bfd_set_error (bfd_error_bad_value);
a95a4550 4250 return NULL;
3af9a47b 4251 }
a4e241ca
TG
4252
4253 /* Get next entry. */
4254 i++;
4255 }
a95a4550 4256
3af9a47b
NC
4257 if (i >= adata->nfat_arch)
4258 {
4259 bfd_set_error (bfd_error_no_more_archived_files);
4260 return NULL;
4261 }
4262
4263 entry = &adata->archentries[i];
15e1c58a
TG
4264 nbfd = _bfd_new_bfd_contained_in (archive);
4265 if (nbfd == NULL)
4266 return NULL;
4267
15e1c58a
TG
4268 bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype,
4269 &arch_type, &arch_subtype);
846b9259 4270
a4e241ca
TG
4271 bfd_mach_o_fat_member_init (nbfd, arch_type, arch_subtype, entry);
4272
846b9259 4273 bfd_set_arch_mach (nbfd, arch_type, arch_subtype);
3af9a47b 4274
15e1c58a 4275 return nbfd;
3af9a47b
NC
4276}
4277
15bbba8d
TG
4278/* Analogous to stat call. */
4279
4280static int
4281bfd_mach_o_fat_stat_arch_elt (bfd *abfd, struct stat *buf)
4282{
4283 if (abfd->arelt_data == NULL)
4284 {
4285 bfd_set_error (bfd_error_invalid_operation);
4286 return -1;
4287 }
4288
4289 buf->st_mtime = 0;
4290 buf->st_uid = 0;
4291 buf->st_gid = 0;
4292 buf->st_mode = 0644;
4293 buf->st_size = arelt_size (abfd);
4294
4295 return 0;
4296}
4297
846b9259
TG
4298/* If ABFD format is FORMAT and architecture is ARCH, return it.
4299 If ABFD is a fat image containing a member that corresponds to FORMAT
4300 and ARCH, returns it.
4301 In other case, returns NULL.
4302 This function allows transparent uses of fat images. */
a4e241ca 4303
846b9259
TG
4304bfd *
4305bfd_mach_o_fat_extract (bfd *abfd,
4306 bfd_format format,
4307 const bfd_arch_info_type *arch)
4308{
4309 bfd *res;
4310 mach_o_fat_data_struct *adata;
4311 unsigned int i;
4312
4313 if (bfd_check_format (abfd, format))
4314 {
4315 if (bfd_get_arch_info (abfd) == arch)
4316 return abfd;
4317 return NULL;
4318 }
4319 if (!bfd_check_format (abfd, bfd_archive)
4320 || abfd->xvec != &mach_o_fat_vec)
4321 return NULL;
c2f09c75 4322
846b9259
TG
4323 /* This is a Mach-O fat image. */
4324 adata = (mach_o_fat_data_struct *) abfd->tdata.mach_o_fat_data;
4325 BFD_ASSERT (adata != NULL);
4326
4327 for (i = 0; i < adata->nfat_arch; i++)
4328 {
4329 struct mach_o_fat_archentry *e = &adata->archentries[i];
4330 enum bfd_architecture cpu_type;
4331 unsigned long cpu_subtype;
4332
4333 bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype,
4334 &cpu_type, &cpu_subtype);
4335 if (cpu_type != arch->arch || cpu_subtype != arch->mach)
4336 continue;
4337
4338 /* The architecture is found. */
4339 res = _bfd_new_bfd_contained_in (abfd);
4340 if (res == NULL)
4341 return NULL;
4342
a4e241ca 4343 bfd_mach_o_fat_member_init (res, cpu_type, cpu_subtype, e);
846b9259
TG
4344
4345 if (bfd_check_format (res, format))
4346 {
4347 BFD_ASSERT (bfd_get_arch_info (res) == arch);
4348 return res;
4349 }
4350 bfd_close (res);
4351 return NULL;
4352 }
4353
4354 return NULL;
4355}
4356
3af9a47b 4357int
116c20d2
NC
4358bfd_mach_o_lookup_command (bfd *abfd,
4359 bfd_mach_o_load_command_type type,
4360 bfd_mach_o_load_command **mcommand)
3af9a47b 4361{
046b007d 4362 struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
3af9a47b
NC
4363 bfd_mach_o_load_command *ncmd = NULL;
4364 unsigned int i, num;
4365
3af9a47b
NC
4366 BFD_ASSERT (md != NULL);
4367 BFD_ASSERT (mcommand != NULL);
4368
4369 num = 0;
4370 for (i = 0; i < md->header.ncmds; i++)
4371 {
4372 struct bfd_mach_o_load_command *cmd = &md->commands[i];
4373
4374 if (cmd->type != type)
4375 continue;
4376
4377 if (num == 0)
4378 ncmd = cmd;
4379 num++;
4380 }
4381
4382 *mcommand = ncmd;
4383 return num;
4384}
4385
4386unsigned long
116c20d2 4387bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
3af9a47b
NC
4388{
4389 switch (type)
4390 {
4391 case BFD_MACH_O_CPU_TYPE_MC680x0:
4392 return 0x04000000;
4393 case BFD_MACH_O_CPU_TYPE_MC88000:
4394 return 0xffffe000;
4395 case BFD_MACH_O_CPU_TYPE_POWERPC:
4396 return 0xc0000000;
4397 case BFD_MACH_O_CPU_TYPE_I386:
4398 return 0xc0000000;
4399 case BFD_MACH_O_CPU_TYPE_SPARC:
4400 return 0xf0000000;
4401 case BFD_MACH_O_CPU_TYPE_I860:
4402 return 0;
4403 case BFD_MACH_O_CPU_TYPE_HPPA:
e84d6fca 4404 return 0xc0000000 - 0x04000000;
3af9a47b
NC
4405 default:
4406 return 0;
4407 }
4408}
4409
ab76eeaf
IS
4410/* The following two tables should be kept, as far as possible, in order of
4411 most frequently used entries to optimize their use from gas. */
4412
c5012cd8 4413const bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] =
046b007d
TG
4414{
4415 { "regular", BFD_MACH_O_S_REGULAR},
ab76eeaf 4416 { "coalesced", BFD_MACH_O_S_COALESCED},
046b007d
TG
4417 { "zerofill", BFD_MACH_O_S_ZEROFILL},
4418 { "cstring_literals", BFD_MACH_O_S_CSTRING_LITERALS},
4419 { "4byte_literals", BFD_MACH_O_S_4BYTE_LITERALS},
4420 { "8byte_literals", BFD_MACH_O_S_8BYTE_LITERALS},
ab76eeaf 4421 { "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS},
046b007d 4422 { "literal_pointers", BFD_MACH_O_S_LITERAL_POINTERS},
046b007d
TG
4423 { "mod_init_func_pointers", BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS},
4424 { "mod_fini_func_pointers", BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS},
046b007d
TG
4425 { "gb_zerofill", BFD_MACH_O_S_GB_ZEROFILL},
4426 { "interposing", BFD_MACH_O_S_INTERPOSING},
046b007d 4427 { "dtrace_dof", BFD_MACH_O_S_DTRACE_DOF},
ab76eeaf
IS
4428 { "non_lazy_symbol_pointers", BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS},
4429 { "lazy_symbol_pointers", BFD_MACH_O_S_LAZY_SYMBOL_POINTERS},
a4551119 4430 { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS},
046b007d
TG
4431 { "lazy_dylib_symbol_pointers", BFD_MACH_O_S_LAZY_DYLIB_SYMBOL_POINTERS},
4432 { NULL, 0}
4433};
4434
c5012cd8 4435const bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[] =
046b007d 4436{
ab76eeaf
IS
4437 { "pure_instructions", BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS },
4438 { "some_instructions", BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS },
046b007d
TG
4439 { "loc_reloc", BFD_MACH_O_S_ATTR_LOC_RELOC },
4440 { "ext_reloc", BFD_MACH_O_S_ATTR_EXT_RELOC },
046b007d 4441 { "debug", BFD_MACH_O_S_ATTR_DEBUG },
046b007d
TG
4442 { "live_support", BFD_MACH_O_S_ATTR_LIVE_SUPPORT },
4443 { "no_dead_strip", BFD_MACH_O_S_ATTR_NO_DEAD_STRIP },
4444 { "strip_static_syms", BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS },
4445 { "no_toc", BFD_MACH_O_S_ATTR_NO_TOC },
a4551119 4446 { "self_modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
ab76eeaf 4447 { "modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
046b007d
TG
4448 { NULL, 0}
4449};
4450
a4551119 4451/* Get the section type from NAME. Return 256 if NAME is unknown. */
53d58d96
TG
4452
4453unsigned int
ab76eeaf 4454bfd_mach_o_get_section_type_from_name (bfd *abfd, const char *name)
53d58d96 4455{
afbb9e17 4456 const bfd_mach_o_xlat_name *x;
ab76eeaf 4457 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
53d58d96
TG
4458
4459 for (x = bfd_mach_o_section_type_name; x->name; x++)
4460 if (strcmp (x->name, name) == 0)
ab76eeaf
IS
4461 {
4462 /* We found it... does the target support it? */
4463 if (bed->bfd_mach_o_section_type_valid_for_target == NULL
4464 || bed->bfd_mach_o_section_type_valid_for_target (x->val))
4465 return x->val; /* OK. */
4466 else
4467 break; /* Not supported. */
4468 }
a4551119
TG
4469 /* Maximum section ID = 0xff. */
4470 return 256;
53d58d96
TG
4471}
4472
4473/* Get the section attribute from NAME. Return -1 if NAME is unknown. */
4474
4475unsigned int
4476bfd_mach_o_get_section_attribute_from_name (const char *name)
4477{
afbb9e17 4478 const bfd_mach_o_xlat_name *x;
53d58d96
TG
4479
4480 for (x = bfd_mach_o_section_attribute_name; x->name; x++)
4481 if (strcmp (x->name, name) == 0)
4482 return x->val;
4483 return (unsigned int)-1;
4484}
4485
3af9a47b 4486int
116c20d2
NC
4487bfd_mach_o_core_fetch_environment (bfd *abfd,
4488 unsigned char **rbuf,
4489 unsigned int *rlen)
3af9a47b 4490{
046b007d 4491 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b
NC
4492 unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
4493 unsigned int i = 0;
4494
4495 for (i = 0; i < mdata->header.ncmds; i++)
4496 {
4497 bfd_mach_o_load_command *cur = &mdata->commands[i];
4498 bfd_mach_o_segment_command *seg = NULL;
4499
4500 if (cur->type != BFD_MACH_O_LC_SEGMENT)
4501 continue;
4502
4503 seg = &cur->command.segment;
4504
4505 if ((seg->vmaddr + seg->vmsize) == stackaddr)
4506 {
4507 unsigned long start = seg->fileoff;
4508 unsigned long end = seg->fileoff + seg->filesize;
4509 unsigned char *buf = bfd_malloc (1024);
4510 unsigned long size = 1024;
4511
4512 for (;;)
4513 {
4514 bfd_size_type nread = 0;
4515 unsigned long offset;
4516 int found_nonnull = 0;
4517
4518 if (size > (end - start))
4519 size = (end - start);
4520
515ef31d
NC
4521 buf = bfd_realloc_or_free (buf, size);
4522 if (buf == NULL)
4523 return -1;
c2f09c75
TG
4524
4525 if (bfd_seek (abfd, end - size, SEEK_SET) != 0)
4526 {
4527 free (buf);
4528 return -1;
4529 }
4530
3af9a47b 4531 nread = bfd_bread (buf, size, abfd);
a95a4550 4532
3af9a47b 4533 if (nread != size)
515ef31d
NC
4534 {
4535 free (buf);
4536 return -1;
4537 }
a95a4550 4538
3af9a47b
NC
4539 for (offset = 4; offset <= size; offset += 4)
4540 {
e84d6fca 4541 unsigned long val;
3af9a47b 4542
e84d6fca 4543 val = *((unsigned long *) (buf + size - offset));
3af9a47b
NC
4544 if (! found_nonnull)
4545 {
4546 if (val != 0)
4547 found_nonnull = 1;
4548 }
4549 else if (val == 0x0)
4550 {
e84d6fca
AM
4551 unsigned long bottom;
4552 unsigned long top;
3af9a47b 4553
e84d6fca
AM
4554 bottom = seg->fileoff + seg->filesize - offset;
4555 top = seg->fileoff + seg->filesize - 4;
3af9a47b
NC
4556 *rbuf = bfd_malloc (top - bottom);
4557 *rlen = top - bottom;
4558
4559 memcpy (*rbuf, buf + size - *rlen, *rlen);
515ef31d 4560 free (buf);
3af9a47b
NC
4561 return 0;
4562 }
4563 }
4564
4565 if (size == (end - start))
4566 break;
4567
4568 size *= 2;
4569 }
515ef31d
NC
4570
4571 free (buf);
3af9a47b
NC
4572 }
4573 }
4574
4575 return -1;
4576}
4577
4578char *
116c20d2 4579bfd_mach_o_core_file_failing_command (bfd *abfd)
3af9a47b
NC
4580{
4581 unsigned char *buf = NULL;
4582 unsigned int len = 0;
4583 int ret = -1;
4584
4585 ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
4586 if (ret < 0)
4587 return NULL;
4588
f075ee0c 4589 return (char *) buf;
3af9a47b
NC
4590}
4591
4592int
116c20d2 4593bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
3af9a47b
NC
4594{
4595 return 0;
4596}
4597
2ca7691a
TG
4598static bfd_mach_o_uuid_command *
4599bfd_mach_o_lookup_uuid_command (bfd *abfd)
4600{
4601 bfd_mach_o_load_command *uuid_cmd;
4602 int ncmd = bfd_mach_o_lookup_command (abfd, BFD_MACH_O_LC_UUID, &uuid_cmd);
4603 if (ncmd != 1)
4604 return FALSE;
4605 return &uuid_cmd->command.uuid;
4606}
4607
4608/* Return true if ABFD is a dSYM file and its UUID matches UUID_CMD. */
4609
4610static bfd_boolean
4611bfd_mach_o_dsym_for_uuid_p (bfd *abfd, const bfd_mach_o_uuid_command *uuid_cmd)
4612{
4613 bfd_mach_o_uuid_command *dsym_uuid_cmd;
4614
4615 BFD_ASSERT (abfd);
4616 BFD_ASSERT (uuid_cmd);
4617
4618 if (!bfd_check_format (abfd, bfd_object))
4619 return FALSE;
4620
4621 if (bfd_get_flavour (abfd) != bfd_target_mach_o_flavour
4622 || bfd_mach_o_get_data (abfd) == NULL
4623 || bfd_mach_o_get_data (abfd)->header.filetype != BFD_MACH_O_MH_DSYM)
4624 return FALSE;
4625
4626 dsym_uuid_cmd = bfd_mach_o_lookup_uuid_command (abfd);
4627 if (dsym_uuid_cmd == NULL)
4628 return FALSE;
4629
4630 if (memcmp (uuid_cmd->uuid, dsym_uuid_cmd->uuid,
4631 sizeof (uuid_cmd->uuid)) != 0)
4632 return FALSE;
4633
4634 return TRUE;
4635}
4636
4637/* Find a BFD in DSYM_FILENAME which matches ARCH and UUID_CMD.
4638 The caller is responsible for closing the returned BFD object and
4639 its my_archive if the returned BFD is in a fat dSYM. */
4640
4641static bfd *
4642bfd_mach_o_find_dsym (const char *dsym_filename,
4643 const bfd_mach_o_uuid_command *uuid_cmd,
4644 const bfd_arch_info_type *arch)
4645{
4646 bfd *base_dsym_bfd, *dsym_bfd;
4647
4648 BFD_ASSERT (uuid_cmd);
4649
4650 base_dsym_bfd = bfd_openr (dsym_filename, NULL);
4651 if (base_dsym_bfd == NULL)
4652 return NULL;
4653
4654 dsym_bfd = bfd_mach_o_fat_extract (base_dsym_bfd, bfd_object, arch);
4655 if (bfd_mach_o_dsym_for_uuid_p (dsym_bfd, uuid_cmd))
4656 return dsym_bfd;
4657
4658 bfd_close (dsym_bfd);
4659 if (base_dsym_bfd != dsym_bfd)
4660 bfd_close (base_dsym_bfd);
4661
4662 return NULL;
4663}
4664
4665/* Return a BFD created from a dSYM file for ABFD.
4666 The caller is responsible for closing the returned BFD object, its
4667 filename, and its my_archive if the returned BFD is in a fat dSYM. */
4668
4669static bfd *
4670bfd_mach_o_follow_dsym (bfd *abfd)
4671{
4672 char *dsym_filename;
4673 bfd_mach_o_uuid_command *uuid_cmd;
4674 bfd *dsym_bfd, *base_bfd = abfd;
4675 const char *base_basename;
4676
4677 if (abfd == NULL || bfd_get_flavour (abfd) != bfd_target_mach_o_flavour)
4678 return NULL;
4679
4680 if (abfd->my_archive)
4681 base_bfd = abfd->my_archive;
4682 /* BFD may have been opened from a stream. */
4683 if (base_bfd->filename == NULL)
4684 {
4685 bfd_set_error (bfd_error_invalid_operation);
4686 return NULL;
4687 }
4688 base_basename = lbasename (base_bfd->filename);
4689
4690 uuid_cmd = bfd_mach_o_lookup_uuid_command (abfd);
4691 if (uuid_cmd == NULL)
4692 return NULL;
4693
4694 /* TODO: We assume the DWARF file has the same as the binary's.
4695 It seems apple's GDB checks all files in the dSYM bundle directory.
4696 http://opensource.apple.com/source/gdb/gdb-1708/src/gdb/macosx/macosx-tdep.c
4697 */
4698 dsym_filename = (char *)bfd_malloc (strlen (base_bfd->filename)
4699 + strlen (dsym_subdir) + 1
4700 + strlen (base_basename) + 1);
4701 sprintf (dsym_filename, "%s%s/%s",
4702 base_bfd->filename, dsym_subdir, base_basename);
4703
4704 dsym_bfd = bfd_mach_o_find_dsym (dsym_filename, uuid_cmd,
4705 bfd_get_arch_info (abfd));
4706 if (dsym_bfd == NULL)
4707 free (dsym_filename);
4708
4709 return dsym_bfd;
4710}
4711
d9071b0c
TG
4712bfd_boolean
4713bfd_mach_o_find_nearest_line (bfd *abfd,
4714 asection *section,
4715 asymbol **symbols,
4716 bfd_vma offset,
4717 const char **filename_ptr,
4718 const char **functionname_ptr,
4719 unsigned int *line_ptr)
4720{
4721 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2ca7691a 4722 if (mdata == NULL)
d9071b0c 4723 return FALSE;
2ca7691a
TG
4724 switch (mdata->header.filetype)
4725 {
4726 case BFD_MACH_O_MH_OBJECT:
4727 break;
4728 case BFD_MACH_O_MH_EXECUTE:
4729 case BFD_MACH_O_MH_DYLIB:
4730 case BFD_MACH_O_MH_BUNDLE:
4731 case BFD_MACH_O_MH_KEXT_BUNDLE:
4732 if (mdata->dwarf2_find_line_info == NULL)
4733 {
4734 mdata->dsym_bfd = bfd_mach_o_follow_dsym (abfd);
4735 /* When we couldn't find dSYM for this binary, we look for
4736 the debug information in the binary itself. In this way,
4737 we won't try finding separated dSYM again because
4738 mdata->dwarf2_find_line_info will be filled. */
4739 if (! mdata->dsym_bfd)
4740 break;
4741 if (! _bfd_dwarf2_slurp_debug_info (abfd, mdata->dsym_bfd,
4742 dwarf_debug_sections, symbols,
4743 &mdata->dwarf2_find_line_info))
4744 return FALSE;
4745 }
4746 break;
4747 default:
4748 return FALSE;
4749 }
d9071b0c
TG
4750 if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections,
4751 section, symbols, offset,
4752 filename_ptr, functionname_ptr,
4753 line_ptr, 0,
4754 &mdata->dwarf2_find_line_info))
4755 return TRUE;
4756 return FALSE;
4757}
4758
4759bfd_boolean
4760bfd_mach_o_close_and_cleanup (bfd *abfd)
4761{
4762 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
4763 if (bfd_get_format (abfd) == bfd_object && mdata != NULL)
4434114c
TG
4764 {
4765 _bfd_dwarf2_cleanup_debug_info (abfd, &mdata->dwarf2_find_line_info);
4766 bfd_mach_o_free_cached_info (abfd);
2ca7691a
TG
4767 if (mdata->dsym_bfd != NULL)
4768 {
4769 bfd *fat_bfd = mdata->dsym_bfd->my_archive;
4770 char *dsym_filename = (char *)(fat_bfd
4771 ? fat_bfd->filename
4772 : mdata->dsym_bfd->filename);
4773 bfd_close (mdata->dsym_bfd);
4774 mdata->dsym_bfd = NULL;
4775 if (fat_bfd)
4776 bfd_close (fat_bfd);
4777 free (dsym_filename);
4778 }
4434114c 4779 }
dff55db0 4780
d9071b0c
TG
4781 return _bfd_generic_close_and_cleanup (abfd);
4782}
4783
dff55db0
TG
4784bfd_boolean bfd_mach_o_free_cached_info (bfd *abfd)
4785{
4786 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
4787 asection *asect;
4788 free (mdata->dyn_reloc_cache);
4789 mdata->dyn_reloc_cache = NULL;
4790 for (asect = abfd->sections; asect != NULL; asect = asect->next)
4791 {
4792 free (asect->relocation);
4793 asect->relocation = NULL;
4794 }
4795
4796 return TRUE;
4797}
4798
92bc0e80
TG
4799#define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
4800#define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
4801
4802#define bfd_mach_o_swap_reloc_in NULL
4803#define bfd_mach_o_swap_reloc_out NULL
b32e07d7 4804#define bfd_mach_o_print_thread NULL
a4551119 4805#define bfd_mach_o_tgt_seg_table NULL
ab76eeaf 4806#define bfd_mach_o_section_type_valid_for_tgt NULL
92bc0e80 4807
116c20d2
NC
4808#define TARGET_NAME mach_o_be_vec
4809#define TARGET_STRING "mach-o-be"
42fa0891 4810#define TARGET_ARCHITECTURE bfd_arch_unknown
116c20d2
NC
4811#define TARGET_BIG_ENDIAN 1
4812#define TARGET_ARCHIVE 0
b93a1992 4813#define TARGET_PRIORITY 1
3af9a47b
NC
4814#include "mach-o-target.c"
4815
4816#undef TARGET_NAME
4817#undef TARGET_STRING
42fa0891 4818#undef TARGET_ARCHITECTURE
3af9a47b
NC
4819#undef TARGET_BIG_ENDIAN
4820#undef TARGET_ARCHIVE
b93a1992 4821#undef TARGET_PRIORITY
3af9a47b 4822
116c20d2
NC
4823#define TARGET_NAME mach_o_le_vec
4824#define TARGET_STRING "mach-o-le"
42fa0891 4825#define TARGET_ARCHITECTURE bfd_arch_unknown
116c20d2
NC
4826#define TARGET_BIG_ENDIAN 0
4827#define TARGET_ARCHIVE 0
b93a1992 4828#define TARGET_PRIORITY 1
3af9a47b
NC
4829
4830#include "mach-o-target.c"
4831
4832#undef TARGET_NAME
4833#undef TARGET_STRING
42fa0891 4834#undef TARGET_ARCHITECTURE
3af9a47b
NC
4835#undef TARGET_BIG_ENDIAN
4836#undef TARGET_ARCHIVE
b93a1992 4837#undef TARGET_PRIORITY
3af9a47b 4838
8f95b6e4
TG
4839/* Not yet handled: creating an archive. */
4840#define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive
4841
4842/* Not used. */
4843#define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr
4844#define bfd_mach_o_write_ar_hdr _bfd_noarchive_write_ar_hdr
4845#define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap
4846#define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
4847#define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
4848#define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname
4849#define bfd_mach_o_write_armap _bfd_noarchive_write_armap
4850#define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index
15bbba8d 4851#define bfd_mach_o_generic_stat_arch_elt bfd_mach_o_fat_stat_arch_elt
8f95b6e4
TG
4852#define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
4853
116c20d2
NC
4854#define TARGET_NAME mach_o_fat_vec
4855#define TARGET_STRING "mach-o-fat"
42fa0891 4856#define TARGET_ARCHITECTURE bfd_arch_unknown
116c20d2
NC
4857#define TARGET_BIG_ENDIAN 1
4858#define TARGET_ARCHIVE 1
b93a1992 4859#define TARGET_PRIORITY 0
3af9a47b
NC
4860
4861#include "mach-o-target.c"
4862
4863#undef TARGET_NAME
4864#undef TARGET_STRING
42fa0891 4865#undef TARGET_ARCHITECTURE
3af9a47b
NC
4866#undef TARGET_BIG_ENDIAN
4867#undef TARGET_ARCHIVE
b93a1992 4868#undef TARGET_PRIORITY
This page took 0.820004 seconds and 4 git commands to generate.