set vma on mach-o sections.
[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",
124 SEC_READONLY | SEC_LOAD, BFD_MACH_O_S_COALESCED,
125 BFD_MACH_O_S_ATTR_LIVE_SUPPORT
126 | BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS
127 | BFD_MACH_O_S_ATTR_NO_TOC, 3},
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{
046b007d 1188 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
92bc0e80
TG
1189 unsigned int i;
1190 arelent **entries;
1191 asection *sec;
1192 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
1193
1194 sec = section->bfdsection;
1195 if (sec->reloc_count == 0)
1196 return TRUE;
1197
1198 if (bed->_bfd_mach_o_swap_reloc_out == NULL)
1199 return TRUE;
1200
1201 /* Allocate relocation room. */
1202 mdata->filelen = FILE_ALIGN(mdata->filelen, 2);
1203 section->nreloc = sec->reloc_count;
1204 sec->rel_filepos = mdata->filelen;
1205 section->reloff = sec->rel_filepos;
1206 mdata->filelen += sec->reloc_count * BFD_MACH_O_RELENT_SIZE;
1207
1208 if (bfd_seek (abfd, section->reloff, SEEK_SET) != 0)
1209 return FALSE;
1210
1211 /* Convert and write. */
1212 entries = section->bfdsection->orelocation;
1213 for (i = 0; i < section->nreloc; i++)
1214 {
1215 arelent *rel = entries[i];
46d1c23b 1216 struct mach_o_reloc_info_external raw;
92bc0e80
TG
1217 bfd_mach_o_reloc_info info, *pinfo = &info;
1218
1219 /* Convert relocation to an intermediate representation. */
1220 if (!(*bed->_bfd_mach_o_swap_reloc_out) (rel, pinfo))
1221 return FALSE;
1222
1223 /* Lower the relocation info. */
1224 if (pinfo->r_scattered)
1225 {
1226 unsigned long v;
1227
1228 v = BFD_MACH_O_SR_SCATTERED
1229 | (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0)
1230 | BFD_MACH_O_SET_SR_LENGTH(pinfo->r_length)
1231 | BFD_MACH_O_SET_SR_TYPE(pinfo->r_type)
1232 | BFD_MACH_O_SET_SR_ADDRESS(pinfo->r_address);
46d1c23b
TG
1233 /* Note: scattered relocs have field in reverse order... */
1234 bfd_put_32 (abfd, v, raw.r_address);
1235 bfd_put_32 (abfd, pinfo->r_value, raw.r_symbolnum);
92bc0e80
TG
1236 }
1237 else
1238 {
1239 unsigned long v;
1240
46d1c23b 1241 bfd_put_32 (abfd, pinfo->r_address, raw.r_address);
92bc0e80
TG
1242 v = BFD_MACH_O_SET_R_SYMBOLNUM (pinfo->r_value)
1243 | (pinfo->r_pcrel ? BFD_MACH_O_R_PCREL : 0)
1244 | BFD_MACH_O_SET_R_LENGTH (pinfo->r_length)
1245 | (pinfo->r_extern ? BFD_MACH_O_R_EXTERN : 0)
1246 | BFD_MACH_O_SET_R_TYPE (pinfo->r_type);
46d1c23b 1247 bfd_put_32 (abfd, v, raw.r_symbolnum);
92bc0e80
TG
1248 }
1249
46d1c23b 1250 if (bfd_bwrite (&raw, BFD_MACH_O_RELENT_SIZE, abfd)
92bc0e80
TG
1251 != BFD_MACH_O_RELENT_SIZE)
1252 return FALSE;
1253 }
1254 return TRUE;
1255}
1256
116c20d2 1257static int
ab273af8 1258bfd_mach_o_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
116c20d2 1259{
46d1c23b
TG
1260 struct mach_o_section_32_external raw;
1261
1262 memcpy (raw.sectname, section->sectname, 16);
72b5104c 1263 memcpy (raw.segname, section->segname, 16);
46d1c23b
TG
1264 bfd_h_put_32 (abfd, section->addr, raw.addr);
1265 bfd_h_put_32 (abfd, section->size, raw.size);
1266 bfd_h_put_32 (abfd, section->offset, raw.offset);
1267 bfd_h_put_32 (abfd, section->align, raw.align);
1268 bfd_h_put_32 (abfd, section->reloff, raw.reloff);
1269 bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
1270 bfd_h_put_32 (abfd, section->flags, raw.flags);
1271 bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
1272 bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
1273
1274 if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
92bc0e80 1275 != BFD_MACH_O_SECTION_SIZE)
116c20d2
NC
1276 return -1;
1277
1278 return 0;
1279}
1280
1281static int
ab273af8 1282bfd_mach_o_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
116c20d2 1283{
46d1c23b
TG
1284 struct mach_o_section_64_external raw;
1285
1286 memcpy (raw.sectname, section->sectname, 16);
1287 memcpy (raw.segname, section->segname, 16);
1288 bfd_h_put_64 (abfd, section->addr, raw.addr);
1289 bfd_h_put_64 (abfd, section->size, raw.size);
1290 bfd_h_put_32 (abfd, section->offset, raw.offset);
1291 bfd_h_put_32 (abfd, section->align, raw.align);
1292 bfd_h_put_32 (abfd, section->reloff, raw.reloff);
1293 bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
1294 bfd_h_put_32 (abfd, section->flags, raw.flags);
1295 bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
1296 bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
1297 bfd_h_put_32 (abfd, section->reserved3, raw.reserved3);
1298
1299 if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
92bc0e80 1300 != BFD_MACH_O_SECTION_64_SIZE)
116c20d2
NC
1301 return -1;
1302
1e8a024a
TG
1303 return 0;
1304}
1305
1306static int
ab273af8 1307bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 1308{
46d1c23b 1309 struct mach_o_segment_command_32_external raw;
1e8a024a 1310 bfd_mach_o_segment_command *seg = &command->command.segment;
f1bde64c 1311 bfd_mach_o_section *sec;
1e8a024a 1312
c2f09c75
TG
1313 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1314
f1bde64c
TG
1315 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1316 if (!bfd_mach_o_write_relocs (abfd, sec))
92bc0e80 1317 return -1;
c2f09c75 1318
46d1c23b
TG
1319 memcpy (raw.segname, seg->segname, 16);
1320 bfd_h_put_32 (abfd, seg->vmaddr, raw.vmaddr);
1321 bfd_h_put_32 (abfd, seg->vmsize, raw.vmsize);
1322 bfd_h_put_32 (abfd, seg->fileoff, raw.fileoff);
1323 bfd_h_put_32 (abfd, seg->filesize, raw.filesize);
1324 bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
1325 bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
1326 bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
1327 bfd_h_put_32 (abfd, seg->flags, raw.flags);
c2f09c75 1328
46d1c23b
TG
1329 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1330 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
c2f09c75 1331 return -1;
1e8a024a 1332
f1bde64c
TG
1333 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1334 if (bfd_mach_o_write_section_32 (abfd, sec))
92bc0e80 1335 return -1;
1e8a024a 1336
116c20d2
NC
1337 return 0;
1338}
1339
1e8a024a 1340static int
ab273af8 1341bfd_mach_o_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 1342{
46d1c23b 1343 struct mach_o_segment_command_64_external raw;
c2f09c75 1344 bfd_mach_o_segment_command *seg = &command->command.segment;
f1bde64c 1345 bfd_mach_o_section *sec;
c2f09c75
TG
1346
1347 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
1348
f1bde64c
TG
1349 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1350 if (!bfd_mach_o_write_relocs (abfd, sec))
92bc0e80 1351 return -1;
c2f09c75 1352
46d1c23b
TG
1353 memcpy (raw.segname, seg->segname, 16);
1354 bfd_h_put_64 (abfd, seg->vmaddr, raw.vmaddr);
1355 bfd_h_put_64 (abfd, seg->vmsize, raw.vmsize);
1356 bfd_h_put_64 (abfd, seg->fileoff, raw.fileoff);
1357 bfd_h_put_64 (abfd, seg->filesize, raw.filesize);
1358 bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
1359 bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
1360 bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
1361 bfd_h_put_32 (abfd, seg->flags, raw.flags);
1362
1363 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1364 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
c2f09c75
TG
1365 return -1;
1366
f1bde64c
TG
1367 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1368 if (bfd_mach_o_write_section_64 (abfd, sec))
92bc0e80 1369 return -1;
c2f09c75 1370
c2f09c75 1371 return 0;
1e8a024a
TG
1372}
1373
c2f09c75 1374static bfd_boolean
ab273af8 1375bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
116c20d2 1376{
046b007d 1377 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
116c20d2 1378 bfd_mach_o_symtab_command *sym = &command->command.symtab;
116c20d2 1379 unsigned long i;
c2f09c75 1380 unsigned int wide = bfd_mach_o_wide_p (abfd);
046b007d 1381 unsigned int symlen = wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
c2f09c75
TG
1382 struct bfd_strtab_hash *strtab;
1383 asymbol **symbols = bfd_get_outsymbols (abfd);
1384
1385 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1386
1387 /* Write the symbols first. */
92bc0e80
TG
1388 mdata->filelen = FILE_ALIGN(mdata->filelen, wide ? 3 : 2);
1389 sym->symoff = mdata->filelen;
c2f09c75
TG
1390 if (bfd_seek (abfd, sym->symoff, SEEK_SET) != 0)
1391 return FALSE;
1392
1393 sym->nsyms = bfd_get_symcount (abfd);
92bc0e80 1394 mdata->filelen += sym->nsyms * symlen;
c2f09c75
TG
1395
1396 strtab = _bfd_stringtab_init ();
1397 if (strtab == NULL)
1398 return FALSE;
116c20d2 1399
a4551119
TG
1400 if (sym->nsyms > 0)
1401 /* Although we don't strictly need to do this, for compatibility with
1402 Darwin system tools, actually output an empty string for the index
1403 0 entry. */
1404 _bfd_stringtab_add (strtab, "", TRUE, FALSE);
1405
116c20d2
NC
1406 for (i = 0; i < sym->nsyms; i++)
1407 {
91d6fa6a 1408 bfd_size_type str_index;
92bc0e80 1409 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
7f307238 1410
92bc0e80 1411 if (s->symbol.name == 0 || s->symbol.name[0] == '\0')
7f307238 1412 /* An index of 0 always means the empty string. */
91d6fa6a 1413 str_index = 0;
c2f09c75
TG
1414 else
1415 {
91d6fa6a 1416 str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
7f307238 1417
91d6fa6a 1418 if (str_index == (bfd_size_type) -1)
c2f09c75
TG
1419 goto err;
1420 }
46d1c23b 1421
c2f09c75 1422 if (wide)
46d1c23b
TG
1423 {
1424 struct mach_o_nlist_64_external raw;
1425
1426 bfd_h_put_32 (abfd, str_index, raw.n_strx);
1427 bfd_h_put_8 (abfd, s->n_type, raw.n_type);
1428 bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
1429 bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
1430 bfd_h_put_64 (abfd, s->symbol.section->vma + s->symbol.value,
1431 raw.n_value);
1432
1433 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1434 goto err;
1435 }
c2f09c75 1436 else
46d1c23b
TG
1437 {
1438 struct mach_o_nlist_external raw;
116c20d2 1439
46d1c23b
TG
1440 bfd_h_put_32 (abfd, str_index, raw.n_strx);
1441 bfd_h_put_8 (abfd, s->n_type, raw.n_type);
1442 bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
1443 bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
1444 bfd_h_put_32 (abfd, s->symbol.section->vma + s->symbol.value,
1445 raw.n_value);
1446
1447 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1448 goto err;
1449 }
116c20d2 1450 }
c2f09c75 1451 sym->strsize = _bfd_stringtab_size (strtab);
92bc0e80
TG
1452 sym->stroff = mdata->filelen;
1453 mdata->filelen += sym->strsize;
116c20d2 1454
c2f09c75
TG
1455 if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
1456 goto err;
1457 _bfd_stringtab_free (strtab);
116c20d2 1458
c2f09c75 1459 /* The command. */
46d1c23b
TG
1460 {
1461 struct mach_o_symtab_command_external raw;
116c20d2 1462
46d1c23b
TG
1463 bfd_h_put_32 (abfd, sym->symoff, raw.symoff);
1464 bfd_h_put_32 (abfd, sym->nsyms, raw.nsyms);
1465 bfd_h_put_32 (abfd, sym->stroff, raw.stroff);
1466 bfd_h_put_32 (abfd, sym->strsize, raw.strsize);
1467
1468 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1469 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1470 return FALSE;
1471 }
116c20d2 1472
c2f09c75 1473 return TRUE;
116c20d2 1474
c2f09c75
TG
1475 err:
1476 _bfd_stringtab_free (strtab);
1477 return FALSE;
116c20d2
NC
1478}
1479
7f307238
IS
1480/* Write a dysymtab command.
1481 TODO: Possibly coalesce writes of smaller objects. */
1482
1483static bfd_boolean
1484bfd_mach_o_write_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
1485{
1486 bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
1487
1488 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
1489
1490 if (cmd->nmodtab != 0)
1491 {
1492 unsigned int i;
1493
1494 if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0)
1495 return FALSE;
1496
1497 for (i = 0; i < cmd->nmodtab; i++)
1498 {
1499 bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
1500 unsigned int iinit;
1501 unsigned int ninit;
1502
1503 iinit = module->iinit & 0xffff;
1504 iinit |= ((module->iterm & 0xffff) << 16);
1505
1506 ninit = module->ninit & 0xffff;
1507 ninit |= ((module->nterm & 0xffff) << 16);
1508
1509 if (bfd_mach_o_wide_p (abfd))
1510 {
1511 struct mach_o_dylib_module_64_external w;
1512
1513 bfd_h_put_32 (abfd, module->module_name_idx, &w.module_name);
1514 bfd_h_put_32 (abfd, module->iextdefsym, &w.iextdefsym);
1515 bfd_h_put_32 (abfd, module->nextdefsym, &w.nextdefsym);
1516 bfd_h_put_32 (abfd, module->irefsym, &w.irefsym);
1517 bfd_h_put_32 (abfd, module->nrefsym, &w.nrefsym);
1518 bfd_h_put_32 (abfd, module->ilocalsym, &w.ilocalsym);
1519 bfd_h_put_32 (abfd, module->nlocalsym, &w.nlocalsym);
1520 bfd_h_put_32 (abfd, module->iextrel, &w.iextrel);
1521 bfd_h_put_32 (abfd, module->nextrel, &w.nextrel);
1522 bfd_h_put_32 (abfd, iinit, &w.iinit_iterm);
1523 bfd_h_put_32 (abfd, ninit, &w.ninit_nterm);
1524 bfd_h_put_64 (abfd, module->objc_module_info_addr,
1525 &w.objc_module_info_addr);
1526 bfd_h_put_32 (abfd, module->objc_module_info_size,
1527 &w.objc_module_info_size);
1528
1529 if (bfd_bwrite ((void *) &w, sizeof (w), abfd) != sizeof (w))
1530 return FALSE;
1531 }
1532 else
1533 {
1534 struct mach_o_dylib_module_external n;
1535
1536 bfd_h_put_32 (abfd, module->module_name_idx, &n.module_name);
1537 bfd_h_put_32 (abfd, module->iextdefsym, &n.iextdefsym);
1538 bfd_h_put_32 (abfd, module->nextdefsym, &n.nextdefsym);
1539 bfd_h_put_32 (abfd, module->irefsym, &n.irefsym);
1540 bfd_h_put_32 (abfd, module->nrefsym, &n.nrefsym);
1541 bfd_h_put_32 (abfd, module->ilocalsym, &n.ilocalsym);
1542 bfd_h_put_32 (abfd, module->nlocalsym, &n.nlocalsym);
1543 bfd_h_put_32 (abfd, module->iextrel, &n.iextrel);
1544 bfd_h_put_32 (abfd, module->nextrel, &n.nextrel);
1545 bfd_h_put_32 (abfd, iinit, &n.iinit_iterm);
1546 bfd_h_put_32 (abfd, ninit, &n.ninit_nterm);
1547 bfd_h_put_32 (abfd, module->objc_module_info_addr,
1548 &n.objc_module_info_addr);
1549 bfd_h_put_32 (abfd, module->objc_module_info_size,
1550 &n.objc_module_info_size);
1551
1552 if (bfd_bwrite ((void *) &n, sizeof (n), abfd) != sizeof (n))
1553 return FALSE;
1554 }
1555 }
1556 }
1557
1558 if (cmd->ntoc != 0)
1559 {
1560 unsigned int i;
1561
1562 if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
1563 return FALSE;
1564
1565 for (i = 0; i < cmd->ntoc; i++)
1566 {
1567 struct mach_o_dylib_table_of_contents_external raw;
1568 bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
1569
1570 bfd_h_put_32 (abfd, toc->symbol_index, &raw.symbol_index);
1571 bfd_h_put_32 (abfd, toc->module_index, &raw.module_index);
1572
1573 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1574 return FALSE;
1575 }
1576 }
1577
1578 if (cmd->nindirectsyms > 0)
1579 {
1580 unsigned int i;
1581
1582 if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
1583 return FALSE;
1584
1585 for (i = 0; i < cmd->nindirectsyms; ++i)
1586 {
1587 unsigned char raw[4];
1588
1589 bfd_h_put_32 (abfd, cmd->indirect_syms[i], &raw);
1590 if (bfd_bwrite (raw, sizeof (raw), abfd) != sizeof (raw))
1591 return FALSE;
1592 }
1593 }
1594
1595 if (cmd->nextrefsyms != 0)
1596 {
1597 unsigned int i;
1598
1599 if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
1600 return FALSE;
1601
1602 for (i = 0; i < cmd->nextrefsyms; i++)
1603 {
1604 unsigned long v;
1605 unsigned char raw[4];
1606 bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
1607
1608 /* Fields isym and flags are written as bit-fields, thus we need
1609 a specific processing for endianness. */
1610
1611 if (bfd_big_endian (abfd))
1612 {
1613 v = ((ref->isym & 0xffffff) << 8);
1614 v |= ref->flags & 0xff;
1615 }
1616 else
1617 {
1618 v = ref->isym & 0xffffff;
1619 v |= ((ref->flags & 0xff) << 24);
1620 }
1621
1622 bfd_h_put_32 (abfd, v, raw);
1623 if (bfd_bwrite (raw, sizeof (raw), abfd) != sizeof (raw))
1624 return FALSE;
1625 }
1626 }
1627
1628 /* The command. */
1629 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0)
1630 return FALSE;
1631 else
1632 {
1633 struct mach_o_dysymtab_command_external raw;
1634
1635 bfd_h_put_32 (abfd, cmd->ilocalsym, &raw.ilocalsym);
1636 bfd_h_put_32 (abfd, cmd->nlocalsym, &raw.nlocalsym);
1637 bfd_h_put_32 (abfd, cmd->iextdefsym, &raw.iextdefsym);
1638 bfd_h_put_32 (abfd, cmd->nextdefsym, &raw.nextdefsym);
1639 bfd_h_put_32 (abfd, cmd->iundefsym, &raw.iundefsym);
1640 bfd_h_put_32 (abfd, cmd->nundefsym, &raw.nundefsym);
1641 bfd_h_put_32 (abfd, cmd->tocoff, &raw.tocoff);
1642 bfd_h_put_32 (abfd, cmd->ntoc, &raw.ntoc);
1643 bfd_h_put_32 (abfd, cmd->modtaboff, &raw.modtaboff);
1644 bfd_h_put_32 (abfd, cmd->nmodtab, &raw.nmodtab);
1645 bfd_h_put_32 (abfd, cmd->extrefsymoff, &raw.extrefsymoff);
1646 bfd_h_put_32 (abfd, cmd->nextrefsyms, &raw.nextrefsyms);
1647 bfd_h_put_32 (abfd, cmd->indirectsymoff, &raw.indirectsymoff);
1648 bfd_h_put_32 (abfd, cmd->nindirectsyms, &raw.nindirectsyms);
1649 bfd_h_put_32 (abfd, cmd->extreloff, &raw.extreloff);
1650 bfd_h_put_32 (abfd, cmd->nextrel, &raw.nextrel);
1651 bfd_h_put_32 (abfd, cmd->locreloff, &raw.locreloff);
1652 bfd_h_put_32 (abfd, cmd->nlocrel, &raw.nlocrel);
1653
1654 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1655 return FALSE;
1656 }
1657
1658 return TRUE;
1659}
1660
1661static unsigned
b22161d6 1662bfd_mach_o_primary_symbol_sort_key (bfd_mach_o_asymbol *s)
7f307238 1663{
b22161d6 1664 unsigned mtyp = s->n_type & BFD_MACH_O_N_TYPE;
68588f95
IS
1665
1666 /* Just leave debug symbols where they are (pretend they are local, and
1667 then they will just be sorted on position). */
b22161d6 1668 if (s->n_type & BFD_MACH_O_N_STAB)
68588f95
IS
1669 return 0;
1670
7f307238 1671 /* Local (we should never see an undefined local AFAICT). */
b22161d6 1672 if (! (s->n_type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT)))
7f307238
IS
1673 return 0;
1674
1675 /* Common symbols look like undefined externs. */
68588f95 1676 if (mtyp == BFD_MACH_O_N_UNDF)
7f307238
IS
1677 return 2;
1678
b22161d6 1679 /* A defined non-local, non-debug symbol. */
7f307238
IS
1680 return 1;
1681}
1682
1683static int
1684bfd_mach_o_cf_symbols (const void *a, const void *b)
1685{
1686 bfd_mach_o_asymbol *sa = *(bfd_mach_o_asymbol **) a;
1687 bfd_mach_o_asymbol *sb = *(bfd_mach_o_asymbol **) b;
1688 unsigned int soa, sob;
1689
b22161d6
IS
1690 soa = bfd_mach_o_primary_symbol_sort_key (sa);
1691 sob = bfd_mach_o_primary_symbol_sort_key (sb);
7f307238
IS
1692 if (soa < sob)
1693 return -1;
1694
1695 if (soa > sob)
1696 return 1;
1697
68588f95 1698 /* If it's local or stab, just preserve the input order. */
7f307238
IS
1699 if (soa == 0)
1700 {
1701 if (sa->symbol.udata.i < sb->symbol.udata.i)
1702 return -1;
1703 if (sa->symbol.udata.i > sb->symbol.udata.i)
1704 return 1;
b22161d6
IS
1705
1706 /* This is probably an error. */
7f307238
IS
1707 return 0;
1708 }
1709
b22161d6
IS
1710 /* The second sort key is name. */
1711 return strcmp (sa->symbol.name, sb->symbol.name);
7f307238
IS
1712}
1713
1714/* Process the symbols.
1715
1716 This should be OK for single-module files - but it is not likely to work
1717 for multi-module shared libraries.
1718
1719 (a) If the application has not filled in the relevant mach-o fields, make
1720 an estimate.
1721
1722 (b) Order them, like this:
1723 ( i) local.
1724 (unsorted)
1725 ( ii) external defined
1726 (by name)
b22161d6 1727 (iii) external undefined/common
7f307238
IS
1728 (by name)
1729 ( iv) common
1730 (by name)
b22161d6 1731*/
92bc0e80
TG
1732
1733static bfd_boolean
b22161d6 1734bfd_mach_o_mangle_symbols (bfd *abfd)
92bc0e80
TG
1735{
1736 unsigned long i;
1737 asymbol **symbols = bfd_get_outsymbols (abfd);
1738
7f307238
IS
1739 if (symbols == NULL || bfd_get_symcount (abfd) == 0)
1740 return TRUE;
1741
92bc0e80
TG
1742 for (i = 0; i < bfd_get_symcount (abfd); i++)
1743 {
1744 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1745
b22161d6
IS
1746 /* We use this value, which is out-of-range as a symbol index, to signal
1747 that the mach-o-specific data are not filled in and need to be created
1748 from the bfd values. It is much preferable for the application to do
1749 this, since more meaningful diagnostics can be made that way. */
1750
1751 if (s->symbol.udata.i == SYM_MACHO_FIELDS_UNSET)
92bc0e80 1752 {
b22161d6
IS
1753 /* No symbol information has been set - therefore determine
1754 it from the bfd symbol flags/info. */
92bc0e80
TG
1755 if (s->symbol.section == bfd_abs_section_ptr)
1756 s->n_type = BFD_MACH_O_N_ABS;
1757 else if (s->symbol.section == bfd_und_section_ptr)
1758 {
1759 s->n_type = BFD_MACH_O_N_UNDF;
1760 if (s->symbol.flags & BSF_WEAK)
1761 s->n_desc |= BFD_MACH_O_N_WEAK_REF;
7f307238
IS
1762 /* mach-o automatically makes undefined symbols extern. */
1763 s->n_type |= BFD_MACH_O_N_EXT;
b22161d6 1764 s->symbol.flags |= BSF_GLOBAL;
92bc0e80
TG
1765 }
1766 else if (s->symbol.section == bfd_com_section_ptr)
b22161d6
IS
1767 {
1768 s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
1769 s->symbol.flags |= BSF_GLOBAL;
1770 }
92bc0e80
TG
1771 else
1772 s->n_type = BFD_MACH_O_N_SECT;
1773
1774 if (s->symbol.flags & BSF_GLOBAL)
1775 s->n_type |= BFD_MACH_O_N_EXT;
1776 }
1777
7f307238 1778 /* Put the section index in, where required. */
68588f95 1779 if ((s->symbol.section != bfd_abs_section_ptr
92bc0e80
TG
1780 && s->symbol.section != bfd_und_section_ptr
1781 && s->symbol.section != bfd_com_section_ptr)
68588f95
IS
1782 || ((s->n_type & BFD_MACH_O_N_STAB) != 0
1783 && s->symbol.name == NULL))
1784 s->n_sect = s->symbol.section->target_index;
92bc0e80 1785
b22161d6
IS
1786 /* Number to preserve order for local and debug syms. */
1787 s->symbol.udata.i = i;
7f307238
IS
1788 }
1789
b22161d6
IS
1790 /* Sort the symbols. */
1791 qsort ((void *) symbols, (size_t) bfd_get_symcount (abfd),
1792 sizeof (asymbol *), bfd_mach_o_cf_symbols);
7f307238 1793
b22161d6
IS
1794 for (i = 0; i < bfd_get_symcount (abfd); ++i)
1795 {
1796 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1797 s->symbol.udata.i = i; /* renumber. */
7f307238
IS
1798 }
1799
1800 return TRUE;
1801}
1802
1803/* We build a flat table of sections, which can be re-ordered if necessary.
1804 Fill in the section number and other mach-o-specific data. */
1805
1806static bfd_boolean
1807bfd_mach_o_mangle_sections (bfd *abfd, bfd_mach_o_data_struct *mdata)
1808{
1809 asection *sec;
1810 unsigned target_index;
1811 unsigned nsect;
1812
1813 nsect = bfd_count_sections (abfd);
1814
1815 /* Don't do it if it's already set - assume the application knows what it's
1816 doing. */
1817 if (mdata->nsects == nsect
1818 && (mdata->nsects == 0 || mdata->sections != NULL))
1819 return TRUE;
1820
1821 mdata->nsects = nsect;
1822 mdata->sections = bfd_alloc (abfd,
1823 mdata->nsects * sizeof (bfd_mach_o_section *));
1824 if (mdata->sections == NULL)
1825 return FALSE;
1826
1827 /* We need to check that this can be done... */
1828 if (nsect > 255)
1829 (*_bfd_error_handler) (_("mach-o: there are too many sections (%d)"
1830 " maximum is 255,\n"), nsect);
1831
1832 /* Create Mach-O sections.
1833 Section type, attribute and align should have been set when the
1834 section was created - either read in or specified. */
1835 target_index = 0;
1836 for (sec = abfd->sections; sec; sec = sec->next)
1837 {
1838 unsigned bfd_align = bfd_get_section_alignment (abfd, sec);
1839 bfd_mach_o_section *msect = bfd_mach_o_get_mach_o_section (sec);
1840
1841 mdata->sections[target_index] = msect;
1842
1843 msect->addr = bfd_get_section_vma (abfd, sec);
1844 msect->size = bfd_get_section_size (sec);
1845
1846 /* Use the largest alignment set, in case it was bumped after the
1847 section was created. */
1848 msect->align = msect->align > bfd_align ? msect->align : bfd_align;
1849
1850 msect->offset = 0;
1851 sec->target_index = ++target_index;
92bc0e80 1852 }
7f307238 1853
92bc0e80
TG
1854 return TRUE;
1855}
1856
154a1ee5 1857bfd_boolean
116c20d2 1858bfd_mach_o_write_contents (bfd *abfd)
3af9a47b
NC
1859{
1860 unsigned int i;
046b007d 1861 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 1862
7f307238 1863 /* Make the commands, if not already present. */
92bc0e80
TG
1864 if (mdata->header.ncmds == 0)
1865 if (!bfd_mach_o_build_commands (abfd))
1866 return FALSE;
1867
154a1ee5 1868 if (!bfd_mach_o_write_header (abfd, &mdata->header))
b34976b6 1869 return FALSE;
3af9a47b
NC
1870
1871 for (i = 0; i < mdata->header.ncmds; i++)
1872 {
46d1c23b 1873 struct mach_o_load_command_external raw;
3af9a47b
NC
1874 bfd_mach_o_load_command *cur = &mdata->commands[i];
1875 unsigned long typeflag;
1876
154a1ee5 1877 typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
3af9a47b 1878
46d1c23b
TG
1879 bfd_h_put_32 (abfd, typeflag, raw.cmd);
1880 bfd_h_put_32 (abfd, cur->len, raw.cmdsize);
3af9a47b 1881
c2f09c75 1882 if (bfd_seek (abfd, cur->offset, SEEK_SET) != 0
46d1c23b 1883 || bfd_bwrite (&raw, BFD_MACH_O_LC_SIZE, abfd) != 8)
b34976b6 1884 return FALSE;
3af9a47b
NC
1885
1886 switch (cur->type)
1887 {
1888 case BFD_MACH_O_LC_SEGMENT:
ab273af8 1889 if (bfd_mach_o_write_segment_32 (abfd, cur) != 0)
1e8a024a
TG
1890 return FALSE;
1891 break;
1892 case BFD_MACH_O_LC_SEGMENT_64:
ab273af8 1893 if (bfd_mach_o_write_segment_64 (abfd, cur) != 0)
b34976b6 1894 return FALSE;
3af9a47b
NC
1895 break;
1896 case BFD_MACH_O_LC_SYMTAB:
ab273af8 1897 if (!bfd_mach_o_write_symtab (abfd, cur))
b34976b6 1898 return FALSE;
3af9a47b 1899 break;
7f307238
IS
1900 case BFD_MACH_O_LC_DYSYMTAB:
1901 if (!bfd_mach_o_write_dysymtab (abfd, cur))
1902 return FALSE;
1903 break;
3af9a47b
NC
1904 case BFD_MACH_O_LC_SYMSEG:
1905 break;
1906 case BFD_MACH_O_LC_THREAD:
1907 case BFD_MACH_O_LC_UNIXTHREAD:
ab273af8 1908 if (bfd_mach_o_write_thread (abfd, cur) != 0)
b34976b6 1909 return FALSE;
3af9a47b
NC
1910 break;
1911 case BFD_MACH_O_LC_LOADFVMLIB:
1912 case BFD_MACH_O_LC_IDFVMLIB:
1913 case BFD_MACH_O_LC_IDENT:
1914 case BFD_MACH_O_LC_FVMFILE:
1915 case BFD_MACH_O_LC_PREPAGE:
3af9a47b
NC
1916 case BFD_MACH_O_LC_LOAD_DYLIB:
1917 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1918 case BFD_MACH_O_LC_ID_DYLIB:
046b007d 1919 case BFD_MACH_O_LC_REEXPORT_DYLIB:
73017762 1920 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
3af9a47b
NC
1921 case BFD_MACH_O_LC_LOAD_DYLINKER:
1922 case BFD_MACH_O_LC_ID_DYLINKER:
1923 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1924 case BFD_MACH_O_LC_ROUTINES:
1925 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1926 break;
1927 default:
4a97a0e5
AM
1928 (*_bfd_error_handler) (_("unable to write unknown load command 0x%lx"),
1929 (unsigned long) cur->type);
b34976b6 1930 return FALSE;
3af9a47b
NC
1931 }
1932 }
1933
b34976b6 1934 return TRUE;
3af9a47b
NC
1935}
1936
f1bde64c
TG
1937static void
1938bfd_mach_o_append_section_to_segment (bfd_mach_o_segment_command *seg,
1939 asection *sec)
1940{
1941 bfd_mach_o_section *s = (bfd_mach_o_section *)sec->used_by_bfd;
1942 if (seg->sect_head == NULL)
1943 seg->sect_head = s;
1944 else
1945 seg->sect_tail->next = s;
1946 seg->sect_tail = s;
1947}
1948
1949/* Create section Mach-O flags from BFD flags. */
1950
1951static void
1952bfd_mach_o_set_section_flags_from_bfd (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
1953{
1954 flagword bfd_flags;
1955 bfd_mach_o_section *s = bfd_mach_o_get_mach_o_section (sec);
1956
1957 /* Create default flags. */
1958 bfd_flags = bfd_get_section_flags (abfd, sec);
1959 if ((bfd_flags & SEC_CODE) == SEC_CODE)
1960 s->flags = BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS
1961 | BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS
1962 | BFD_MACH_O_S_REGULAR;
1963 else if ((bfd_flags & (SEC_ALLOC | SEC_LOAD)) == SEC_ALLOC)
1964 s->flags = BFD_MACH_O_S_ZEROFILL;
1965 else if (bfd_flags & SEC_DEBUGGING)
1966 s->flags = BFD_MACH_O_S_REGULAR | BFD_MACH_O_S_ATTR_DEBUG;
1967 else
1968 s->flags = BFD_MACH_O_S_REGULAR;
1969}
1970
7f307238
IS
1971/* Count the number of sections in the list for the segment named.
1972
1973 The special case of NULL or "" for the segment name is valid for
1974 an MH_OBJECT file and means 'all sections available'.
1975
1976 Requires that the sections table in mdata be filled in.
1977
1978 Returns the number of sections (0 is valid).
1979 Any number > 255 signals an invalid section count, although we will,
1980 perhaps, allow the file to be written (in line with Darwin tools up
1981 to XCode 4).
1982
1983 A section count of (unsigned long) -1 signals a definite error. */
1984
1985static unsigned long
1986bfd_mach_o_count_sections_for_seg (const char *segment,
1987 bfd_mach_o_data_struct *mdata)
1988{
1989 unsigned i,j;
1990 if (mdata == NULL || mdata->sections == NULL)
1991 return (unsigned long) -1;
1992
1993 /* The MH_OBJECT case, all sections are considered; Although nsects is
1994 is an unsigned long, the maximum valid section count is 255 and this
1995 will have been checked already by mangle_sections. */
1996 if (segment == NULL || segment[0] == '\0')
1997 return mdata->nsects;
1998
1999 /* Count the number of sections we see in this segment. */
2000 j = 0;
2001 for (i = 0; i < mdata->nsects; ++i)
2002 {
2003 bfd_mach_o_section *s = mdata->sections[i];
2004 if (strncmp (segment, s->segname, BFD_MACH_O_SEGNAME_SIZE) == 0)
2005 j++;
2006 }
2007 return j;
2008}
2009
2010static bfd_boolean
2011bfd_mach_o_build_seg_command (const char *segment,
2012 bfd_mach_o_data_struct *mdata,
2013 bfd_mach_o_segment_command *seg)
2014{
2015 unsigned i;
2016 int is_mho = (segment == NULL || segment[0] == '\0');
2017
2018 /* Fill segment command. */
2019 if (is_mho)
2020 memset (seg->segname, 0, sizeof (seg->segname));
2021 else
2022 strncpy (seg->segname, segment, sizeof (seg->segname));
2023
2024 /* TODO: fix this up for non-MH_OBJECT cases. */
2025 seg->vmaddr = 0;
e5081f2f 2026 seg->vmsize = 0;
7f307238
IS
2027
2028 seg->fileoff = mdata->filelen;
2029 seg->filesize = 0;
2030 seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
2031 | BFD_MACH_O_PROT_EXECUTE;
2032 seg->initprot = seg->maxprot;
2033 seg->flags = 0;
2034 seg->sect_head = NULL;
2035 seg->sect_tail = NULL;
2036
2037 /* Append sections to the segment. */
2038
2039 for (i = 0; i < mdata->nsects; ++i)
2040 {
2041 bfd_mach_o_section *s = mdata->sections[i];
2042 asection *sec = s->bfdsection;
2043
2044 /* If we're not making an MH_OBJECT, check whether this section is from
2045 our segment, and skip if not. Otherwise, just add all sections. */
2046 if (! is_mho
2047 && strncmp (segment, s->segname, BFD_MACH_O_SEGNAME_SIZE) != 0)
2048 continue;
2049
2050 bfd_mach_o_append_section_to_segment (seg, sec);
2051
e5081f2f
IS
2052 s->offset = 0;
2053 if (s->size > 0)
2054 {
2055 seg->vmsize = FILE_ALIGN (seg->vmsize, s->align);
2056 seg->vmsize += s->size;
2057 }
2058
2059 /* Zerofill sections have zero file size & offset,
2060 and are not written. */
2061 if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) == BFD_MACH_O_S_ZEROFILL
2062 || (s->flags & BFD_MACH_O_SECTION_TYPE_MASK)
2063 == BFD_MACH_O_S_GB_ZEROFILL)
2064 continue;
2065
2066 if (s->size > 0)
7f307238
IS
2067 {
2068 mdata->filelen = FILE_ALIGN (mdata->filelen, s->align);
2069 s->offset = mdata->filelen;
2070 }
2071
2072 sec->filepos = s->offset;
2073
2074 mdata->filelen += s->size;
2075 }
2076
2077 seg->filesize = mdata->filelen - seg->fileoff;
7f307238
IS
2078
2079 return TRUE;
2080}
2081
50d10658
IS
2082/* Count the number of indirect symbols in the image.
2083 Requires that the sections are in their final order. */
2084
2085static unsigned int
2086bfd_mach_o_count_indirect_symbols (bfd *abfd, bfd_mach_o_data_struct *mdata)
2087{
2088 unsigned int i;
2089 unsigned int nisyms = 0;
2090
2091 for (i = 0; i < mdata->nsects; ++i)
2092 {
2093 bfd_mach_o_section *sec = mdata->sections[i];
2094
2095 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
2096 {
2097 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
2098 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
2099 case BFD_MACH_O_S_SYMBOL_STUBS:
2100 nisyms += bfd_mach_o_section_get_nbr_indirect (abfd, sec);
2101 break;
2102 default:
2103 break;
2104 }
2105 }
2106 return nisyms;
2107}
2108
7f307238
IS
2109static bfd_boolean
2110bfd_mach_o_build_dysymtab_command (bfd *abfd,
2111 bfd_mach_o_data_struct *mdata,
2112 bfd_mach_o_load_command *cmd)
2113{
2114 bfd_mach_o_dysymtab_command *dsym = &cmd->command.dysymtab;
2115
2116 /* TODO:
2117 We are not going to try and fill these in yet and, moreover, we are
2118 going to bail if they are already set. */
2119 if (dsym->nmodtab != 0
2120 || dsym->ntoc != 0
2121 || dsym->nextrefsyms != 0)
2122 {
2123 (*_bfd_error_handler) (_("sorry: modtab, toc and extrefsyms are not yet"
2124 " implemented for dysymtab commands."));
2125 return FALSE;
2126 }
2127
2128 dsym->ilocalsym = 0;
7f307238 2129
b22161d6 2130 if (bfd_get_symcount (abfd) > 0)
7f307238 2131 {
b22161d6
IS
2132 asymbol **symbols = bfd_get_outsymbols (abfd);
2133 unsigned long i;
2134
2135 /* Count the number of each kind of symbol. */
2136 for (i = 0; i < bfd_get_symcount (abfd); ++i)
2137 {
2138 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
2139 if (s->n_type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT))
2140 break;
2141 }
2142 dsym->nlocalsym = i;
2143 dsym->iextdefsym = i;
2144 for (; i < bfd_get_symcount (abfd); ++i)
2145 {
2146 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
2147 if ((s->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_UNDF)
2148 break;
2149 }
2150 dsym->nextdefsym = i - dsym->nlocalsym;
2151 dsym->iundefsym = dsym->nextdefsym + dsym->iextdefsym;
2152 dsym->nundefsym = bfd_get_symcount (abfd)
2153 - dsym->nlocalsym
2154 - dsym->nextdefsym;
2155 }
2156 else
2157 {
2158 dsym->nlocalsym = 0;
2159 dsym->iextdefsym = 0;
2160 dsym->nextdefsym = 0;
2161 dsym->iundefsym = 0;
2162 dsym->nundefsym = 0;
2163 }
2164
50d10658 2165 dsym->nindirectsyms = bfd_mach_o_count_indirect_symbols (abfd, mdata);
b22161d6
IS
2166 if (dsym->nindirectsyms > 0)
2167 {
2168 unsigned i;
50d10658 2169 unsigned n;
7f307238
IS
2170
2171 mdata->filelen = FILE_ALIGN (mdata->filelen, 2);
2172 dsym->indirectsymoff = mdata->filelen;
b22161d6 2173 mdata->filelen += dsym->nindirectsyms * 4;
7f307238 2174
b22161d6 2175 dsym->indirect_syms = bfd_zalloc (abfd, dsym->nindirectsyms * 4);
7f307238
IS
2176 if (dsym->indirect_syms == NULL)
2177 return FALSE;
50d10658
IS
2178
2179 n = 0;
2180 for (i = 0; i < mdata->nsects; ++i)
7f307238 2181 {
50d10658
IS
2182 bfd_mach_o_section *sec = mdata->sections[i];
2183
2184 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
2185 {
2186 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
2187 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
2188 case BFD_MACH_O_S_SYMBOL_STUBS:
2189 {
2190 unsigned j, num;
2191 bfd_mach_o_asymbol **isyms = sec->indirect_syms;
2192
2193 num = bfd_mach_o_section_get_nbr_indirect (abfd, sec);
2194 if (isyms == NULL || num == 0)
2195 break;
2196 /* Record the starting index in the reserved1 field. */
2197 sec->reserved1 = n;
2198 for (j = 0; j < num; j++, n++)
2199 {
2200 if (isyms[j] == NULL)
2201 dsym->indirect_syms[n] = BFD_MACH_O_INDIRECT_SYM_LOCAL;
2202 else
2203 dsym->indirect_syms[n] = isyms[j]->symbol.udata.i;
2204 }
2205 }
2206 break;
2207 default:
2208 break;
2209 }
7f307238
IS
2210 }
2211 }
2212
2213 return TRUE;
2214}
2215
2216/* Build Mach-O load commands (currently assuming an MH_OBJECT file).
2217 TODO: Other file formats, rebuilding symtab/dysymtab commands for strip
2218 and copy functionality. */
154a1ee5
TG
2219
2220bfd_boolean
2221bfd_mach_o_build_commands (bfd *abfd)
2222{
046b007d 2223 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
bbd56171
IS
2224 unsigned wide = mach_o_wide_p (&mdata->header);
2225 int segcmd_idx = -1;
2226 int symtab_idx = -1;
2227 int dysymtab_idx = -1;
2228 unsigned long base_offset = 0;
154a1ee5 2229
7f307238 2230 /* Return now if commands are already present. */
154a1ee5
TG
2231 if (mdata->header.ncmds)
2232 return FALSE;
2233
7f307238 2234 /* Fill in the file type, if not already set. */
154a1ee5 2235
7f307238 2236 if (mdata->header.filetype == 0)
154a1ee5 2237 {
7f307238
IS
2238 if (abfd->flags & EXEC_P)
2239 mdata->header.filetype = BFD_MACH_O_MH_EXECUTE;
2240 else if (abfd->flags & DYNAMIC)
2241 mdata->header.filetype = BFD_MACH_O_MH_DYLIB;
2242 else
2243 mdata->header.filetype = BFD_MACH_O_MH_OBJECT;
154a1ee5 2244 }
7f307238
IS
2245
2246 /* If hasn't already been done, flatten sections list, and sort
2247 if/when required. Must be done before the symbol table is adjusted,
2248 since that depends on properly numbered sections. */
2249 if (mdata->nsects == 0 || mdata->sections == NULL)
2250 if (! bfd_mach_o_mangle_sections (abfd, mdata))
2251 return FALSE;
2252
2253 /* Order the symbol table, fill-in/check mach-o specific fields and
2254 partition out any indirect symbols. */
b22161d6 2255 if (!bfd_mach_o_mangle_symbols (abfd))
7f307238
IS
2256 return FALSE;
2257
bbd56171
IS
2258 /* Very simple command set (only really applicable to MH_OBJECTs):
2259 All the commands are optional - present only when there is suitable data.
2260 (i.e. it is valid to have an empty file)
2261
2262 a command (segment) to contain all the sections,
2263 command for the symbol table,
2264 a command for the dysymtab.
2265
2266 ??? maybe we should assert that this is an MH_OBJECT? */
2267
7f307238 2268 if (mdata->nsects > 0)
154a1ee5 2269 {
bbd56171 2270 segcmd_idx = 0;
7f307238 2271 mdata->header.ncmds = 1;
154a1ee5 2272 }
154a1ee5 2273
7f307238 2274 if (bfd_get_symcount (abfd) > 0)
bbd56171
IS
2275 {
2276 mdata->header.ncmds++;
2277 symtab_idx = segcmd_idx + 1; /* 0 if the seg command is absent. */
2278 }
c2f09c75 2279
bbd56171
IS
2280 /* FIXME:
2281 This is a rather crude test for whether we should build a dysymtab. */
2282 if (bfd_mach_o_should_emit_dysymtab ()
2283 && bfd_get_symcount (abfd))
2284 {
2285 mdata->header.ncmds++;
2286 /* If there should be a case where a dysymtab could be emitted without
2287 a symtab (seems improbable), this would need amending. */
2288 dysymtab_idx = symtab_idx + 1;
2289 }
154a1ee5 2290
bbd56171
IS
2291 if (wide)
2292 base_offset = BFD_MACH_O_HEADER_64_SIZE;
2293 else
2294 base_offset = BFD_MACH_O_HEADER_SIZE;
c2f09c75 2295
bbd56171
IS
2296 /* Well, we must have a header, at least. */
2297 mdata->filelen = base_offset;
f1bde64c 2298
bbd56171 2299 /* A bit unusual, but no content is valid;
7f307238
IS
2300 as -n empty.s -o empty.o */
2301 if (mdata->header.ncmds == 0)
2302 return TRUE;
f1bde64c 2303
7f307238
IS
2304 mdata->commands = bfd_zalloc (abfd, mdata->header.ncmds
2305 * sizeof (bfd_mach_o_load_command));
2306 if (mdata->commands == NULL)
2307 return FALSE;
2308
bbd56171 2309 if (segcmd_idx >= 0)
7f307238 2310 {
bbd56171
IS
2311 bfd_mach_o_load_command *cmd = &mdata->commands[segcmd_idx];
2312 bfd_mach_o_segment_command *seg = &cmd->command.segment;
7f307238
IS
2313
2314 /* Count the segctions in the special blank segment used for MH_OBJECT. */
2315 seg->nsects = bfd_mach_o_count_sections_for_seg (NULL, mdata);
2316 if (seg->nsects == (unsigned long) -1)
2317 return FALSE;
2318
2319 /* Init segment command. */
bbd56171 2320 cmd->offset = base_offset;
7f307238
IS
2321 if (wide)
2322 {
2323 cmd->type = BFD_MACH_O_LC_SEGMENT_64;
7f307238
IS
2324 cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
2325 + BFD_MACH_O_SECTION_64_SIZE * seg->nsects;
2326 }
92bc0e80 2327 else
7f307238
IS
2328 {
2329 cmd->type = BFD_MACH_O_LC_SEGMENT;
7f307238
IS
2330 cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
2331 + BFD_MACH_O_SECTION_SIZE * seg->nsects;
2332 }
bbd56171 2333
7f307238
IS
2334 cmd->type_required = FALSE;
2335 mdata->header.sizeofcmds = cmd->len;
bbd56171 2336 mdata->filelen += cmd->len;
7f307238 2337 }
f1bde64c 2338
bbd56171 2339 if (symtab_idx >= 0)
7f307238
IS
2340 {
2341 /* Init symtab command. */
bbd56171 2342 bfd_mach_o_load_command *cmd = &mdata->commands[symtab_idx];
7f307238 2343
bbd56171
IS
2344 cmd->type = BFD_MACH_O_LC_SYMTAB;
2345 cmd->offset = base_offset;
2346 if (segcmd_idx >= 0)
2347 cmd->offset += mdata->commands[segcmd_idx].len;
2348
2349 cmd->len = sizeof (struct mach_o_symtab_command_external)
2350 + BFD_MACH_O_LC_SIZE;
2351 cmd->type_required = FALSE;
2352 mdata->header.sizeofcmds += cmd->len;
2353 mdata->filelen += cmd->len;
7f307238 2354 }
154a1ee5 2355
bbd56171
IS
2356 /* If required, setup symtab command, see comment above about the quality
2357 of this test. */
2358 if (dysymtab_idx >= 0)
7f307238 2359 {
bbd56171
IS
2360 bfd_mach_o_load_command *cmd = &mdata->commands[dysymtab_idx];
2361
7f307238 2362 cmd->type = BFD_MACH_O_LC_DYSYMTAB;
bbd56171
IS
2363 if (symtab_idx >= 0)
2364 cmd->offset = mdata->commands[symtab_idx].offset
2365 + mdata->commands[symtab_idx].len;
2366 else if (segcmd_idx >= 0)
2367 cmd->offset = mdata->commands[segcmd_idx].offset
2368 + mdata->commands[segcmd_idx].len;
2369 else
2370 cmd->offset = base_offset;
2371
7f307238 2372 cmd->type_required = FALSE;
bbd56171
IS
2373 cmd->len = sizeof (struct mach_o_dysymtab_command_external)
2374 + BFD_MACH_O_LC_SIZE;
7f307238
IS
2375
2376 mdata->header.sizeofcmds += cmd->len;
2377 mdata->filelen += cmd->len;
154a1ee5 2378 }
154a1ee5 2379
7f307238
IS
2380 /* So, now we have sized the commands and the filelen set to that.
2381 Now we can build the segment command and set the section file offsets. */
bbd56171
IS
2382 if (segcmd_idx >= 0
2383 && ! bfd_mach_o_build_seg_command
2384 (NULL, mdata, &mdata->commands[segcmd_idx].command.segment))
7f307238
IS
2385 return FALSE;
2386
2387 /* If we're doing a dysymtab, cmd points to its load command. */
bbd56171 2388 if (dysymtab_idx >= 0
7f307238 2389 && ! bfd_mach_o_build_dysymtab_command (abfd, mdata,
bbd56171 2390 &mdata->commands[dysymtab_idx]))
7f307238
IS
2391 return FALSE;
2392
2393 /* The symtab command is filled in when the symtab is written. */
154a1ee5
TG
2394 return TRUE;
2395}
2396
2397/* Set the contents of a section. */
2398
2399bfd_boolean
2400bfd_mach_o_set_section_contents (bfd *abfd,
2401 asection *section,
2402 const void * location,
2403 file_ptr offset,
2404 bfd_size_type count)
2405{
2406 file_ptr pos;
2407
7f307238
IS
2408 /* Trying to write the first section contents will trigger the creation of
2409 the load commands if they are not already present. */
154a1ee5
TG
2410 if (! abfd->output_has_begun && ! bfd_mach_o_build_commands (abfd))
2411 return FALSE;
2412
2413 if (count == 0)
2414 return TRUE;
2415
2416 pos = section->filepos + offset;
2417 if (bfd_seek (abfd, pos, SEEK_SET) != 0
2418 || bfd_bwrite (location, count, abfd) != count)
2419 return FALSE;
2420
2421 return TRUE;
2422}
2423
2424int
116c20d2 2425bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
a6b96beb 2426 struct bfd_link_info *info ATTRIBUTE_UNUSED)
3af9a47b
NC
2427{
2428 return 0;
2429}
2430
2431/* Make an empty symbol. This is required only because
2432 bfd_make_section_anyway wants to create a symbol for the section. */
2433
154a1ee5 2434asymbol *
116c20d2 2435bfd_mach_o_make_empty_symbol (bfd *abfd)
3af9a47b 2436{
d3ce72d0
NC
2437 asymbol *new_symbol;
2438
2439 new_symbol = bfd_zalloc (abfd, sizeof (bfd_mach_o_asymbol));
2440 if (new_symbol == NULL)
2441 return new_symbol;
2442 new_symbol->the_bfd = abfd;
b22161d6 2443 new_symbol->udata.i = SYM_MACHO_FIELDS_UNSET;
d3ce72d0 2444 return new_symbol;
3af9a47b
NC
2445}
2446
154a1ee5 2447static bfd_boolean
116c20d2 2448bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
3af9a47b 2449{
46d1c23b 2450 struct mach_o_header_external raw;
1e8a024a 2451 unsigned int size;
edeb6e24 2452 bfd_vma (*get32) (const void *) = NULL;
3af9a47b 2453
1e8a024a 2454 /* Just read the magic number. */
c2f09c75 2455 if (bfd_seek (abfd, 0, SEEK_SET) != 0
46d1c23b 2456 || bfd_bread (raw.magic, sizeof (raw.magic), abfd) != 4)
154a1ee5 2457 return FALSE;
3af9a47b 2458
46d1c23b 2459 if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
3af9a47b
NC
2460 {
2461 header->byteorder = BFD_ENDIAN_BIG;
154a1ee5 2462 header->magic = BFD_MACH_O_MH_MAGIC;
1e8a024a 2463 header->version = 1;
3af9a47b
NC
2464 get32 = bfd_getb32;
2465 }
46d1c23b 2466 else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
3af9a47b 2467 {
a95a4550 2468 header->byteorder = BFD_ENDIAN_LITTLE;
154a1ee5 2469 header->magic = BFD_MACH_O_MH_MAGIC;
1e8a024a
TG
2470 header->version = 1;
2471 get32 = bfd_getl32;
2472 }
46d1c23b 2473 else if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
1e8a024a
TG
2474 {
2475 header->byteorder = BFD_ENDIAN_BIG;
154a1ee5 2476 header->magic = BFD_MACH_O_MH_MAGIC_64;
1e8a024a
TG
2477 header->version = 2;
2478 get32 = bfd_getb32;
2479 }
46d1c23b 2480 else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
1e8a024a
TG
2481 {
2482 header->byteorder = BFD_ENDIAN_LITTLE;
154a1ee5 2483 header->magic = BFD_MACH_O_MH_MAGIC_64;
1e8a024a 2484 header->version = 2;
3af9a47b
NC
2485 get32 = bfd_getl32;
2486 }
2487 else
2488 {
2489 header->byteorder = BFD_ENDIAN_UNKNOWN;
154a1ee5 2490 return FALSE;
3af9a47b 2491 }
a95a4550 2492
1e8a024a 2493 /* Once the size of the header is known, read the full header. */
c2f09c75 2494 size = mach_o_wide_p (header) ?
154a1ee5 2495 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
1e8a024a 2496
c2f09c75 2497 if (bfd_seek (abfd, 0, SEEK_SET) != 0
46d1c23b 2498 || bfd_bread (&raw, size, abfd) != size)
154a1ee5 2499 return FALSE;
1e8a024a 2500
46d1c23b
TG
2501 header->cputype = (*get32) (raw.cputype);
2502 header->cpusubtype = (*get32) (raw.cpusubtype);
2503 header->filetype = (*get32) (raw.filetype);
2504 header->ncmds = (*get32) (raw.ncmds);
2505 header->sizeofcmds = (*get32) (raw.sizeofcmds);
2506 header->flags = (*get32) (raw.flags);
3af9a47b 2507
c2f09c75 2508 if (mach_o_wide_p (header))
46d1c23b 2509 header->reserved = (*get32) (raw.reserved);
1e8a024a 2510
154a1ee5 2511 return TRUE;
3af9a47b
NC
2512}
2513
f1bde64c
TG
2514bfd_boolean
2515bfd_mach_o_new_section_hook (bfd *abfd, asection *sec)
2516{
2517 bfd_mach_o_section *s;
a4551119 2518 unsigned bfdalign = bfd_get_section_alignment (abfd, sec);
f1bde64c
TG
2519
2520 s = bfd_mach_o_get_mach_o_section (sec);
2521 if (s == NULL)
2522 {
2523 flagword bfd_flags;
a4551119 2524 static const mach_o_section_name_xlat * xlat;
f1bde64c
TG
2525
2526 s = (bfd_mach_o_section *) bfd_zalloc (abfd, sizeof (*s));
2527 if (s == NULL)
2528 return FALSE;
2529 sec->used_by_bfd = s;
2530 s->bfdsection = sec;
2531
a4551119
TG
2532 /* Create the Darwin seg/sect name pair from the bfd name.
2533 If this is a canonical name for which a specific paiting exists
2534 there will also be defined flags, type, attribute and alignment
2535 values. */
2536 xlat = bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, s);
2537 if (xlat != NULL)
2538 {
2539 s->flags = xlat->macho_sectype | xlat->macho_secattr;
2540 s->align = xlat->sectalign > bfdalign ? xlat->sectalign
2541 : bfdalign;
2542 bfd_set_section_alignment (abfd, sec, s->align);
2543 bfd_flags = bfd_get_section_flags (abfd, sec);
2544 if (bfd_flags == SEC_NO_FLAGS)
2545 bfd_set_section_flags (abfd, sec, xlat->bfd_flags);
2546 }
f1bde64c 2547 else
a4551119
TG
2548 /* Create default flags. */
2549 bfd_mach_o_set_section_flags_from_bfd (abfd, sec);
f1bde64c
TG
2550 }
2551
2552 return _bfd_generic_new_section_hook (abfd, sec);
2553}
2554
2555static void
2556bfd_mach_o_init_section_from_mach_o (bfd *abfd, asection *sec,
2557 unsigned long prot)
3af9a47b 2558{
117ed4f8 2559 flagword flags;
f1bde64c 2560 bfd_mach_o_section *section;
3af9a47b 2561
f1bde64c
TG
2562 flags = bfd_get_section_flags (abfd, sec);
2563 section = bfd_mach_o_get_mach_o_section (sec);
3af9a47b 2564
a4551119
TG
2565 /* TODO: see if we should use the xlat system for doing this by
2566 preference and fall back to this for unknown sections. */
2567
8462aec7 2568 if (flags == SEC_NO_FLAGS)
ef17cb22 2569 {
8462aec7
TG
2570 /* Try to guess flags. */
2571 if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
2572 flags = SEC_DEBUGGING;
2573 else
2574 {
2575 flags = SEC_ALLOC;
2576 if ((section->flags & BFD_MACH_O_SECTION_TYPE_MASK)
2577 != BFD_MACH_O_S_ZEROFILL)
2578 {
2579 flags |= SEC_LOAD;
2580 if (prot & BFD_MACH_O_PROT_EXECUTE)
2581 flags |= SEC_CODE;
2582 if (prot & BFD_MACH_O_PROT_WRITE)
2583 flags |= SEC_DATA;
2584 else if (prot & BFD_MACH_O_PROT_READ)
2585 flags |= SEC_READONLY;
2586 }
2587 }
ef17cb22 2588 }
15e1c58a
TG
2589 else
2590 {
8462aec7
TG
2591 if ((flags & SEC_DEBUGGING) == 0)
2592 flags |= SEC_ALLOC;
15e1c58a 2593 }
8462aec7
TG
2594
2595 if (section->offset != 0)
2596 flags |= SEC_HAS_CONTENTS;
92bc0e80
TG
2597 if (section->nreloc != 0)
2598 flags |= SEC_RELOC;
2599
f1bde64c
TG
2600 bfd_set_section_flags (abfd, sec, flags);
2601
2602 sec->vma = section->addr;
2603 sec->lma = section->addr;
2604 sec->size = section->size;
2605 sec->filepos = section->offset;
2606 sec->alignment_power = section->align;
2607 sec->segment_mark = 0;
2608 sec->reloc_count = section->nreloc;
2609 sec->rel_filepos = section->reloff;
2610}
2611
2612static asection *
2613bfd_mach_o_make_bfd_section (bfd *abfd,
2614 const unsigned char *segname,
2615 const unsigned char *sectname)
2616{
2617 const char *sname;
2618 flagword flags;
a95a4550 2619
f1bde64c
TG
2620 bfd_mach_o_convert_section_name_to_bfd
2621 (abfd, (const char *)segname, (const char *)sectname, &sname, &flags);
2622 if (sname == NULL)
2623 return NULL;
3af9a47b 2624
f1bde64c 2625 return bfd_make_section_anyway_with_flags (abfd, sname, flags);
3af9a47b
NC
2626}
2627
f1bde64c 2628static asection *
ab273af8 2629bfd_mach_o_read_section_32 (bfd *abfd,
ab273af8
TG
2630 unsigned int offset,
2631 unsigned long prot)
3af9a47b 2632{
46d1c23b 2633 struct mach_o_section_32_external raw;
f1bde64c
TG
2634 asection *sec;
2635 bfd_mach_o_section *section;
3af9a47b 2636
c2f09c75 2637 if (bfd_seek (abfd, offset, SEEK_SET) != 0
46d1c23b 2638 || (bfd_bread (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
c2f09c75 2639 != BFD_MACH_O_SECTION_SIZE))
f1bde64c 2640 return NULL;
a95a4550 2641
5a5cbf72 2642 sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
f1bde64c
TG
2643 if (sec == NULL)
2644 return NULL;
2645
2646 section = bfd_mach_o_get_mach_o_section (sec);
2647 memcpy (section->segname, raw.segname, sizeof (raw.segname));
2648 section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
2649 memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
69499dca 2650 section->sectname[BFD_MACH_O_SECTNAME_SIZE] = 0;
46d1c23b
TG
2651 section->addr = bfd_h_get_32 (abfd, raw.addr);
2652 section->size = bfd_h_get_32 (abfd, raw.size);
2653 section->offset = bfd_h_get_32 (abfd, raw.offset);
2654 section->align = bfd_h_get_32 (abfd, raw.align);
2655 section->reloff = bfd_h_get_32 (abfd, raw.reloff);
2656 section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
2657 section->flags = bfd_h_get_32 (abfd, raw.flags);
2658 section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
2659 section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
1e8a024a 2660 section->reserved3 = 0;
1e8a024a 2661
f1bde64c 2662 bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
1e8a024a 2663
f1bde64c 2664 return sec;
1e8a024a
TG
2665}
2666
f1bde64c 2667static asection *
ab273af8 2668bfd_mach_o_read_section_64 (bfd *abfd,
ab273af8
TG
2669 unsigned int offset,
2670 unsigned long prot)
1e8a024a 2671{
46d1c23b 2672 struct mach_o_section_64_external raw;
f1bde64c
TG
2673 asection *sec;
2674 bfd_mach_o_section *section;
1e8a024a 2675
c2f09c75 2676 if (bfd_seek (abfd, offset, SEEK_SET) != 0
46d1c23b 2677 || (bfd_bread (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
c2f09c75 2678 != BFD_MACH_O_SECTION_64_SIZE))
f1bde64c
TG
2679 return NULL;
2680
5a5cbf72 2681 sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
f1bde64c
TG
2682 if (sec == NULL)
2683 return NULL;
1e8a024a 2684
f1bde64c
TG
2685 section = bfd_mach_o_get_mach_o_section (sec);
2686 memcpy (section->segname, raw.segname, sizeof (raw.segname));
2687 section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
2688 memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
69499dca 2689 section->sectname[BFD_MACH_O_SECTNAME_SIZE] = 0;
46d1c23b
TG
2690 section->addr = bfd_h_get_64 (abfd, raw.addr);
2691 section->size = bfd_h_get_64 (abfd, raw.size);
2692 section->offset = bfd_h_get_32 (abfd, raw.offset);
2693 section->align = bfd_h_get_32 (abfd, raw.align);
2694 section->reloff = bfd_h_get_32 (abfd, raw.reloff);
2695 section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
2696 section->flags = bfd_h_get_32 (abfd, raw.flags);
2697 section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
2698 section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
2699 section->reserved3 = bfd_h_get_32 (abfd, raw.reserved3);
3af9a47b 2700
f1bde64c 2701 bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
3af9a47b 2702
f1bde64c 2703 return sec;
3af9a47b
NC
2704}
2705
f1bde64c 2706static asection *
ab273af8 2707bfd_mach_o_read_section (bfd *abfd,
ab273af8
TG
2708 unsigned int offset,
2709 unsigned long prot,
2710 unsigned int wide)
1e8a024a
TG
2711{
2712 if (wide)
f1bde64c 2713 return bfd_mach_o_read_section_64 (abfd, offset, prot);
1e8a024a 2714 else
f1bde64c 2715 return bfd_mach_o_read_section_32 (abfd, offset, prot);
1e8a024a
TG
2716}
2717
afbb9e17 2718static bfd_boolean
ab273af8
TG
2719bfd_mach_o_read_symtab_symbol (bfd *abfd,
2720 bfd_mach_o_symtab_command *sym,
2721 bfd_mach_o_asymbol *s,
2722 unsigned long i)
3af9a47b 2723{
046b007d 2724 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
c2f09c75 2725 unsigned int wide = mach_o_wide_p (&mdata->header);
046b007d
TG
2726 unsigned int symwidth =
2727 wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
92bc0e80 2728 unsigned int symoff = sym->symoff + (i * symwidth);
46d1c23b 2729 struct mach_o_nlist_64_external raw;
3af9a47b
NC
2730 unsigned char type = -1;
2731 unsigned char section = -1;
2732 short desc = -1;
1e8a024a 2733 symvalue value = -1;
3af9a47b
NC
2734 unsigned long stroff = -1;
2735 unsigned int symtype = -1;
2736
2737 BFD_ASSERT (sym->strtab != NULL);
2738
c2f09c75 2739 if (bfd_seek (abfd, symoff, SEEK_SET) != 0
46d1c23b 2740 || bfd_bread (&raw, symwidth, abfd) != symwidth)
3af9a47b 2741 {
46d1c23b
TG
2742 (*_bfd_error_handler)
2743 (_("bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"),
2744 symwidth, (unsigned long) symoff);
afbb9e17 2745 return FALSE;
3af9a47b
NC
2746 }
2747
46d1c23b
TG
2748 stroff = bfd_h_get_32 (abfd, raw.n_strx);
2749 type = bfd_h_get_8 (abfd, raw.n_type);
c2f09c75 2750 symtype = type & BFD_MACH_O_N_TYPE;
46d1c23b
TG
2751 section = bfd_h_get_8 (abfd, raw.n_sect);
2752 desc = bfd_h_get_16 (abfd, raw.n_desc);
1e8a024a 2753 if (wide)
46d1c23b 2754 value = bfd_h_get_64 (abfd, raw.n_value);
1e8a024a 2755 else
46d1c23b 2756 value = bfd_h_get_32 (abfd, raw.n_value);
3af9a47b
NC
2757
2758 if (stroff >= sym->strsize)
2759 {
46d1c23b
TG
2760 (*_bfd_error_handler)
2761 (_("bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"),
2762 (unsigned long) stroff,
2763 (unsigned long) sym->strsize);
afbb9e17 2764 return FALSE;
3af9a47b
NC
2765 }
2766
92bc0e80
TG
2767 s->symbol.the_bfd = abfd;
2768 s->symbol.name = sym->strtab + stroff;
2769 s->symbol.value = value;
2770 s->symbol.flags = 0x0;
b22161d6 2771 s->symbol.udata.i = i;
92bc0e80
TG
2772 s->n_type = type;
2773 s->n_sect = section;
2774 s->n_desc = desc;
3af9a47b
NC
2775
2776 if (type & BFD_MACH_O_N_STAB)
2777 {
92bc0e80
TG
2778 s->symbol.flags |= BSF_DEBUGGING;
2779 s->symbol.section = bfd_und_section_ptr;
15e1c58a
TG
2780 switch (type)
2781 {
2782 case N_FUN:
2783 case N_STSYM:
2784 case N_LCSYM:
2785 case N_BNSYM:
2786 case N_SLINE:
2787 case N_ENSYM:
2788 case N_ECOMM:
2789 case N_ECOML:
2790 case N_GSYM:
2791 if ((section > 0) && (section <= mdata->nsects))
2792 {
92bc0e80
TG
2793 s->symbol.section = mdata->sections[section - 1]->bfdsection;
2794 s->symbol.value =
2795 s->symbol.value - mdata->sections[section - 1]->addr;
15e1c58a
TG
2796 }
2797 break;
2798 }
3af9a47b
NC
2799 }
2800 else
2801 {
b22161d6 2802 if (type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT))
92bc0e80 2803 s->symbol.flags |= BSF_GLOBAL;
b22161d6 2804 else
92bc0e80 2805 s->symbol.flags |= BSF_LOCAL;
3af9a47b
NC
2806
2807 switch (symtype)
2808 {
2809 case BFD_MACH_O_N_UNDF:
c2f09c75 2810 if (type == (BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT)
92bc0e80 2811 && s->symbol.value != 0)
c2f09c75
TG
2812 {
2813 /* A common symbol. */
92bc0e80
TG
2814 s->symbol.section = bfd_com_section_ptr;
2815 s->symbol.flags = BSF_NO_FLAGS;
c2f09c75
TG
2816 }
2817 else
92bc0e80
TG
2818 {
2819 s->symbol.section = bfd_und_section_ptr;
2820 if (s->n_desc & BFD_MACH_O_N_WEAK_REF)
2821 s->symbol.flags |= BSF_WEAK;
2822 }
3af9a47b
NC
2823 break;
2824 case BFD_MACH_O_N_PBUD:
92bc0e80 2825 s->symbol.section = bfd_und_section_ptr;
3af9a47b
NC
2826 break;
2827 case BFD_MACH_O_N_ABS:
92bc0e80 2828 s->symbol.section = bfd_abs_section_ptr;
3af9a47b
NC
2829 break;
2830 case BFD_MACH_O_N_SECT:
2831 if ((section > 0) && (section <= mdata->nsects))
2832 {
92bc0e80
TG
2833 s->symbol.section = mdata->sections[section - 1]->bfdsection;
2834 s->symbol.value =
2835 s->symbol.value - mdata->sections[section - 1]->addr;
3af9a47b
NC
2836 }
2837 else
2838 {
2839 /* Mach-O uses 0 to mean "no section"; not an error. */
2840 if (section != 0)
2841 {
4a97a0e5
AM
2842 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
2843 "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"),
2844 s->symbol.name, section, mdata->nsects);
3af9a47b 2845 }
92bc0e80 2846 s->symbol.section = bfd_und_section_ptr;
3af9a47b
NC
2847 }
2848 break;
2849 case BFD_MACH_O_N_INDR:
0596a831
TG
2850 /* FIXME: we don't follow the BFD convention as this indirect symbol
2851 won't be followed by the referenced one. This looks harmless
2852 unless we start using the linker. */
2853 s->symbol.flags |= BSF_INDIRECT;
2854 s->symbol.section = bfd_ind_section_ptr;
2855 s->symbol.value = 0;
3af9a47b
NC
2856 break;
2857 default:
4a97a0e5
AM
2858 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
2859 "symbol \"%s\" specified invalid type field 0x%x: setting to undefined"),
2860 s->symbol.name, symtype);
92bc0e80 2861 s->symbol.section = bfd_und_section_ptr;
3af9a47b
NC
2862 break;
2863 }
2864 }
2865
afbb9e17 2866 return TRUE;
3af9a47b
NC
2867}
2868
c5012cd8 2869bfd_boolean
ab273af8 2870bfd_mach_o_read_symtab_strtab (bfd *abfd)
3af9a47b 2871{
046b007d
TG
2872 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2873 bfd_mach_o_symtab_command *sym = mdata->symtab;
2874
2875 /* Fail if there is no symtab. */
2876 if (sym == NULL)
afbb9e17 2877 return FALSE;
046b007d
TG
2878
2879 /* Success if already loaded. */
2880 if (sym->strtab)
afbb9e17 2881 return TRUE;
3af9a47b
NC
2882
2883 if (abfd->flags & BFD_IN_MEMORY)
2884 {
2885 struct bfd_in_memory *b;
2886
2887 b = (struct bfd_in_memory *) abfd->iostream;
2888
2889 if ((sym->stroff + sym->strsize) > b->size)
2890 {
2891 bfd_set_error (bfd_error_file_truncated);
afbb9e17 2892 return FALSE;
3af9a47b 2893 }
f075ee0c 2894 sym->strtab = (char *) b->buffer + sym->stroff;
3af9a47b 2895 }
046b007d 2896 else
3af9a47b 2897 {
046b007d
TG
2898 sym->strtab = bfd_alloc (abfd, sym->strsize);
2899 if (sym->strtab == NULL)
afbb9e17 2900 return FALSE;
046b007d
TG
2901
2902 if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0
afbb9e17 2903 || bfd_bread (sym->strtab, sym->strsize, abfd) != sym->strsize)
046b007d
TG
2904 {
2905 bfd_set_error (bfd_error_file_truncated);
afbb9e17 2906 return FALSE;
046b007d 2907 }
3af9a47b
NC
2908 }
2909
afbb9e17 2910 return TRUE;
3af9a47b
NC
2911}
2912
c5012cd8 2913bfd_boolean
ab273af8 2914bfd_mach_o_read_symtab_symbols (bfd *abfd)
3af9a47b 2915{
046b007d
TG
2916 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2917 bfd_mach_o_symtab_command *sym = mdata->symtab;
3af9a47b 2918 unsigned long i;
3af9a47b 2919
092d27ff
TG
2920 if (sym == NULL || sym->symbols)
2921 {
2922 /* Return now if there are no symbols or if already loaded. */
afbb9e17 2923 return TRUE;
092d27ff 2924 }
046b007d 2925
92bc0e80 2926 sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
3af9a47b
NC
2927
2928 if (sym->symbols == NULL)
2929 {
4a97a0e5 2930 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"));
afbb9e17 2931 return FALSE;
3af9a47b 2932 }
a95a4550 2933
afbb9e17
TG
2934 if (!bfd_mach_o_read_symtab_strtab (abfd))
2935 return FALSE;
3af9a47b
NC
2936
2937 for (i = 0; i < sym->nsyms; i++)
2938 {
afbb9e17
TG
2939 if (!bfd_mach_o_read_symtab_symbol (abfd, sym, &sym->symbols[i], i))
2940 return FALSE;
3af9a47b 2941 }
a95a4550 2942
afbb9e17 2943 return TRUE;
3af9a47b
NC
2944}
2945
2946static const char *
116c20d2 2947bfd_mach_o_i386_flavour_string (unsigned int flavour)
3af9a47b
NC
2948{
2949 switch ((int) flavour)
2950 {
15e1c58a
TG
2951 case BFD_MACH_O_x86_THREAD_STATE32: return "x86_THREAD_STATE32";
2952 case BFD_MACH_O_x86_FLOAT_STATE32: return "x86_FLOAT_STATE32";
2953 case BFD_MACH_O_x86_EXCEPTION_STATE32: return "x86_EXCEPTION_STATE32";
2954 case BFD_MACH_O_x86_THREAD_STATE64: return "x86_THREAD_STATE64";
2955 case BFD_MACH_O_x86_FLOAT_STATE64: return "x86_FLOAT_STATE64";
2956 case BFD_MACH_O_x86_EXCEPTION_STATE64: return "x86_EXCEPTION_STATE64";
2957 case BFD_MACH_O_x86_THREAD_STATE: return "x86_THREAD_STATE";
2958 case BFD_MACH_O_x86_FLOAT_STATE: return "x86_FLOAT_STATE";
2959 case BFD_MACH_O_x86_EXCEPTION_STATE: return "x86_EXCEPTION_STATE";
2960 case BFD_MACH_O_x86_DEBUG_STATE32: return "x86_DEBUG_STATE32";
2961 case BFD_MACH_O_x86_DEBUG_STATE64: return "x86_DEBUG_STATE64";
2962 case BFD_MACH_O_x86_DEBUG_STATE: return "x86_DEBUG_STATE";
b32e07d7 2963 case BFD_MACH_O_x86_THREAD_STATE_NONE: return "x86_THREAD_STATE_NONE";
3af9a47b
NC
2964 default: return "UNKNOWN";
2965 }
2966}
2967
2968static const char *
116c20d2 2969bfd_mach_o_ppc_flavour_string (unsigned int flavour)
3af9a47b
NC
2970{
2971 switch ((int) flavour)
2972 {
b32e07d7
TG
2973 case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
2974 case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
2975 case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
2976 case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
2977 case BFD_MACH_O_PPC_THREAD_STATE64: return "PPC_THREAD_STATE64";
2978 case BFD_MACH_O_PPC_EXCEPTION_STATE64: return "PPC_EXCEPTION_STATE64";
3af9a47b
NC
2979 default: return "UNKNOWN";
2980 }
2981}
2982
2983static int
ab273af8 2984bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b
NC
2985{
2986 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
46d1c23b 2987 struct mach_o_str_command_external raw;
3af9a47b 2988 unsigned int nameoff;
3af9a47b
NC
2989
2990 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
2991 || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
2992
46d1c23b
TG
2993 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2994 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
2995 return -1;
2996
46d1c23b 2997 nameoff = bfd_h_get_32 (abfd, raw.str);
3af9a47b
NC
2998
2999 cmd->name_offset = command->offset + nameoff;
3000 cmd->name_len = command->len - nameoff;
b32e07d7
TG
3001 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
3002 if (cmd->name_str == NULL)
3af9a47b 3003 return -1;
b32e07d7
TG
3004 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
3005 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
3af9a47b 3006 return -1;
3af9a47b
NC
3007 return 0;
3008}
3009
3010static int
ab273af8 3011bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b
NC
3012{
3013 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
46d1c23b 3014 struct mach_o_dylib_command_external raw;
3af9a47b 3015 unsigned int nameoff;
3af9a47b 3016
046b007d
TG
3017 switch (command->type)
3018 {
3019 case BFD_MACH_O_LC_LOAD_DYLIB:
046b007d 3020 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
046b007d 3021 case BFD_MACH_O_LC_ID_DYLIB:
046b007d 3022 case BFD_MACH_O_LC_REEXPORT_DYLIB:
73017762 3023 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
046b007d
TG
3024 break;
3025 default:
b32e07d7
TG
3026 BFD_FAIL ();
3027 return -1;
046b007d 3028 }
3af9a47b 3029
46d1c23b
TG
3030 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3031 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
3032 return -1;
3033
46d1c23b
TG
3034 nameoff = bfd_h_get_32 (abfd, raw.name);
3035 cmd->timestamp = bfd_h_get_32 (abfd, raw.timestamp);
3036 cmd->current_version = bfd_h_get_32 (abfd, raw.current_version);
3037 cmd->compatibility_version = bfd_h_get_32 (abfd, raw.compatibility_version);
3af9a47b
NC
3038
3039 cmd->name_offset = command->offset + nameoff;
3040 cmd->name_len = command->len - nameoff;
b32e07d7
TG
3041 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
3042 if (cmd->name_str == NULL)
3af9a47b 3043 return -1;
b32e07d7
TG
3044 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
3045 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
3af9a47b 3046 return -1;
3af9a47b
NC
3047 return 0;
3048}
3049
3050static int
ab273af8
TG
3051bfd_mach_o_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
3052 bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
3af9a47b
NC
3053{
3054 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
3055
3056 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
3057 return 0;
3058}
3059
9f4a5bd1
TG
3060static int
3061bfd_mach_o_read_fvmlib (bfd *abfd, bfd_mach_o_load_command *command)
3062{
3063 bfd_mach_o_fvmlib_command *fvm = &command->command.fvmlib;
3064 struct mach_o_fvmlib_command_external raw;
3065 unsigned int nameoff;
3066
3067 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3068 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3069 return -1;
3070
3071 nameoff = bfd_h_get_32 (abfd, raw.name);
3072 fvm->minor_version = bfd_h_get_32 (abfd, raw.minor_version);
3073 fvm->header_addr = bfd_h_get_32 (abfd, raw.header_addr);
3074
3075 fvm->name_offset = command->offset + nameoff;
3076 fvm->name_len = command->len - nameoff;
3077 fvm->name_str = bfd_alloc (abfd, fvm->name_len);
3078 if (fvm->name_str == NULL)
3079 return -1;
3080 if (bfd_seek (abfd, fvm->name_offset, SEEK_SET) != 0
3081 || bfd_bread (fvm->name_str, fvm->name_len, abfd) != fvm->name_len)
3082 return -1;
3083 return 0;
3084}
3085
3af9a47b 3086static int
ab273af8 3087bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 3088{
b32e07d7 3089 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 3090 bfd_mach_o_thread_command *cmd = &command->command.thread;
92bc0e80 3091 unsigned int offset;
3af9a47b
NC
3092 unsigned int nflavours;
3093 unsigned int i;
3094
3095 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
3096 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
3097
b32e07d7 3098 /* Count the number of threads. */
3af9a47b
NC
3099 offset = 8;
3100 nflavours = 0;
3101 while (offset != command->len)
3102 {
46d1c23b
TG
3103 struct mach_o_thread_command_external raw;
3104
3af9a47b
NC
3105 if (offset >= command->len)
3106 return -1;
3107
c2f09c75 3108 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
46d1c23b 3109 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
3110 return -1;
3111
46d1c23b 3112 offset += sizeof (raw) + bfd_h_get_32 (abfd, raw.count) * 4;
3af9a47b
NC
3113 nflavours++;
3114 }
3115
b32e07d7
TG
3116 /* Allocate threads. */
3117 cmd->flavours = bfd_alloc
3118 (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
3af9a47b
NC
3119 if (cmd->flavours == NULL)
3120 return -1;
3121 cmd->nflavours = nflavours;
3122
3123 offset = 8;
3124 nflavours = 0;
3125 while (offset != command->len)
3126 {
46d1c23b
TG
3127 struct mach_o_thread_command_external raw;
3128
3af9a47b
NC
3129 if (offset >= command->len)
3130 return -1;
3131
3132 if (nflavours >= cmd->nflavours)
3133 return -1;
3134
c2f09c75 3135 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
46d1c23b 3136 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
3137 return -1;
3138
46d1c23b
TG
3139 cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, raw.flavour);
3140 cmd->flavours[nflavours].offset = command->offset + offset + sizeof (raw);
3141 cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, raw.count) * 4;
3142 offset += cmd->flavours[nflavours].size + sizeof (raw);
3af9a47b
NC
3143 nflavours++;
3144 }
3145
3146 for (i = 0; i < nflavours; i++)
3147 {
3148 asection *bfdsec;
3149 unsigned int snamelen;
3150 char *sname;
3151 const char *flavourstr;
3152 const char *prefix = "LC_THREAD";
a95a4550
AM
3153 unsigned int j = 0;
3154
3af9a47b
NC
3155 switch (mdata->header.cputype)
3156 {
3157 case BFD_MACH_O_CPU_TYPE_POWERPC:
1e8a024a 3158 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
3af9a47b
NC
3159 flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
3160 break;
3161 case BFD_MACH_O_CPU_TYPE_I386:
1e8a024a 3162 case BFD_MACH_O_CPU_TYPE_X86_64:
3af9a47b
NC
3163 flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
3164 break;
3165 default:
3166 flavourstr = "UNKNOWN_ARCHITECTURE";
3167 break;
3168 }
a95a4550 3169
3af9a47b 3170 snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
116c20d2 3171 sname = bfd_alloc (abfd, snamelen);
3af9a47b
NC
3172 if (sname == NULL)
3173 return -1;
3174
3175 for (;;)
3176 {
a95a4550
AM
3177 sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
3178 if (bfd_get_section_by_name (abfd, sname) == NULL)
3af9a47b 3179 break;
a95a4550 3180 j++;
3af9a47b
NC
3181 }
3182
117ed4f8 3183 bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
a95a4550 3184
3af9a47b
NC
3185 bfdsec->vma = 0;
3186 bfdsec->lma = 0;
eea6121a 3187 bfdsec->size = cmd->flavours[i].size;
3af9a47b
NC
3188 bfdsec->filepos = cmd->flavours[i].offset;
3189 bfdsec->alignment_power = 0x0;
3af9a47b
NC
3190
3191 cmd->section = bfdsec;
3192 }
3193
3194 return 0;
3195}
3196
a95a4550 3197static int
ab273af8 3198bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 3199{
046b007d 3200 bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
b32e07d7 3201 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b
NC
3202
3203 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
3204
46d1c23b
TG
3205 {
3206 struct mach_o_dysymtab_command_external raw;
3207
3208 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3209 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3210 return -1;
3af9a47b 3211
46d1c23b
TG
3212 cmd->ilocalsym = bfd_h_get_32 (abfd, raw.ilocalsym);
3213 cmd->nlocalsym = bfd_h_get_32 (abfd, raw.nlocalsym);
3214 cmd->iextdefsym = bfd_h_get_32 (abfd, raw.iextdefsym);
3215 cmd->nextdefsym = bfd_h_get_32 (abfd, raw.nextdefsym);
3216 cmd->iundefsym = bfd_h_get_32 (abfd, raw.iundefsym);
3217 cmd->nundefsym = bfd_h_get_32 (abfd, raw.nundefsym);
3218 cmd->tocoff = bfd_h_get_32 (abfd, raw.tocoff);
3219 cmd->ntoc = bfd_h_get_32 (abfd, raw.ntoc);
3220 cmd->modtaboff = bfd_h_get_32 (abfd, raw.modtaboff);
3221 cmd->nmodtab = bfd_h_get_32 (abfd, raw.nmodtab);
3222 cmd->extrefsymoff = bfd_h_get_32 (abfd, raw.extrefsymoff);
3223 cmd->nextrefsyms = bfd_h_get_32 (abfd, raw.nextrefsyms);
3224 cmd->indirectsymoff = bfd_h_get_32 (abfd, raw.indirectsymoff);
3225 cmd->nindirectsyms = bfd_h_get_32 (abfd, raw.nindirectsyms);
3226 cmd->extreloff = bfd_h_get_32 (abfd, raw.extreloff);
3227 cmd->nextrel = bfd_h_get_32 (abfd, raw.nextrel);
3228 cmd->locreloff = bfd_h_get_32 (abfd, raw.locreloff);
3229 cmd->nlocrel = bfd_h_get_32 (abfd, raw.nlocrel);
3230 }
046b007d
TG
3231
3232 if (cmd->nmodtab != 0)
3233 {
046b007d
TG
3234 unsigned int i;
3235 int wide = bfd_mach_o_wide_p (abfd);
3236 unsigned int module_len = wide ? 56 : 52;
3237
3238 cmd->dylib_module =
3239 bfd_alloc (abfd, cmd->nmodtab * sizeof (bfd_mach_o_dylib_module));
3240 if (cmd->dylib_module == NULL)
3241 return -1;
3242
3243 if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0)
3244 return -1;
3245
3246 for (i = 0; i < cmd->nmodtab; i++)
3247 {
3248 bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
3249 unsigned long v;
46d1c23b 3250 unsigned char buf[56];
046b007d 3251
91d6fa6a 3252 if (bfd_bread ((void *) buf, module_len, abfd) != module_len)
046b007d
TG
3253 return -1;
3254
3255 module->module_name_idx = bfd_h_get_32 (abfd, buf + 0);
3256 module->iextdefsym = bfd_h_get_32 (abfd, buf + 4);
3257 module->nextdefsym = bfd_h_get_32 (abfd, buf + 8);
3258 module->irefsym = bfd_h_get_32 (abfd, buf + 12);
3259 module->nrefsym = bfd_h_get_32 (abfd, buf + 16);
3260 module->ilocalsym = bfd_h_get_32 (abfd, buf + 20);
3261 module->nlocalsym = bfd_h_get_32 (abfd, buf + 24);
3262 module->iextrel = bfd_h_get_32 (abfd, buf + 28);
3263 module->nextrel = bfd_h_get_32 (abfd, buf + 32);
3264 v = bfd_h_get_32 (abfd, buf +36);
3265 module->iinit = v & 0xffff;
3266 module->iterm = (v >> 16) & 0xffff;
3267 v = bfd_h_get_32 (abfd, buf + 40);
3268 module->ninit = v & 0xffff;
3269 module->nterm = (v >> 16) & 0xffff;
3270 if (wide)
3271 {
3272 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 44);
3273 module->objc_module_info_addr = bfd_h_get_64 (abfd, buf + 48);
3274 }
3275 else
3276 {
3277 module->objc_module_info_addr = bfd_h_get_32 (abfd, buf + 44);
3278 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 48);
3279 }
3280 }
3281 }
afbb9e17 3282
046b007d
TG
3283 if (cmd->ntoc != 0)
3284 {
046b007d
TG
3285 unsigned int i;
3286
3287 cmd->dylib_toc = bfd_alloc
3288 (abfd, cmd->ntoc * sizeof (bfd_mach_o_dylib_table_of_content));
3289 if (cmd->dylib_toc == NULL)
3290 return -1;
3291
3292 if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
3293 return -1;
3294
3295 for (i = 0; i < cmd->ntoc; i++)
3296 {
46d1c23b 3297 struct mach_o_dylib_table_of_contents_external raw;
046b007d
TG
3298 bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
3299
46d1c23b 3300 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
3301 return -1;
3302
46d1c23b
TG
3303 toc->symbol_index = bfd_h_get_32 (abfd, raw.symbol_index);
3304 toc->module_index = bfd_h_get_32 (abfd, raw.module_index);
046b007d
TG
3305 }
3306 }
3307
3308 if (cmd->nindirectsyms != 0)
3309 {
046b007d
TG
3310 unsigned int i;
3311
3312 cmd->indirect_syms = bfd_alloc
3313 (abfd, cmd->nindirectsyms * sizeof (unsigned int));
3314 if (cmd->indirect_syms == NULL)
3315 return -1;
3316
3317 if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
3318 return -1;
3319
3320 for (i = 0; i < cmd->nindirectsyms; i++)
3321 {
46d1c23b 3322 unsigned char raw[4];
046b007d
TG
3323 unsigned int *is = &cmd->indirect_syms[i];
3324
46d1c23b 3325 if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
3326 return -1;
3327
46d1c23b 3328 *is = bfd_h_get_32 (abfd, raw);
046b007d
TG
3329 }
3330 }
3331
3332 if (cmd->nextrefsyms != 0)
3333 {
046b007d
TG
3334 unsigned long v;
3335 unsigned int i;
3336
3337 cmd->ext_refs = bfd_alloc
3338 (abfd, cmd->nextrefsyms * sizeof (bfd_mach_o_dylib_reference));
3339 if (cmd->ext_refs == NULL)
3340 return -1;
3341
3342 if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
3343 return -1;
3344
3345 for (i = 0; i < cmd->nextrefsyms; i++)
3346 {
46d1c23b 3347 unsigned char raw[4];
046b007d
TG
3348 bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
3349
46d1c23b 3350 if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
3351 return -1;
3352
b32e07d7
TG
3353 /* Fields isym and flags are written as bit-fields, thus we need
3354 a specific processing for endianness. */
46d1c23b 3355 v = bfd_h_get_32 (abfd, raw);
b32e07d7
TG
3356 if (bfd_big_endian (abfd))
3357 {
3358 ref->isym = (v >> 8) & 0xffffff;
3359 ref->flags = v & 0xff;
3360 }
3361 else
3362 {
3363 ref->isym = v & 0xffffff;
3364 ref->flags = (v >> 24) & 0xff;
3365 }
046b007d
TG
3366 }
3367 }
3af9a47b 3368
b32e07d7
TG
3369 if (mdata->dysymtab)
3370 return -1;
3371 mdata->dysymtab = cmd;
3372
3af9a47b
NC
3373 return 0;
3374}
3375
a95a4550 3376static int
ab273af8 3377bfd_mach_o_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 3378{
046b007d
TG
3379 bfd_mach_o_symtab_command *symtab = &command->command.symtab;
3380 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
46d1c23b 3381 struct mach_o_symtab_command_external raw;
3af9a47b
NC
3382
3383 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
3384
46d1c23b
TG
3385 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3386 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b 3387 return -1;
a95a4550 3388
46d1c23b
TG
3389 symtab->symoff = bfd_h_get_32 (abfd, raw.symoff);
3390 symtab->nsyms = bfd_h_get_32 (abfd, raw.nsyms);
3391 symtab->stroff = bfd_h_get_32 (abfd, raw.stroff);
3392 symtab->strsize = bfd_h_get_32 (abfd, raw.strsize);
046b007d
TG
3393 symtab->symbols = NULL;
3394 symtab->strtab = NULL;
3af9a47b 3395
046b007d 3396 if (symtab->nsyms != 0)
15e1c58a
TG
3397 abfd->flags |= HAS_SYMS;
3398
046b007d
TG
3399 if (mdata->symtab)
3400 return -1;
3401 mdata->symtab = symtab;
3af9a47b
NC
3402 return 0;
3403}
3404
15e1c58a 3405static int
ab273af8 3406bfd_mach_o_read_uuid (bfd *abfd, bfd_mach_o_load_command *command)
15e1c58a
TG
3407{
3408 bfd_mach_o_uuid_command *cmd = &command->command.uuid;
15e1c58a
TG
3409
3410 BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
3411
46d1c23b
TG
3412 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3413 || bfd_bread (cmd->uuid, 16, abfd) != 16)
15e1c58a
TG
3414 return -1;
3415
15e1c58a
TG
3416 return 0;
3417}
3418
046b007d 3419static int
ab273af8 3420bfd_mach_o_read_linkedit (bfd *abfd, bfd_mach_o_load_command *command)
046b007d
TG
3421{
3422 bfd_mach_o_linkedit_command *cmd = &command->command.linkedit;
46d1c23b 3423 struct mach_o_linkedit_data_command_external raw;
046b007d 3424
46d1c23b
TG
3425 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3426 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
3427 return -1;
3428
46d1c23b
TG
3429 cmd->dataoff = bfd_get_32 (abfd, raw.dataoff);
3430 cmd->datasize = bfd_get_32 (abfd, raw.datasize);
046b007d
TG
3431 return 0;
3432}
3433
3434static int
ab273af8 3435bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command)
046b007d
TG
3436{
3437 bfd_mach_o_str_command *cmd = &command->command.str;
46d1c23b 3438 struct mach_o_str_command_external raw;
046b007d
TG
3439 unsigned long off;
3440
46d1c23b
TG
3441 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3442 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
3443 return -1;
3444
46d1c23b 3445 off = bfd_get_32 (abfd, raw.str);
046b007d
TG
3446 cmd->stroff = command->offset + off;
3447 cmd->str_len = command->len - off;
3448 cmd->str = bfd_alloc (abfd, cmd->str_len);
3449 if (cmd->str == NULL)
3450 return -1;
3451 if (bfd_seek (abfd, cmd->stroff, SEEK_SET) != 0
91d6fa6a 3452 || bfd_bread ((void *) cmd->str, cmd->str_len, abfd) != cmd->str_len)
046b007d
TG
3453 return -1;
3454 return 0;
3455}
3456
ad86f1fb 3457static int
ab273af8 3458bfd_mach_o_read_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
ad86f1fb
TG
3459{
3460 bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
46d1c23b 3461 struct mach_o_dyld_info_command_external raw;
ad86f1fb 3462
46d1c23b
TG
3463 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3464 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
ad86f1fb
TG
3465 return -1;
3466
46d1c23b
TG
3467 cmd->rebase_off = bfd_get_32 (abfd, raw.rebase_off);
3468 cmd->rebase_size = bfd_get_32 (abfd, raw.rebase_size);
3469 cmd->bind_off = bfd_get_32 (abfd, raw.bind_off);
3470 cmd->bind_size = bfd_get_32 (abfd, raw.bind_size);
3471 cmd->weak_bind_off = bfd_get_32 (abfd, raw.weak_bind_off);
3472 cmd->weak_bind_size = bfd_get_32 (abfd, raw.weak_bind_size);
3473 cmd->lazy_bind_off = bfd_get_32 (abfd, raw.lazy_bind_off);
3474 cmd->lazy_bind_size = bfd_get_32 (abfd, raw.lazy_bind_size);
3475 cmd->export_off = bfd_get_32 (abfd, raw.export_off);
3476 cmd->export_size = bfd_get_32 (abfd, raw.export_size);
ad86f1fb
TG
3477 return 0;
3478}
3479
edbdea0e
TG
3480static bfd_boolean
3481bfd_mach_o_read_version_min (bfd *abfd, bfd_mach_o_load_command *command)
3482{
3483 bfd_mach_o_version_min_command *cmd = &command->command.version_min;
3484 struct mach_o_version_min_command_external raw;
3485 unsigned int ver;
3486
3487 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3488 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3489 return FALSE;
3490
3491 ver = bfd_get_32 (abfd, raw.version);
3492 cmd->rel = ver >> 16;
3493 cmd->maj = ver >> 8;
3494 cmd->min = ver;
3495 cmd->reserved = bfd_get_32 (abfd, raw.reserved);
3496 return TRUE;
3497}
3498
fc55a902
TG
3499static bfd_boolean
3500bfd_mach_o_read_encryption_info (bfd *abfd, bfd_mach_o_load_command *command)
3501{
3502 bfd_mach_o_encryption_info_command *cmd = &command->command.encryption_info;
3503 struct mach_o_encryption_info_command_external raw;
3504
3505 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3506 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3507 return FALSE;
3508
3509 cmd->cryptoff = bfd_get_32 (abfd, raw.cryptoff);
3510 cmd->cryptsize = bfd_get_32 (abfd, raw.cryptsize);
3511 cmd->cryptid = bfd_get_32 (abfd, raw.cryptid);
3512 return TRUE;
3513}
3514
3af9a47b 3515static int
ab273af8
TG
3516bfd_mach_o_read_segment (bfd *abfd,
3517 bfd_mach_o_load_command *command,
3518 unsigned int wide)
3af9a47b 3519{
3af9a47b
NC
3520 bfd_mach_o_segment_command *seg = &command->command.segment;
3521 unsigned long i;
a95a4550 3522
1e8a024a
TG
3523 if (wide)
3524 {
46d1c23b
TG
3525 struct mach_o_segment_command_64_external raw;
3526
1e8a024a 3527 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
3af9a47b 3528
46d1c23b
TG
3529 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3530 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3531 return -1;
3af9a47b 3532
46d1c23b 3533 memcpy (seg->segname, raw.segname, 16);
15e1c58a 3534 seg->segname[16] = '\0';
1e8a024a 3535
46d1c23b
TG
3536 seg->vmaddr = bfd_h_get_64 (abfd, raw.vmaddr);
3537 seg->vmsize = bfd_h_get_64 (abfd, raw.vmsize);
3538 seg->fileoff = bfd_h_get_64 (abfd, raw.fileoff);
3539 seg->filesize = bfd_h_get_64 (abfd, raw.filesize);
3540 seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
3541 seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
3542 seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
3543 seg->flags = bfd_h_get_32 (abfd, raw.flags);
1e8a024a
TG
3544 }
3545 else
3546 {
46d1c23b
TG
3547 struct mach_o_segment_command_32_external raw;
3548
1e8a024a
TG
3549 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
3550
46d1c23b
TG
3551 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
3552 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3553 return -1;
1e8a024a 3554
46d1c23b 3555 memcpy (seg->segname, raw.segname, 16);
15e1c58a 3556 seg->segname[16] = '\0';
1e8a024a 3557
46d1c23b
TG
3558 seg->vmaddr = bfd_h_get_32 (abfd, raw.vmaddr);
3559 seg->vmsize = bfd_h_get_32 (abfd, raw.vmsize);
3560 seg->fileoff = bfd_h_get_32 (abfd, raw.fileoff);
3561 seg->filesize = bfd_h_get_32 (abfd, raw.filesize);
3562 seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
3563 seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
3564 seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
3565 seg->flags = bfd_h_get_32 (abfd, raw.flags);
1e8a024a 3566 }
9d4b6009
TG
3567 seg->sect_head = NULL;
3568 seg->sect_tail = NULL;
3af9a47b 3569
f1bde64c 3570 for (i = 0; i < seg->nsects; i++)
3af9a47b 3571 {
f1bde64c
TG
3572 bfd_vma segoff;
3573 asection *sec;
a95a4550 3574
f1bde64c
TG
3575 if (wide)
3576 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
3577 + (i * BFD_MACH_O_SECTION_64_SIZE);
3578 else
3579 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
3580 + (i * BFD_MACH_O_SECTION_SIZE);
3af9a47b 3581
f1bde64c
TG
3582 sec = bfd_mach_o_read_section (abfd, segoff, seg->initprot, wide);
3583 if (sec == NULL)
3584 return -1;
3585
3586 bfd_mach_o_append_section_to_segment (seg, sec);
3af9a47b
NC
3587 }
3588
3589 return 0;
3590}
3591
1e8a024a 3592static int
ab273af8 3593bfd_mach_o_read_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 3594{
ab273af8 3595 return bfd_mach_o_read_segment (abfd, command, 0);
1e8a024a
TG
3596}
3597
3598static int
ab273af8 3599bfd_mach_o_read_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 3600{
ab273af8 3601 return bfd_mach_o_read_segment (abfd, command, 1);
1e8a024a
TG
3602}
3603
3af9a47b 3604static int
ab273af8 3605bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 3606{
46d1c23b
TG
3607 struct mach_o_load_command_external raw;
3608 unsigned int cmd;
3af9a47b 3609
046b007d 3610 /* Read command type and length. */
c2f09c75 3611 if (bfd_seek (abfd, command->offset, SEEK_SET) != 0
46d1c23b 3612 || bfd_bread (&raw, BFD_MACH_O_LC_SIZE, abfd) != BFD_MACH_O_LC_SIZE)
3af9a47b
NC
3613 return -1;
3614
46d1c23b
TG
3615 cmd = bfd_h_get_32 (abfd, raw.cmd);
3616 command->type = cmd & ~BFD_MACH_O_LC_REQ_DYLD;
3617 command->type_required = cmd & BFD_MACH_O_LC_REQ_DYLD ? TRUE : FALSE;
3618 command->len = bfd_h_get_32 (abfd, raw.cmdsize);
3af9a47b
NC
3619
3620 switch (command->type)
3621 {
3622 case BFD_MACH_O_LC_SEGMENT:
ab273af8 3623 if (bfd_mach_o_read_segment_32 (abfd, command) != 0)
1e8a024a
TG
3624 return -1;
3625 break;
3626 case BFD_MACH_O_LC_SEGMENT_64:
ab273af8 3627 if (bfd_mach_o_read_segment_64 (abfd, command) != 0)
3af9a47b
NC
3628 return -1;
3629 break;
3630 case BFD_MACH_O_LC_SYMTAB:
ab273af8 3631 if (bfd_mach_o_read_symtab (abfd, command) != 0)
3af9a47b
NC
3632 return -1;
3633 break;
3634 case BFD_MACH_O_LC_SYMSEG:
3635 break;
3636 case BFD_MACH_O_LC_THREAD:
3637 case BFD_MACH_O_LC_UNIXTHREAD:
ab273af8 3638 if (bfd_mach_o_read_thread (abfd, command) != 0)
3af9a47b
NC
3639 return -1;
3640 break;
3641 case BFD_MACH_O_LC_LOAD_DYLINKER:
3642 case BFD_MACH_O_LC_ID_DYLINKER:
ab273af8 3643 if (bfd_mach_o_read_dylinker (abfd, command) != 0)
3af9a47b
NC
3644 return -1;
3645 break;
3646 case BFD_MACH_O_LC_LOAD_DYLIB:
3647 case BFD_MACH_O_LC_ID_DYLIB:
3648 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
046b007d 3649 case BFD_MACH_O_LC_REEXPORT_DYLIB:
73017762 3650 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
ab273af8 3651 if (bfd_mach_o_read_dylib (abfd, command) != 0)
3af9a47b
NC
3652 return -1;
3653 break;
3654 case BFD_MACH_O_LC_PREBOUND_DYLIB:
ab273af8 3655 if (bfd_mach_o_read_prebound_dylib (abfd, command) != 0)
3af9a47b
NC
3656 return -1;
3657 break;
3658 case BFD_MACH_O_LC_LOADFVMLIB:
3659 case BFD_MACH_O_LC_IDFVMLIB:
9f4a5bd1
TG
3660 if (bfd_mach_o_read_fvmlib (abfd, command) != 0)
3661 return -1;
3662 break;
3af9a47b
NC
3663 case BFD_MACH_O_LC_IDENT:
3664 case BFD_MACH_O_LC_FVMFILE:
3665 case BFD_MACH_O_LC_PREPAGE:
3666 case BFD_MACH_O_LC_ROUTINES:
9b02d212 3667 case BFD_MACH_O_LC_ROUTINES_64:
046b007d 3668 break;
3af9a47b 3669 case BFD_MACH_O_LC_SUB_FRAMEWORK:
046b007d
TG
3670 case BFD_MACH_O_LC_SUB_UMBRELLA:
3671 case BFD_MACH_O_LC_SUB_LIBRARY:
3672 case BFD_MACH_O_LC_SUB_CLIENT:
0c9b2b4c 3673 case BFD_MACH_O_LC_RPATH:
ab273af8 3674 if (bfd_mach_o_read_str (abfd, command) != 0)
046b007d 3675 return -1;
3af9a47b
NC
3676 break;
3677 case BFD_MACH_O_LC_DYSYMTAB:
ab273af8 3678 if (bfd_mach_o_read_dysymtab (abfd, command) != 0)
3af9a47b
NC
3679 return -1;
3680 break;
3af9a47b
NC
3681 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
3682 case BFD_MACH_O_LC_PREBIND_CKSUM:
3683 break;
15e1c58a 3684 case BFD_MACH_O_LC_UUID:
ab273af8 3685 if (bfd_mach_o_read_uuid (abfd, command) != 0)
15e1c58a
TG
3686 return -1;
3687 break;
3688 case BFD_MACH_O_LC_CODE_SIGNATURE:
846b9259 3689 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
edbdea0e 3690 case BFD_MACH_O_LC_FUNCTION_STARTS:
ab273af8 3691 if (bfd_mach_o_read_linkedit (abfd, command) != 0)
046b007d 3692 return -1;
15e1c58a 3693 break;
fc55a902
TG
3694 case BFD_MACH_O_LC_ENCRYPTION_INFO:
3695 if (!bfd_mach_o_read_encryption_info (abfd, command))
3696 return -1;
3697 break;
ad86f1fb 3698 case BFD_MACH_O_LC_DYLD_INFO:
ab273af8 3699 if (bfd_mach_o_read_dyld_info (abfd, command) != 0)
ad86f1fb
TG
3700 return -1;
3701 break;
edbdea0e
TG
3702 case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
3703 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
3704 if (!bfd_mach_o_read_version_min (abfd, command))
3705 return -1;
3706 break;
3af9a47b 3707 default:
fc55a902 3708 (*_bfd_error_handler)(_("%B: unknown load command 0x%lx"),
c0d9d051 3709 abfd, (unsigned long) command->type);
3af9a47b
NC
3710 break;
3711 }
3712
3713 return 0;
3714}
3715
3716static void
116c20d2 3717bfd_mach_o_flatten_sections (bfd *abfd)
3af9a47b 3718{
046b007d 3719 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 3720 long csect = 0;
f1bde64c 3721 unsigned long i;
a95a4550 3722
15e1c58a 3723 /* Count total number of sections. */
3af9a47b
NC
3724 mdata->nsects = 0;
3725
3726 for (i = 0; i < mdata->header.ncmds; i++)
3727 {
1e8a024a
TG
3728 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
3729 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
3af9a47b 3730 {
e84d6fca
AM
3731 bfd_mach_o_segment_command *seg;
3732
3733 seg = &mdata->commands[i].command.segment;
3af9a47b
NC
3734 mdata->nsects += seg->nsects;
3735 }
3736 }
3737
15e1c58a 3738 /* Allocate sections array. */
e84d6fca
AM
3739 mdata->sections = bfd_alloc (abfd,
3740 mdata->nsects * sizeof (bfd_mach_o_section *));
15e1c58a
TG
3741
3742 /* Fill the array. */
3af9a47b
NC
3743 csect = 0;
3744
3745 for (i = 0; i < mdata->header.ncmds; i++)
3746 {
1e8a024a
TG
3747 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
3748 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
3af9a47b 3749 {
e84d6fca 3750 bfd_mach_o_segment_command *seg;
f1bde64c 3751 bfd_mach_o_section *sec;
3af9a47b 3752
e84d6fca 3753 seg = &mdata->commands[i].command.segment;
3af9a47b
NC
3754 BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
3755
f1bde64c
TG
3756 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
3757 mdata->sections[csect++] = sec;
3af9a47b
NC
3758 }
3759 }
3760}
3761
afbb9e17 3762static bfd_boolean
116c20d2 3763bfd_mach_o_scan_start_address (bfd *abfd)
3af9a47b 3764{
046b007d 3765 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b
NC
3766 bfd_mach_o_thread_command *cmd = NULL;
3767 unsigned long i;
3768
3769 for (i = 0; i < mdata->header.ncmds; i++)
afbb9e17
TG
3770 if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
3771 (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
3772 {
3773 cmd = &mdata->commands[i].command.thread;
3774 break;
3775 }
3af9a47b
NC
3776
3777 if (cmd == NULL)
afbb9e17 3778 return FALSE;
3af9a47b 3779
afbb9e17 3780 /* FIXME: create a subtarget hook ? */
3af9a47b
NC
3781 for (i = 0; i < cmd->nflavours; i++)
3782 {
a95a4550 3783 if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
e84d6fca 3784 && (cmd->flavours[i].flavour
15e1c58a 3785 == (unsigned long) BFD_MACH_O_x86_THREAD_STATE32))
3af9a47b
NC
3786 {
3787 unsigned char buf[4];
3788
c2f09c75
TG
3789 if (bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET) != 0
3790 || bfd_bread (buf, 4, abfd) != 4)
afbb9e17 3791 return FALSE;
3af9a47b
NC
3792
3793 abfd->start_address = bfd_h_get_32 (abfd, buf);
3794 }
a95a4550 3795 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
3af9a47b
NC
3796 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
3797 {
3798 unsigned char buf[4];
3799
c2f09c75
TG
3800 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
3801 || bfd_bread (buf, 4, abfd) != 4)
afbb9e17 3802 return FALSE;
3af9a47b
NC
3803
3804 abfd->start_address = bfd_h_get_32 (abfd, buf);
3805 }
1e8a024a 3806 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
b32e07d7 3807 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE64))
1e8a024a
TG
3808 {
3809 unsigned char buf[8];
3810
c2f09c75
TG
3811 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
3812 || bfd_bread (buf, 8, abfd) != 8)
afbb9e17 3813 return FALSE;
1e8a024a
TG
3814
3815 abfd->start_address = bfd_h_get_64 (abfd, buf);
3816 }
3817 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
3818 && (cmd->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE64))
3819 {
3820 unsigned char buf[8];
3821
c2f09c75
TG
3822 if (bfd_seek (abfd, cmd->flavours[i].offset + (16 * 8), SEEK_SET) != 0
3823 || bfd_bread (buf, 8, abfd) != 8)
afbb9e17 3824 return FALSE;
1e8a024a
TG
3825
3826 abfd->start_address = bfd_h_get_64 (abfd, buf);
3827 }
3af9a47b
NC
3828 }
3829
afbb9e17 3830 return TRUE;
3af9a47b
NC
3831}
3832
42fa0891
TG
3833bfd_boolean
3834bfd_mach_o_set_arch_mach (bfd *abfd,
3835 enum bfd_architecture arch,
3836 unsigned long machine)
3837{
3838 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
3839
3840 /* If this isn't the right architecture for this backend, and this
3841 isn't the generic backend, fail. */
3842 if (arch != bed->arch
3843 && arch != bfd_arch_unknown
3844 && bed->arch != bfd_arch_unknown)
3845 return FALSE;
3846
3847 return bfd_default_set_arch_mach (abfd, arch, machine);
3848}
3849
afbb9e17 3850static bfd_boolean
116c20d2
NC
3851bfd_mach_o_scan (bfd *abfd,
3852 bfd_mach_o_header *header,
3853 bfd_mach_o_data_struct *mdata)
3af9a47b
NC
3854{
3855 unsigned int i;
3af9a47b
NC
3856 enum bfd_architecture cputype;
3857 unsigned long cpusubtype;
1e8a024a
TG
3858 unsigned int hdrsize;
3859
c2f09c75 3860 hdrsize = mach_o_wide_p (header) ?
154a1ee5 3861 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
3af9a47b 3862
3af9a47b 3863 mdata->header = *header;
3af9a47b 3864
154a1ee5 3865 abfd->flags = abfd->flags & BFD_IN_MEMORY;
15e1c58a
TG
3866 switch (header->filetype)
3867 {
3868 case BFD_MACH_O_MH_OBJECT:
3869 abfd->flags |= HAS_RELOC;
3870 break;
3871 case BFD_MACH_O_MH_EXECUTE:
3872 abfd->flags |= EXEC_P;
3873 break;
3874 case BFD_MACH_O_MH_DYLIB:
3875 case BFD_MACH_O_MH_BUNDLE:
3876 abfd->flags |= DYNAMIC;
3877 break;
3878 }
3879
3af9a47b
NC
3880 abfd->tdata.mach_o_data = mdata;
3881
e84d6fca
AM
3882 bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
3883 &cputype, &cpusubtype);
3af9a47b
NC
3884 if (cputype == bfd_arch_unknown)
3885 {
afbb9e17
TG
3886 (*_bfd_error_handler)
3887 (_("bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"),
3888 header->cputype, header->cpusubtype);
3889 return FALSE;
3af9a47b
NC
3890 }
3891
3892 bfd_set_arch_mach (abfd, cputype, cpusubtype);
a95a4550 3893
3af9a47b
NC
3894 if (header->ncmds != 0)
3895 {
046b007d
TG
3896 mdata->commands = bfd_alloc
3897 (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
3af9a47b 3898 if (mdata->commands == NULL)
afbb9e17 3899 return FALSE;
a95a4550 3900
3af9a47b
NC
3901 for (i = 0; i < header->ncmds; i++)
3902 {
3903 bfd_mach_o_load_command *cur = &mdata->commands[i];
3904
3905 if (i == 0)
1e8a024a 3906 cur->offset = hdrsize;
3af9a47b
NC
3907 else
3908 {
3909 bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
3910 cur->offset = prev->offset + prev->len;
3911 }
3912
ab273af8 3913 if (bfd_mach_o_read_command (abfd, cur) < 0)
afbb9e17 3914 return FALSE;
a95a4550 3915 }
3af9a47b
NC
3916 }
3917
3918 if (bfd_mach_o_scan_start_address (abfd) < 0)
afbb9e17 3919 return FALSE;
3af9a47b
NC
3920
3921 bfd_mach_o_flatten_sections (abfd);
afbb9e17 3922 return TRUE;
3af9a47b
NC
3923}
3924
b34976b6 3925bfd_boolean
154a1ee5 3926bfd_mach_o_mkobject_init (bfd *abfd)
3af9a47b
NC
3927{
3928 bfd_mach_o_data_struct *mdata = NULL;
3929
116c20d2 3930 mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
3af9a47b 3931 if (mdata == NULL)
b34976b6 3932 return FALSE;
3af9a47b
NC
3933 abfd->tdata.mach_o_data = mdata;
3934
3935 mdata->header.magic = 0;
3936 mdata->header.cputype = 0;
3937 mdata->header.cpusubtype = 0;
3938 mdata->header.filetype = 0;
3939 mdata->header.ncmds = 0;
3940 mdata->header.sizeofcmds = 0;
3941 mdata->header.flags = 0;
3942 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
3943 mdata->commands = NULL;
3af9a47b
NC
3944 mdata->nsects = 0;
3945 mdata->sections = NULL;
4434114c 3946 mdata->dyn_reloc_cache = NULL;
3af9a47b 3947
b34976b6 3948 return TRUE;
3af9a47b
NC
3949}
3950
42fa0891
TG
3951static bfd_boolean
3952bfd_mach_o_gen_mkobject (bfd *abfd)
3953{
3954 bfd_mach_o_data_struct *mdata;
3955
3956 if (!bfd_mach_o_mkobject_init (abfd))
3957 return FALSE;
3958
3959 mdata = bfd_mach_o_get_data (abfd);
3960 mdata->header.magic = BFD_MACH_O_MH_MAGIC;
3961 mdata->header.cputype = 0;
3962 mdata->header.cpusubtype = 0;
3963 mdata->header.byteorder = abfd->xvec->byteorder;
3964 mdata->header.version = 1;
3965
3966 return TRUE;
3967}
3968
3af9a47b 3969const bfd_target *
154a1ee5
TG
3970bfd_mach_o_header_p (bfd *abfd,
3971 bfd_mach_o_filetype filetype,
3972 bfd_mach_o_cpu_type cputype)
3af9a47b 3973{
e84d6fca 3974 struct bfd_preserve preserve;
3af9a47b
NC
3975 bfd_mach_o_header header;
3976
e84d6fca 3977 preserve.marker = NULL;
154a1ee5 3978 if (!bfd_mach_o_read_header (abfd, &header))
e84d6fca 3979 goto wrong;
3af9a47b 3980
e84d6fca
AM
3981 if (! (header.byteorder == BFD_ENDIAN_BIG
3982 || header.byteorder == BFD_ENDIAN_LITTLE))
3af9a47b 3983 {
4a97a0e5
AM
3984 (*_bfd_error_handler) (_("unknown header byte-order value 0x%lx"),
3985 (unsigned long) header.byteorder);
e84d6fca 3986 goto wrong;
3af9a47b
NC
3987 }
3988
e84d6fca
AM
3989 if (! ((header.byteorder == BFD_ENDIAN_BIG
3990 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
3991 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
3992 || (header.byteorder == BFD_ENDIAN_LITTLE
3993 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
3994 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
3995 goto wrong;
3af9a47b 3996
154a1ee5
TG
3997 /* Check cputype and filetype.
3998 In case of wildcard, do not accept magics that are handled by existing
3999 targets. */
4000 if (cputype)
4001 {
4002 if (header.cputype != cputype)
4003 goto wrong;
4004 }
b22161d6 4005
154a1ee5
TG
4006 if (filetype)
4007 {
4008 if (header.filetype != filetype)
4009 goto wrong;
4010 }
4011 else
4012 {
4013 switch (header.filetype)
4014 {
4015 case BFD_MACH_O_MH_CORE:
4016 /* Handled by core_p */
4017 goto wrong;
4018 default:
4019 break;
4020 }
4021 }
4022
e84d6fca
AM
4023 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
4024 if (preserve.marker == NULL
4025 || !bfd_preserve_save (abfd, &preserve))
4026 goto fail;
3af9a47b 4027
afbb9e17
TG
4028 if (!bfd_mach_o_scan (abfd, &header,
4029 (bfd_mach_o_data_struct *) preserve.marker))
e84d6fca 4030 goto wrong;
a95a4550 4031
e84d6fca 4032 bfd_preserve_finish (abfd, &preserve);
3af9a47b 4033 return abfd->xvec;
e84d6fca
AM
4034
4035 wrong:
4036 bfd_set_error (bfd_error_wrong_format);
4037
4038 fail:
4039 if (preserve.marker != NULL)
4040 bfd_preserve_restore (abfd, &preserve);
4041 return NULL;
3af9a47b
NC
4042}
4043
154a1ee5
TG
4044static const bfd_target *
4045bfd_mach_o_gen_object_p (bfd *abfd)
3af9a47b 4046{
154a1ee5
TG
4047 return bfd_mach_o_header_p (abfd, 0, 0);
4048}
e84d6fca 4049
154a1ee5
TG
4050static const bfd_target *
4051bfd_mach_o_gen_core_p (bfd *abfd)
4052{
4053 return bfd_mach_o_header_p (abfd, BFD_MACH_O_MH_CORE, 0);
3af9a47b
NC
4054}
4055
4056typedef struct mach_o_fat_archentry
4057{
4058 unsigned long cputype;
4059 unsigned long cpusubtype;
4060 unsigned long offset;
4061 unsigned long size;
4062 unsigned long align;
3af9a47b
NC
4063} mach_o_fat_archentry;
4064
4065typedef struct mach_o_fat_data_struct
4066{
4067 unsigned long magic;
4068 unsigned long nfat_arch;
4069 mach_o_fat_archentry *archentries;
4070} mach_o_fat_data_struct;
4071
4072const bfd_target *
116c20d2 4073bfd_mach_o_archive_p (bfd *abfd)
3af9a47b 4074{
e84d6fca 4075 mach_o_fat_data_struct *adata = NULL;
46d1c23b 4076 struct mach_o_fat_header_external hdr;
3af9a47b
NC
4077 unsigned long i;
4078
c2f09c75 4079 if (bfd_seek (abfd, 0, SEEK_SET) != 0
46d1c23b 4080 || bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
e84d6fca 4081 goto error;
3af9a47b 4082
116c20d2 4083 adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
3af9a47b 4084 if (adata == NULL)
e84d6fca 4085 goto error;
a95a4550 4086
46d1c23b
TG
4087 adata->magic = bfd_getb32 (hdr.magic);
4088 adata->nfat_arch = bfd_getb32 (hdr.nfat_arch);
3af9a47b 4089 if (adata->magic != 0xcafebabe)
e84d6fca 4090 goto error;
27cc28f9
AS
4091 /* Avoid matching Java bytecode files, which have the same magic number.
4092 In the Java bytecode file format this field contains the JVM version,
4093 which starts at 43.0. */
4094 if (adata->nfat_arch > 30)
4095 goto error;
3af9a47b 4096
c2f09c75 4097 adata->archentries =
3af9a47b
NC
4098 bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
4099 if (adata->archentries == NULL)
e84d6fca 4100 goto error;
3af9a47b
NC
4101
4102 for (i = 0; i < adata->nfat_arch; i++)
4103 {
46d1c23b
TG
4104 struct mach_o_fat_arch_external arch;
4105 if (bfd_bread (&arch, sizeof (arch), abfd) != sizeof (arch))
e84d6fca 4106 goto error;
46d1c23b
TG
4107 adata->archentries[i].cputype = bfd_getb32 (arch.cputype);
4108 adata->archentries[i].cpusubtype = bfd_getb32 (arch.cpusubtype);
4109 adata->archentries[i].offset = bfd_getb32 (arch.offset);
4110 adata->archentries[i].size = bfd_getb32 (arch.size);
4111 adata->archentries[i].align = bfd_getb32 (arch.align);
3af9a47b
NC
4112 }
4113
4114 abfd->tdata.mach_o_fat_data = adata;
4115 return abfd->xvec;
e84d6fca
AM
4116
4117 error:
4118 if (adata != NULL)
4119 bfd_release (abfd, adata);
4120 bfd_set_error (bfd_error_wrong_format);
4121 return NULL;
3af9a47b
NC
4122}
4123
a4e241ca
TG
4124/* Set the filename for a fat binary member ABFD, whose bfd architecture is
4125 ARCH_TYPE/ARCH_SUBTYPE and corresponding entry in header is ENTRY.
4126 Set arelt_data and origin fields too. */
4127
4128static void
4129bfd_mach_o_fat_member_init (bfd *abfd,
4130 enum bfd_architecture arch_type,
4131 unsigned long arch_subtype,
4132 mach_o_fat_archentry *entry)
4133{
4134 struct areltdata *areltdata;
4135 /* Create the member filename. Use ARCH_NAME. */
4136 const bfd_arch_info_type *ap = bfd_lookup_arch (arch_type, arch_subtype);
4137
4138 if (ap)
4139 {
4140 /* Use the architecture name if known. */
4141 abfd->filename = ap->printable_name;
4142 }
4143 else
4144 {
4145 /* Forge a uniq id. */
4146 const size_t namelen = 2 + 8 + 1 + 2 + 8 + 1;
4147 char *name = bfd_alloc (abfd, namelen);
4148 snprintf (name, namelen, "0x%lx-0x%lx",
4149 entry->cputype, entry->cpusubtype);
4150 abfd->filename = name;
4151 }
4152
4153 areltdata = bfd_zalloc (abfd, sizeof (struct areltdata));
4154 areltdata->parsed_size = entry->size;
4155 abfd->arelt_data = areltdata;
4156 abfd->iostream = NULL;
4157 abfd->origin = entry->offset;
4158}
4159
3af9a47b 4160bfd *
116c20d2 4161bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
3af9a47b 4162{
e84d6fca 4163 mach_o_fat_data_struct *adata;
3af9a47b
NC
4164 mach_o_fat_archentry *entry = NULL;
4165 unsigned long i;
15e1c58a 4166 bfd *nbfd;
15e1c58a
TG
4167 enum bfd_architecture arch_type;
4168 unsigned long arch_subtype;
3af9a47b 4169
e84d6fca 4170 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
3af9a47b
NC
4171 BFD_ASSERT (adata != NULL);
4172
4173 /* Find index of previous entry. */
4174 if (prev == NULL)
a4e241ca
TG
4175 {
4176 /* Start at first one. */
4177 i = 0;
4178 }
3af9a47b
NC
4179 else
4180 {
a4e241ca 4181 /* Find index of PREV. */
3af9a47b
NC
4182 for (i = 0; i < adata->nfat_arch; i++)
4183 {
15e1c58a 4184 if (adata->archentries[i].offset == prev->origin)
3af9a47b
NC
4185 break;
4186 }
4187
4188 if (i == adata->nfat_arch)
4189 {
4190 /* Not found. */
4191 bfd_set_error (bfd_error_bad_value);
a95a4550 4192 return NULL;
3af9a47b 4193 }
a4e241ca
TG
4194
4195 /* Get next entry. */
4196 i++;
4197 }
a95a4550 4198
3af9a47b
NC
4199 if (i >= adata->nfat_arch)
4200 {
4201 bfd_set_error (bfd_error_no_more_archived_files);
4202 return NULL;
4203 }
4204
4205 entry = &adata->archentries[i];
15e1c58a
TG
4206 nbfd = _bfd_new_bfd_contained_in (archive);
4207 if (nbfd == NULL)
4208 return NULL;
4209
15e1c58a
TG
4210 bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype,
4211 &arch_type, &arch_subtype);
846b9259 4212
a4e241ca
TG
4213 bfd_mach_o_fat_member_init (nbfd, arch_type, arch_subtype, entry);
4214
846b9259 4215 bfd_set_arch_mach (nbfd, arch_type, arch_subtype);
3af9a47b 4216
15e1c58a 4217 return nbfd;
3af9a47b
NC
4218}
4219
15bbba8d
TG
4220/* Analogous to stat call. */
4221
4222static int
4223bfd_mach_o_fat_stat_arch_elt (bfd *abfd, struct stat *buf)
4224{
4225 if (abfd->arelt_data == NULL)
4226 {
4227 bfd_set_error (bfd_error_invalid_operation);
4228 return -1;
4229 }
4230
4231 buf->st_mtime = 0;
4232 buf->st_uid = 0;
4233 buf->st_gid = 0;
4234 buf->st_mode = 0644;
4235 buf->st_size = arelt_size (abfd);
4236
4237 return 0;
4238}
4239
846b9259
TG
4240/* If ABFD format is FORMAT and architecture is ARCH, return it.
4241 If ABFD is a fat image containing a member that corresponds to FORMAT
4242 and ARCH, returns it.
4243 In other case, returns NULL.
4244 This function allows transparent uses of fat images. */
a4e241ca 4245
846b9259
TG
4246bfd *
4247bfd_mach_o_fat_extract (bfd *abfd,
4248 bfd_format format,
4249 const bfd_arch_info_type *arch)
4250{
4251 bfd *res;
4252 mach_o_fat_data_struct *adata;
4253 unsigned int i;
4254
4255 if (bfd_check_format (abfd, format))
4256 {
4257 if (bfd_get_arch_info (abfd) == arch)
4258 return abfd;
4259 return NULL;
4260 }
4261 if (!bfd_check_format (abfd, bfd_archive)
4262 || abfd->xvec != &mach_o_fat_vec)
4263 return NULL;
c2f09c75 4264
846b9259
TG
4265 /* This is a Mach-O fat image. */
4266 adata = (mach_o_fat_data_struct *) abfd->tdata.mach_o_fat_data;
4267 BFD_ASSERT (adata != NULL);
4268
4269 for (i = 0; i < adata->nfat_arch; i++)
4270 {
4271 struct mach_o_fat_archentry *e = &adata->archentries[i];
4272 enum bfd_architecture cpu_type;
4273 unsigned long cpu_subtype;
4274
4275 bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype,
4276 &cpu_type, &cpu_subtype);
4277 if (cpu_type != arch->arch || cpu_subtype != arch->mach)
4278 continue;
4279
4280 /* The architecture is found. */
4281 res = _bfd_new_bfd_contained_in (abfd);
4282 if (res == NULL)
4283 return NULL;
4284
a4e241ca 4285 bfd_mach_o_fat_member_init (res, cpu_type, cpu_subtype, e);
846b9259
TG
4286
4287 if (bfd_check_format (res, format))
4288 {
4289 BFD_ASSERT (bfd_get_arch_info (res) == arch);
4290 return res;
4291 }
4292 bfd_close (res);
4293 return NULL;
4294 }
4295
4296 return NULL;
4297}
4298
3af9a47b 4299int
116c20d2
NC
4300bfd_mach_o_lookup_command (bfd *abfd,
4301 bfd_mach_o_load_command_type type,
4302 bfd_mach_o_load_command **mcommand)
3af9a47b 4303{
046b007d 4304 struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
3af9a47b
NC
4305 bfd_mach_o_load_command *ncmd = NULL;
4306 unsigned int i, num;
4307
3af9a47b
NC
4308 BFD_ASSERT (md != NULL);
4309 BFD_ASSERT (mcommand != NULL);
4310
4311 num = 0;
4312 for (i = 0; i < md->header.ncmds; i++)
4313 {
4314 struct bfd_mach_o_load_command *cmd = &md->commands[i];
4315
4316 if (cmd->type != type)
4317 continue;
4318
4319 if (num == 0)
4320 ncmd = cmd;
4321 num++;
4322 }
4323
4324 *mcommand = ncmd;
4325 return num;
4326}
4327
4328unsigned long
116c20d2 4329bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
3af9a47b
NC
4330{
4331 switch (type)
4332 {
4333 case BFD_MACH_O_CPU_TYPE_MC680x0:
4334 return 0x04000000;
4335 case BFD_MACH_O_CPU_TYPE_MC88000:
4336 return 0xffffe000;
4337 case BFD_MACH_O_CPU_TYPE_POWERPC:
4338 return 0xc0000000;
4339 case BFD_MACH_O_CPU_TYPE_I386:
4340 return 0xc0000000;
4341 case BFD_MACH_O_CPU_TYPE_SPARC:
4342 return 0xf0000000;
4343 case BFD_MACH_O_CPU_TYPE_I860:
4344 return 0;
4345 case BFD_MACH_O_CPU_TYPE_HPPA:
e84d6fca 4346 return 0xc0000000 - 0x04000000;
3af9a47b
NC
4347 default:
4348 return 0;
4349 }
4350}
4351
ab76eeaf
IS
4352/* The following two tables should be kept, as far as possible, in order of
4353 most frequently used entries to optimize their use from gas. */
4354
c5012cd8 4355const bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] =
046b007d
TG
4356{
4357 { "regular", BFD_MACH_O_S_REGULAR},
ab76eeaf 4358 { "coalesced", BFD_MACH_O_S_COALESCED},
046b007d
TG
4359 { "zerofill", BFD_MACH_O_S_ZEROFILL},
4360 { "cstring_literals", BFD_MACH_O_S_CSTRING_LITERALS},
4361 { "4byte_literals", BFD_MACH_O_S_4BYTE_LITERALS},
4362 { "8byte_literals", BFD_MACH_O_S_8BYTE_LITERALS},
ab76eeaf 4363 { "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS},
046b007d 4364 { "literal_pointers", BFD_MACH_O_S_LITERAL_POINTERS},
046b007d
TG
4365 { "mod_init_func_pointers", BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS},
4366 { "mod_fini_func_pointers", BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS},
046b007d
TG
4367 { "gb_zerofill", BFD_MACH_O_S_GB_ZEROFILL},
4368 { "interposing", BFD_MACH_O_S_INTERPOSING},
046b007d 4369 { "dtrace_dof", BFD_MACH_O_S_DTRACE_DOF},
ab76eeaf
IS
4370 { "non_lazy_symbol_pointers", BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS},
4371 { "lazy_symbol_pointers", BFD_MACH_O_S_LAZY_SYMBOL_POINTERS},
a4551119 4372 { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS},
046b007d
TG
4373 { "lazy_dylib_symbol_pointers", BFD_MACH_O_S_LAZY_DYLIB_SYMBOL_POINTERS},
4374 { NULL, 0}
4375};
4376
c5012cd8 4377const bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[] =
046b007d 4378{
ab76eeaf
IS
4379 { "pure_instructions", BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS },
4380 { "some_instructions", BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS },
046b007d
TG
4381 { "loc_reloc", BFD_MACH_O_S_ATTR_LOC_RELOC },
4382 { "ext_reloc", BFD_MACH_O_S_ATTR_EXT_RELOC },
046b007d 4383 { "debug", BFD_MACH_O_S_ATTR_DEBUG },
046b007d
TG
4384 { "live_support", BFD_MACH_O_S_ATTR_LIVE_SUPPORT },
4385 { "no_dead_strip", BFD_MACH_O_S_ATTR_NO_DEAD_STRIP },
4386 { "strip_static_syms", BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS },
4387 { "no_toc", BFD_MACH_O_S_ATTR_NO_TOC },
a4551119 4388 { "self_modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
ab76eeaf 4389 { "modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
046b007d
TG
4390 { NULL, 0}
4391};
4392
a4551119 4393/* Get the section type from NAME. Return 256 if NAME is unknown. */
53d58d96
TG
4394
4395unsigned int
ab76eeaf 4396bfd_mach_o_get_section_type_from_name (bfd *abfd, const char *name)
53d58d96 4397{
afbb9e17 4398 const bfd_mach_o_xlat_name *x;
ab76eeaf 4399 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
53d58d96
TG
4400
4401 for (x = bfd_mach_o_section_type_name; x->name; x++)
4402 if (strcmp (x->name, name) == 0)
ab76eeaf
IS
4403 {
4404 /* We found it... does the target support it? */
4405 if (bed->bfd_mach_o_section_type_valid_for_target == NULL
4406 || bed->bfd_mach_o_section_type_valid_for_target (x->val))
4407 return x->val; /* OK. */
4408 else
4409 break; /* Not supported. */
4410 }
a4551119
TG
4411 /* Maximum section ID = 0xff. */
4412 return 256;
53d58d96
TG
4413}
4414
4415/* Get the section attribute from NAME. Return -1 if NAME is unknown. */
4416
4417unsigned int
4418bfd_mach_o_get_section_attribute_from_name (const char *name)
4419{
afbb9e17 4420 const bfd_mach_o_xlat_name *x;
53d58d96
TG
4421
4422 for (x = bfd_mach_o_section_attribute_name; x->name; x++)
4423 if (strcmp (x->name, name) == 0)
4424 return x->val;
4425 return (unsigned int)-1;
4426}
4427
3af9a47b 4428int
116c20d2
NC
4429bfd_mach_o_core_fetch_environment (bfd *abfd,
4430 unsigned char **rbuf,
4431 unsigned int *rlen)
3af9a47b 4432{
046b007d 4433 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b
NC
4434 unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
4435 unsigned int i = 0;
4436
4437 for (i = 0; i < mdata->header.ncmds; i++)
4438 {
4439 bfd_mach_o_load_command *cur = &mdata->commands[i];
4440 bfd_mach_o_segment_command *seg = NULL;
4441
4442 if (cur->type != BFD_MACH_O_LC_SEGMENT)
4443 continue;
4444
4445 seg = &cur->command.segment;
4446
4447 if ((seg->vmaddr + seg->vmsize) == stackaddr)
4448 {
4449 unsigned long start = seg->fileoff;
4450 unsigned long end = seg->fileoff + seg->filesize;
4451 unsigned char *buf = bfd_malloc (1024);
4452 unsigned long size = 1024;
4453
4454 for (;;)
4455 {
4456 bfd_size_type nread = 0;
4457 unsigned long offset;
4458 int found_nonnull = 0;
4459
4460 if (size > (end - start))
4461 size = (end - start);
4462
515ef31d
NC
4463 buf = bfd_realloc_or_free (buf, size);
4464 if (buf == NULL)
4465 return -1;
c2f09c75
TG
4466
4467 if (bfd_seek (abfd, end - size, SEEK_SET) != 0)
4468 {
4469 free (buf);
4470 return -1;
4471 }
4472
3af9a47b 4473 nread = bfd_bread (buf, size, abfd);
a95a4550 4474
3af9a47b 4475 if (nread != size)
515ef31d
NC
4476 {
4477 free (buf);
4478 return -1;
4479 }
a95a4550 4480
3af9a47b
NC
4481 for (offset = 4; offset <= size; offset += 4)
4482 {
e84d6fca 4483 unsigned long val;
3af9a47b 4484
e84d6fca 4485 val = *((unsigned long *) (buf + size - offset));
3af9a47b
NC
4486 if (! found_nonnull)
4487 {
4488 if (val != 0)
4489 found_nonnull = 1;
4490 }
4491 else if (val == 0x0)
4492 {
e84d6fca
AM
4493 unsigned long bottom;
4494 unsigned long top;
3af9a47b 4495
e84d6fca
AM
4496 bottom = seg->fileoff + seg->filesize - offset;
4497 top = seg->fileoff + seg->filesize - 4;
3af9a47b
NC
4498 *rbuf = bfd_malloc (top - bottom);
4499 *rlen = top - bottom;
4500
4501 memcpy (*rbuf, buf + size - *rlen, *rlen);
515ef31d 4502 free (buf);
3af9a47b
NC
4503 return 0;
4504 }
4505 }
4506
4507 if (size == (end - start))
4508 break;
4509
4510 size *= 2;
4511 }
515ef31d
NC
4512
4513 free (buf);
3af9a47b
NC
4514 }
4515 }
4516
4517 return -1;
4518}
4519
4520char *
116c20d2 4521bfd_mach_o_core_file_failing_command (bfd *abfd)
3af9a47b
NC
4522{
4523 unsigned char *buf = NULL;
4524 unsigned int len = 0;
4525 int ret = -1;
4526
4527 ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
4528 if (ret < 0)
4529 return NULL;
4530
f075ee0c 4531 return (char *) buf;
3af9a47b
NC
4532}
4533
4534int
116c20d2 4535bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
3af9a47b
NC
4536{
4537 return 0;
4538}
4539
2ca7691a
TG
4540static bfd_mach_o_uuid_command *
4541bfd_mach_o_lookup_uuid_command (bfd *abfd)
4542{
4543 bfd_mach_o_load_command *uuid_cmd;
4544 int ncmd = bfd_mach_o_lookup_command (abfd, BFD_MACH_O_LC_UUID, &uuid_cmd);
4545 if (ncmd != 1)
4546 return FALSE;
4547 return &uuid_cmd->command.uuid;
4548}
4549
4550/* Return true if ABFD is a dSYM file and its UUID matches UUID_CMD. */
4551
4552static bfd_boolean
4553bfd_mach_o_dsym_for_uuid_p (bfd *abfd, const bfd_mach_o_uuid_command *uuid_cmd)
4554{
4555 bfd_mach_o_uuid_command *dsym_uuid_cmd;
4556
4557 BFD_ASSERT (abfd);
4558 BFD_ASSERT (uuid_cmd);
4559
4560 if (!bfd_check_format (abfd, bfd_object))
4561 return FALSE;
4562
4563 if (bfd_get_flavour (abfd) != bfd_target_mach_o_flavour
4564 || bfd_mach_o_get_data (abfd) == NULL
4565 || bfd_mach_o_get_data (abfd)->header.filetype != BFD_MACH_O_MH_DSYM)
4566 return FALSE;
4567
4568 dsym_uuid_cmd = bfd_mach_o_lookup_uuid_command (abfd);
4569 if (dsym_uuid_cmd == NULL)
4570 return FALSE;
4571
4572 if (memcmp (uuid_cmd->uuid, dsym_uuid_cmd->uuid,
4573 sizeof (uuid_cmd->uuid)) != 0)
4574 return FALSE;
4575
4576 return TRUE;
4577}
4578
4579/* Find a BFD in DSYM_FILENAME which matches ARCH and UUID_CMD.
4580 The caller is responsible for closing the returned BFD object and
4581 its my_archive if the returned BFD is in a fat dSYM. */
4582
4583static bfd *
4584bfd_mach_o_find_dsym (const char *dsym_filename,
4585 const bfd_mach_o_uuid_command *uuid_cmd,
4586 const bfd_arch_info_type *arch)
4587{
4588 bfd *base_dsym_bfd, *dsym_bfd;
4589
4590 BFD_ASSERT (uuid_cmd);
4591
4592 base_dsym_bfd = bfd_openr (dsym_filename, NULL);
4593 if (base_dsym_bfd == NULL)
4594 return NULL;
4595
4596 dsym_bfd = bfd_mach_o_fat_extract (base_dsym_bfd, bfd_object, arch);
4597 if (bfd_mach_o_dsym_for_uuid_p (dsym_bfd, uuid_cmd))
4598 return dsym_bfd;
4599
4600 bfd_close (dsym_bfd);
4601 if (base_dsym_bfd != dsym_bfd)
4602 bfd_close (base_dsym_bfd);
4603
4604 return NULL;
4605}
4606
4607/* Return a BFD created from a dSYM file for ABFD.
4608 The caller is responsible for closing the returned BFD object, its
4609 filename, and its my_archive if the returned BFD is in a fat dSYM. */
4610
4611static bfd *
4612bfd_mach_o_follow_dsym (bfd *abfd)
4613{
4614 char *dsym_filename;
4615 bfd_mach_o_uuid_command *uuid_cmd;
4616 bfd *dsym_bfd, *base_bfd = abfd;
4617 const char *base_basename;
4618
4619 if (abfd == NULL || bfd_get_flavour (abfd) != bfd_target_mach_o_flavour)
4620 return NULL;
4621
4622 if (abfd->my_archive)
4623 base_bfd = abfd->my_archive;
4624 /* BFD may have been opened from a stream. */
4625 if (base_bfd->filename == NULL)
4626 {
4627 bfd_set_error (bfd_error_invalid_operation);
4628 return NULL;
4629 }
4630 base_basename = lbasename (base_bfd->filename);
4631
4632 uuid_cmd = bfd_mach_o_lookup_uuid_command (abfd);
4633 if (uuid_cmd == NULL)
4634 return NULL;
4635
4636 /* TODO: We assume the DWARF file has the same as the binary's.
4637 It seems apple's GDB checks all files in the dSYM bundle directory.
4638 http://opensource.apple.com/source/gdb/gdb-1708/src/gdb/macosx/macosx-tdep.c
4639 */
4640 dsym_filename = (char *)bfd_malloc (strlen (base_bfd->filename)
4641 + strlen (dsym_subdir) + 1
4642 + strlen (base_basename) + 1);
4643 sprintf (dsym_filename, "%s%s/%s",
4644 base_bfd->filename, dsym_subdir, base_basename);
4645
4646 dsym_bfd = bfd_mach_o_find_dsym (dsym_filename, uuid_cmd,
4647 bfd_get_arch_info (abfd));
4648 if (dsym_bfd == NULL)
4649 free (dsym_filename);
4650
4651 return dsym_bfd;
4652}
4653
d9071b0c
TG
4654bfd_boolean
4655bfd_mach_o_find_nearest_line (bfd *abfd,
4656 asection *section,
4657 asymbol **symbols,
4658 bfd_vma offset,
4659 const char **filename_ptr,
4660 const char **functionname_ptr,
4661 unsigned int *line_ptr)
4662{
4663 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2ca7691a 4664 if (mdata == NULL)
d9071b0c 4665 return FALSE;
2ca7691a
TG
4666 switch (mdata->header.filetype)
4667 {
4668 case BFD_MACH_O_MH_OBJECT:
4669 break;
4670 case BFD_MACH_O_MH_EXECUTE:
4671 case BFD_MACH_O_MH_DYLIB:
4672 case BFD_MACH_O_MH_BUNDLE:
4673 case BFD_MACH_O_MH_KEXT_BUNDLE:
4674 if (mdata->dwarf2_find_line_info == NULL)
4675 {
4676 mdata->dsym_bfd = bfd_mach_o_follow_dsym (abfd);
4677 /* When we couldn't find dSYM for this binary, we look for
4678 the debug information in the binary itself. In this way,
4679 we won't try finding separated dSYM again because
4680 mdata->dwarf2_find_line_info will be filled. */
4681 if (! mdata->dsym_bfd)
4682 break;
4683 if (! _bfd_dwarf2_slurp_debug_info (abfd, mdata->dsym_bfd,
4684 dwarf_debug_sections, symbols,
4685 &mdata->dwarf2_find_line_info))
4686 return FALSE;
4687 }
4688 break;
4689 default:
4690 return FALSE;
4691 }
d9071b0c
TG
4692 if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections,
4693 section, symbols, offset,
4694 filename_ptr, functionname_ptr,
4695 line_ptr, 0,
4696 &mdata->dwarf2_find_line_info))
4697 return TRUE;
4698 return FALSE;
4699}
4700
4701bfd_boolean
4702bfd_mach_o_close_and_cleanup (bfd *abfd)
4703{
4704 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
4705 if (bfd_get_format (abfd) == bfd_object && mdata != NULL)
4434114c
TG
4706 {
4707 _bfd_dwarf2_cleanup_debug_info (abfd, &mdata->dwarf2_find_line_info);
4708 bfd_mach_o_free_cached_info (abfd);
2ca7691a
TG
4709 if (mdata->dsym_bfd != NULL)
4710 {
4711 bfd *fat_bfd = mdata->dsym_bfd->my_archive;
4712 char *dsym_filename = (char *)(fat_bfd
4713 ? fat_bfd->filename
4714 : mdata->dsym_bfd->filename);
4715 bfd_close (mdata->dsym_bfd);
4716 mdata->dsym_bfd = NULL;
4717 if (fat_bfd)
4718 bfd_close (fat_bfd);
4719 free (dsym_filename);
4720 }
4434114c 4721 }
dff55db0 4722
d9071b0c
TG
4723 return _bfd_generic_close_and_cleanup (abfd);
4724}
4725
dff55db0
TG
4726bfd_boolean bfd_mach_o_free_cached_info (bfd *abfd)
4727{
4728 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
4729 asection *asect;
4730 free (mdata->dyn_reloc_cache);
4731 mdata->dyn_reloc_cache = NULL;
4732 for (asect = abfd->sections; asect != NULL; asect = asect->next)
4733 {
4734 free (asect->relocation);
4735 asect->relocation = NULL;
4736 }
4737
4738 return TRUE;
4739}
4740
92bc0e80
TG
4741#define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
4742#define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
4743
4744#define bfd_mach_o_swap_reloc_in NULL
4745#define bfd_mach_o_swap_reloc_out NULL
b32e07d7 4746#define bfd_mach_o_print_thread NULL
a4551119 4747#define bfd_mach_o_tgt_seg_table NULL
ab76eeaf 4748#define bfd_mach_o_section_type_valid_for_tgt NULL
92bc0e80 4749
116c20d2
NC
4750#define TARGET_NAME mach_o_be_vec
4751#define TARGET_STRING "mach-o-be"
42fa0891 4752#define TARGET_ARCHITECTURE bfd_arch_unknown
116c20d2
NC
4753#define TARGET_BIG_ENDIAN 1
4754#define TARGET_ARCHIVE 0
b93a1992 4755#define TARGET_PRIORITY 1
3af9a47b
NC
4756#include "mach-o-target.c"
4757
4758#undef TARGET_NAME
4759#undef TARGET_STRING
42fa0891 4760#undef TARGET_ARCHITECTURE
3af9a47b
NC
4761#undef TARGET_BIG_ENDIAN
4762#undef TARGET_ARCHIVE
b93a1992 4763#undef TARGET_PRIORITY
3af9a47b 4764
116c20d2
NC
4765#define TARGET_NAME mach_o_le_vec
4766#define TARGET_STRING "mach-o-le"
42fa0891 4767#define TARGET_ARCHITECTURE bfd_arch_unknown
116c20d2
NC
4768#define TARGET_BIG_ENDIAN 0
4769#define TARGET_ARCHIVE 0
b93a1992 4770#define TARGET_PRIORITY 1
3af9a47b
NC
4771
4772#include "mach-o-target.c"
4773
4774#undef TARGET_NAME
4775#undef TARGET_STRING
42fa0891 4776#undef TARGET_ARCHITECTURE
3af9a47b
NC
4777#undef TARGET_BIG_ENDIAN
4778#undef TARGET_ARCHIVE
b93a1992 4779#undef TARGET_PRIORITY
3af9a47b 4780
8f95b6e4
TG
4781/* Not yet handled: creating an archive. */
4782#define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive
4783
4784/* Not used. */
4785#define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr
4786#define bfd_mach_o_write_ar_hdr _bfd_noarchive_write_ar_hdr
4787#define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap
4788#define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
4789#define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
4790#define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname
4791#define bfd_mach_o_write_armap _bfd_noarchive_write_armap
4792#define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index
15bbba8d 4793#define bfd_mach_o_generic_stat_arch_elt bfd_mach_o_fat_stat_arch_elt
8f95b6e4
TG
4794#define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
4795
116c20d2
NC
4796#define TARGET_NAME mach_o_fat_vec
4797#define TARGET_STRING "mach-o-fat"
42fa0891 4798#define TARGET_ARCHITECTURE bfd_arch_unknown
116c20d2
NC
4799#define TARGET_BIG_ENDIAN 1
4800#define TARGET_ARCHIVE 1
b93a1992 4801#define TARGET_PRIORITY 0
3af9a47b
NC
4802
4803#include "mach-o-target.c"
4804
4805#undef TARGET_NAME
4806#undef TARGET_STRING
42fa0891 4807#undef TARGET_ARCHITECTURE
3af9a47b
NC
4808#undef TARGET_BIG_ENDIAN
4809#undef TARGET_ARCHIVE
b93a1992 4810#undef TARGET_PRIORITY
This page took 1.106461 seconds and 4 git commands to generate.