bfd/
[deliverable/binutils-gdb.git] / bfd / mach-o.c
CommitLineData
3af9a47b 1/* Mach-O support for BFD.
4f608e79 2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
4a97a0e5 3 2009, 2010, 2011
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
NC
31#include <ctype.h>
32
154a1ee5
TG
33#define bfd_mach_o_object_p bfd_mach_o_gen_object_p
34#define bfd_mach_o_core_p bfd_mach_o_gen_core_p
42fa0891 35#define bfd_mach_o_mkobject bfd_mach_o_gen_mkobject
116c20d2 36
92bc0e80
TG
37#define FILE_ALIGN(off, algn) \
38 (((off) + ((file_ptr) 1 << (algn)) - 1) & ((file_ptr) -1 << (algn)))
39
c2f09c75 40unsigned int
1e8a024a
TG
41bfd_mach_o_version (bfd *abfd)
42{
43 bfd_mach_o_data_struct *mdata = NULL;
44
45 BFD_ASSERT (bfd_mach_o_valid (abfd));
046b007d 46 mdata = bfd_mach_o_get_data (abfd);
1e8a024a
TG
47
48 return mdata->header.version;
49}
50
b34976b6 51bfd_boolean
116c20d2 52bfd_mach_o_valid (bfd *abfd)
3af9a47b
NC
53{
54 if (abfd == NULL || abfd->xvec == NULL)
154a1ee5 55 return FALSE;
3af9a47b 56
154a1ee5
TG
57 if (abfd->xvec->flavour != bfd_target_mach_o_flavour)
58 return FALSE;
3af9a47b 59
046b007d 60 if (bfd_mach_o_get_data (abfd) == NULL)
154a1ee5
TG
61 return FALSE;
62 return TRUE;
63}
64
c2f09c75
TG
65static INLINE bfd_boolean
66mach_o_wide_p (bfd_mach_o_header *header)
67{
68 switch (header->version)
69 {
70 case 1:
71 return FALSE;
72 case 2:
73 return TRUE;
74 default:
75 BFD_FAIL ();
76 return FALSE;
77 }
78}
79
80static INLINE bfd_boolean
81bfd_mach_o_wide_p (bfd *abfd)
82{
046b007d 83 return mach_o_wide_p (&bfd_mach_o_get_data (abfd)->header);
c2f09c75
TG
84}
85
154a1ee5
TG
86/* Tables to translate well known Mach-O segment/section names to bfd
87 names. Use of canonical names (such as .text or .debug_frame) is required
88 by gdb. */
89
a4551119
TG
90/* __TEXT Segment. */
91static const mach_o_section_name_xlat text_section_names_xlat[] =
154a1ee5 92 {
a4551119
TG
93 { ".text", "__text",
94 SEC_CODE | SEC_LOAD, BFD_MACH_O_S_REGULAR,
95 BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS, 0},
96 { ".const", "__const",
97 SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
98 BFD_MACH_O_S_ATTR_NONE, 0},
99 { ".static_const", "__static_const",
100 SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
101 BFD_MACH_O_S_ATTR_NONE, 0},
102 { ".cstring", "__cstring",
103 SEC_READONLY | SEC_DATA | SEC_LOAD | SEC_MERGE | SEC_STRINGS,
104 BFD_MACH_O_S_CSTRING_LITERALS,
105 BFD_MACH_O_S_ATTR_NONE, 0},
106 { ".literal4", "__literal4",
107 SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_4BYTE_LITERALS,
108 BFD_MACH_O_S_ATTR_NONE, 2},
109 { ".literal8", "__literal8",
110 SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_8BYTE_LITERALS,
111 BFD_MACH_O_S_ATTR_NONE, 3},
112 { ".literal16", "__literal16",
113 SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_16BYTE_LITERALS,
114 BFD_MACH_O_S_ATTR_NONE, 4},
115 { ".constructor", "__constructor",
116 SEC_CODE | SEC_LOAD, BFD_MACH_O_S_REGULAR,
117 BFD_MACH_O_S_ATTR_NONE, 0},
118 { ".destructor", "__destructor",
119 SEC_CODE | SEC_LOAD, BFD_MACH_O_S_REGULAR,
120 BFD_MACH_O_S_ATTR_NONE, 0},
121 { ".eh_frame", "__eh_frame",
122 SEC_READONLY | SEC_LOAD, BFD_MACH_O_S_COALESCED,
123 BFD_MACH_O_S_ATTR_LIVE_SUPPORT
124 | BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS
125 | BFD_MACH_O_S_ATTR_NO_TOC, 3},
126 { NULL, NULL, 0, 0, 0, 0}
154a1ee5
TG
127 };
128
a4551119
TG
129/* __DATA Segment. */
130static const mach_o_section_name_xlat data_section_names_xlat[] =
154a1ee5 131 {
a4551119
TG
132 { ".data", "__data",
133 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
134 BFD_MACH_O_S_ATTR_NONE, 0},
135 { ".bss", "__bss",
136 SEC_NO_FLAGS, BFD_MACH_O_S_ZEROFILL,
137 BFD_MACH_O_S_ATTR_NONE, 0},
138 { ".const_data", "__const",
139 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
140 BFD_MACH_O_S_ATTR_NONE, 0},
141 { ".static_data", "__static_data",
142 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
143 BFD_MACH_O_S_ATTR_NONE, 0},
144 { ".mod_init_func", "__mod_init_func",
145 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS,
146 BFD_MACH_O_S_ATTR_NONE, 2},
147 { ".mod_term_func", "__mod_term_func",
148 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS,
149 BFD_MACH_O_S_ATTR_NONE, 2},
150 { ".dyld", "__dyld",
151 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
152 BFD_MACH_O_S_ATTR_NONE, 0},
153 { ".cfstring", "__cfstring",
154 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
155 BFD_MACH_O_S_ATTR_NONE, 2},
156 { NULL, NULL, 0, 0, 0, 0}
154a1ee5
TG
157 };
158
a4551119
TG
159/* __DWARF Segment. */
160static const mach_o_section_name_xlat dwarf_section_names_xlat[] =
154a1ee5 161 {
a4551119
TG
162 { ".debug_frame", "__debug_frame",
163 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
164 BFD_MACH_O_S_ATTR_DEBUG, 0},
165 { ".debug_info", "__debug_info",
166 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
167 BFD_MACH_O_S_ATTR_DEBUG, 0},
168 { ".debug_abbrev", "__debug_abbrev",
169 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
170 BFD_MACH_O_S_ATTR_DEBUG, 0},
171 { ".debug_aranges", "__debug_aranges",
172 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
173 BFD_MACH_O_S_ATTR_DEBUG, 0},
174 { ".debug_macinfo", "__debug_macinfo",
175 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
176 BFD_MACH_O_S_ATTR_DEBUG, 0},
177 { ".debug_line", "__debug_line",
178 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
179 BFD_MACH_O_S_ATTR_DEBUG, 0},
180 { ".debug_loc", "__debug_loc",
181 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
182 BFD_MACH_O_S_ATTR_DEBUG, 0},
183 { ".debug_pubnames", "__debug_pubnames",
184 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
185 BFD_MACH_O_S_ATTR_DEBUG, 0},
186 { ".debug_pubtypes", "__debug_pubtypes",
187 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
188 BFD_MACH_O_S_ATTR_DEBUG, 0},
189 { ".debug_str", "__debug_str",
190 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
191 BFD_MACH_O_S_ATTR_DEBUG, 0},
192 { ".debug_ranges", "__debug_ranges",
193 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
194 BFD_MACH_O_S_ATTR_DEBUG, 0},
195 { ".debug_macro", "__debug_macro",
196 SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
197 BFD_MACH_O_S_ATTR_DEBUG, 0},
198 { NULL, NULL, 0, 0, 0, 0}
154a1ee5
TG
199 };
200
a4551119
TG
201/* __OBJC Segment. */
202static const mach_o_section_name_xlat objc_section_names_xlat[] =
203 {
204 { ".objc_class", "__class",
205 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
206 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
207 { ".objc_meta_class", "__meta_class",
208 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
209 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
210 { ".objc_cat_cls_meth", "__cat_cls_meth",
211 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
212 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
213 { ".objc_cat_inst_meth", "__cat_inst_meth",
214 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
215 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
216 { ".objc_protocol", "__protocol",
217 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
218 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
219 { ".objc_string_object", "__string_object",
220 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
221 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
222 { ".objc_cls_meth", "__cls_meth",
223 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
224 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
225 { ".objc_inst_meth", "__inst_meth",
226 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
227 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
228 { ".objc_cls_refs", "__cls_refs",
229 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_LITERAL_POINTERS,
230 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
231 { ".objc_message_refs", "__message_refs",
232 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_LITERAL_POINTERS,
233 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
234 { ".objc_symbols", "__symbols",
235 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
236 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
237 { ".objc_category", "__category",
238 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
239 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
240 { ".objc_class_vars", "__class_vars",
241 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
242 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
243 { ".objc_instance_vars", "__instance_vars",
244 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
245 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
246 { ".objc_module_info", "__module_info",
247 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
248 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
249 { ".objc_selector_strs", "__selector_strs",
250 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_CSTRING_LITERALS,
251 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
252 { ".objc_image_info", "__image_info",
253 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
254 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
255 { ".objc_selector_fixup", "__sel_fixup",
256 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
257 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
258 /* Objc V1 */
259 { ".objc1_class_ext", "__class_ext",
260 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
261 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
262 { ".objc1_property_list", "__property",
263 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
264 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
265 { ".objc1_protocol_ext", "__protocol_ext",
266 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
267 BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
268 { NULL, NULL, 0, 0, 0, 0}
269 };
5a5cbf72 270
a4551119 271static const mach_o_segment_name_xlat segsec_names_xlat[] =
154a1ee5 272 {
154a1ee5
TG
273 { "__TEXT", text_section_names_xlat },
274 { "__DATA", data_section_names_xlat },
5a5cbf72 275 { "__DWARF", dwarf_section_names_xlat },
a4551119 276 { "__OBJC", objc_section_names_xlat },
154a1ee5
TG
277 { NULL, NULL }
278 };
279
a4551119
TG
280/* For both cases bfd-name => mach-o name and vice versa, the specific target
281 is checked before the generic. This allows a target (e.g. ppc for cstring)
282 to override the generic definition with a more specific one. */
154a1ee5 283
a4551119
TG
284/* Fetch the translation from a Mach-O section designation (segment, section)
285 as a bfd short name, if one exists. Otherwise return NULL.
286
287 Allow the segment and section names to be unterminated 16 byte arrays. */
288
289const mach_o_section_name_xlat *
290bfd_mach_o_section_data_for_mach_sect (bfd *abfd, const char *segname,
291 const char *sectname)
154a1ee5
TG
292{
293 const struct mach_o_segment_name_xlat *seg;
a4551119
TG
294 const mach_o_section_name_xlat *sec;
295 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
154a1ee5 296
a4551119
TG
297 /* First try any target-specific translations defined... */
298 if (bed->segsec_names_xlat)
299 for (seg = bed->segsec_names_xlat; seg->segname; seg++)
300 if (strncmp (seg->segname, segname, BFD_MACH_O_SEGNAME_SIZE) == 0)
301 for (sec = seg->sections; sec->mach_o_name; sec++)
302 if (strncmp (sec->mach_o_name, sectname,
303 BFD_MACH_O_SECTNAME_SIZE) == 0)
304 return sec;
8462aec7 305
a4551119 306 /* ... and then the Mach-O generic ones. */
154a1ee5 307 for (seg = segsec_names_xlat; seg->segname; seg++)
a4551119
TG
308 if (strncmp (seg->segname, segname, BFD_MACH_O_SEGNAME_SIZE) == 0)
309 for (sec = seg->sections; sec->mach_o_name; sec++)
310 if (strncmp (sec->mach_o_name, sectname,
311 BFD_MACH_O_SECTNAME_SIZE) == 0)
312 return sec;
154a1ee5 313
a4551119 314 return NULL;
53d58d96
TG
315}
316
a4551119
TG
317/* If the bfd_name for this section is a 'canonical' form for which we
318 know the Mach-O data, return the segment name and the data for the
319 Mach-O equivalent. Otherwise return NULL. */
7ba695a9 320
a4551119
TG
321const mach_o_section_name_xlat *
322bfd_mach_o_section_data_for_bfd_name (bfd *abfd, const char *bfd_name,
323 const char **segname)
53d58d96 324{
a4551119
TG
325 const struct mach_o_segment_name_xlat *seg;
326 const mach_o_section_name_xlat *sec;
327 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
328 *segname = NULL;
329
330 if (bfd_name[0] != '.')
331 return NULL;
332
333 /* First try any target-specific translations defined... */
334 if (bed->segsec_names_xlat)
335 for (seg = bed->segsec_names_xlat; seg->segname; seg++)
336 for (sec = seg->sections; sec->bfd_name; sec++)
337 if (strcmp (bfd_name, sec->bfd_name) == 0)
338 {
339 *segname = seg->segname;
340 return sec;
341 }
342
343 /* ... and then the Mach-O generic ones. */
344 for (seg = segsec_names_xlat; seg->segname; seg++)
345 for (sec = seg->sections; sec->bfd_name; sec++)
346 if (strcmp (bfd_name, sec->bfd_name) == 0)
347 {
348 *segname = seg->segname;
349 return sec;
350 }
351
352 return NULL;
353}
354
355/* Convert Mach-O section name to BFD.
356
357 Try to use standard/canonical names, for which we have tables including
358 default flag settings - which are returned. Otherwise forge a new name
359 in the form "<segmentname>.<sectionname>" this will be prefixed with
360 LC_SEGMENT. if the segment name does not begin with an underscore.
361
362 SEGNAME and SECTNAME are 16 byte arrays (they do not need to be NUL-
363 terminated if the name length is exactly 16 bytes - but must be if the name
364 length is less than 16 characters). */
365
366void
367bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, const char *segname,
368 const char *secname, const char **name,
369 flagword *flags)
370{
371 const mach_o_section_name_xlat *xlat;
53d58d96
TG
372 char *res;
373 unsigned int len;
374 const char *pfx = "";
375
a4551119
TG
376 *name = NULL;
377 *flags = SEC_NO_FLAGS;
53d58d96 378
a4551119
TG
379 /* First search for a canonical name...
380 xlat will be non-null if there is an entry for segname, secname. */
381 xlat = bfd_mach_o_section_data_for_mach_sect (abfd, segname, secname);
382 if (xlat)
383 {
384 len = strlen (xlat->bfd_name);
385 res = bfd_alloc (abfd, len+1);
386 if (res == NULL)
387 return;
388 memcpy (res, xlat->bfd_name, len+1);
389 *name = res;
390 *flags = xlat->bfd_flags;
391 return;
392 }
393
394 /* ... else we make up a bfd name from the segment concatenated with the
395 section. */
154a1ee5 396
7ba695a9 397 len = 16 + 1 + 16 + 1;
154a1ee5 398
c2f09c75
TG
399 /* Put "LC_SEGMENT." prefix if the segment name is weird (ie doesn't start
400 with an underscore. */
f1bde64c 401 if (segname[0] != '_')
c2f09c75
TG
402 {
403 static const char seg_pfx[] = "LC_SEGMENT.";
404
405 pfx = seg_pfx;
406 len += sizeof (seg_pfx) - 1;
407 }
408
154a1ee5
TG
409 res = bfd_alloc (abfd, len);
410 if (res == NULL)
8462aec7 411 return;
a4551119 412 snprintf (res, len, "%s%.16s.%.16s", pfx, segname, secname);
8462aec7 413 *name = res;
154a1ee5
TG
414}
415
a4551119 416/* Convert a bfd section name to a Mach-O segment + section name.
154a1ee5 417
a4551119
TG
418 If the name is a canonical one for which we have a Darwin match
419 return the translation table - which contains defaults for flags,
420 type, attribute and default alignment data.
421
422 Otherwise, expand the bfd_name (assumed to be in the form
423 "[LC_SEGMENT.]<segmentname>.<sectionname>") and return NULL. */
424
425static const mach_o_section_name_xlat *
154a1ee5
TG
426bfd_mach_o_convert_section_name_to_mach_o (bfd *abfd ATTRIBUTE_UNUSED,
427 asection *sect,
428 bfd_mach_o_section *section)
429{
a4551119 430 const mach_o_section_name_xlat *xlat;
154a1ee5 431 const char *name = bfd_get_section_name (abfd, sect);
a4551119 432 const char *segname;
154a1ee5
TG
433 const char *dot;
434 unsigned int len;
435 unsigned int seglen;
436 unsigned int seclen;
437
a4551119
TG
438 memset (section->segname, 0, BFD_MACH_O_SEGNAME_SIZE + 1);
439 memset (section->sectname, 0, BFD_MACH_O_SECTNAME_SIZE + 1);
440
441 /* See if is a canonical name ... */
442 xlat = bfd_mach_o_section_data_for_bfd_name (abfd, name, &segname);
443 if (xlat)
444 {
445 strcpy (section->segname, segname);
446 strcpy (section->sectname, xlat->mach_o_name);
447 return xlat;
448 }
154a1ee5 449
a4551119
TG
450 /* .. else we convert our constructed one back to Mach-O.
451 Strip LC_SEGMENT. prefix, if present. */
154a1ee5
TG
452 if (strncmp (name, "LC_SEGMENT.", 11) == 0)
453 name += 11;
454
455 /* Find a dot. */
456 dot = strchr (name, '.');
457 len = strlen (name);
458
459 /* Try to split name into segment and section names. */
460 if (dot && dot != name)
461 {
462 seglen = dot - name;
463 seclen = len - (dot + 1 - name);
464
465 if (seglen < 16 && seclen < 16)
466 {
467 memcpy (section->segname, name, seglen);
468 section->segname[seglen] = 0;
469 memcpy (section->sectname, dot + 1, seclen);
470 section->sectname[seclen] = 0;
a4551119 471 return NULL;
154a1ee5
TG
472 }
473 }
474
a4551119
TG
475 /* The segment and section names are both missing - don't make them
476 into dots. */
477 if (dot && dot == name)
478 return NULL;
479
480 /* Just duplicate the name into both segment and section. */
154a1ee5
TG
481 if (len > 16)
482 len = 16;
483 memcpy (section->segname, name, len);
484 section->segname[len] = 0;
485 memcpy (section->sectname, name, len);
486 section->sectname[len] = 0;
a4551119 487 return NULL;
3af9a47b
NC
488}
489
b2b62060
TG
490/* Return the size of an entry for section SEC.
491 Must be called only for symbol pointer section and symbol stubs
492 sections. */
493
c5012cd8 494unsigned int
b2b62060
TG
495bfd_mach_o_section_get_entry_size (bfd *abfd, bfd_mach_o_section *sec)
496{
497 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
498 {
499 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
500 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
501 return bfd_mach_o_wide_p (abfd) ? 8 : 4;
502 case BFD_MACH_O_S_SYMBOL_STUBS:
503 return sec->reserved2;
504 default:
505 BFD_FAIL ();
506 return 0;
507 }
508}
509
510/* Return the number of indirect symbols for a section.
511 Must be called only for symbol pointer section and symbol stubs
512 sections. */
513
c5012cd8 514unsigned int
b2b62060
TG
515bfd_mach_o_section_get_nbr_indirect (bfd *abfd, bfd_mach_o_section *sec)
516{
517 unsigned int elsz;
518
519 elsz = bfd_mach_o_section_get_entry_size (abfd, sec);
520 if (elsz == 0)
521 return 0;
522 else
523 return sec->size / elsz;
524}
525
526
3af9a47b
NC
527/* Copy any private info we understand from the input symbol
528 to the output symbol. */
529
154a1ee5 530bfd_boolean
116c20d2
NC
531bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
532 asymbol *isymbol ATTRIBUTE_UNUSED,
533 bfd *obfd ATTRIBUTE_UNUSED,
534 asymbol *osymbol ATTRIBUTE_UNUSED)
3af9a47b 535{
b34976b6 536 return TRUE;
3af9a47b
NC
537}
538
539/* Copy any private info we understand from the input section
540 to the output section. */
541
154a1ee5 542bfd_boolean
116c20d2 543bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
a4551119 544 asection *isection,
116c20d2 545 bfd *obfd ATTRIBUTE_UNUSED,
a4551119
TG
546 asection *osection)
547{
548 if (osection->used_by_bfd == NULL)
549 osection->used_by_bfd = isection->used_by_bfd;
550 else
551 if (isection->used_by_bfd != NULL)
552 memcpy (osection->used_by_bfd, isection->used_by_bfd,
553 sizeof (bfd_mach_o_section));
554
555 if (osection->used_by_bfd != NULL)
556 ((bfd_mach_o_section *)osection->used_by_bfd)->bfdsection = osection;
557
b34976b6 558 return TRUE;
3af9a47b
NC
559}
560
561/* Copy any private info we understand from the input bfd
562 to the output bfd. */
563
154a1ee5 564bfd_boolean
116c20d2 565bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
3af9a47b 566{
154a1ee5
TG
567 if (bfd_get_flavour (ibfd) != bfd_target_mach_o_flavour
568 || bfd_get_flavour (obfd) != bfd_target_mach_o_flavour)
569 return TRUE;
570
3af9a47b
NC
571 BFD_ASSERT (bfd_mach_o_valid (ibfd));
572 BFD_ASSERT (bfd_mach_o_valid (obfd));
573
154a1ee5
TG
574 /* FIXME: copy commands. */
575
b34976b6 576 return TRUE;
3af9a47b
NC
577}
578
0c9ef0f0
TG
579/* This allows us to set up to 32 bits of flags (unless we invent some
580 fiendish scheme to subdivide). For now, we'll just set the file flags
581 without error checking - just overwrite. */
582
583bfd_boolean
584bfd_mach_o_bfd_set_private_flags (bfd *abfd, flagword flags)
585{
586 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
587
588 if (!mdata)
589 return FALSE;
590
591 mdata->header.flags = flags;
592 return TRUE;
593}
594
046b007d 595/* Count the total number of symbols. */
154a1ee5 596
3af9a47b 597static long
116c20d2 598bfd_mach_o_count_symbols (bfd *abfd)
3af9a47b 599{
046b007d 600 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 601
046b007d
TG
602 if (mdata->symtab == NULL)
603 return 0;
604 return mdata->symtab->nsyms;
3af9a47b
NC
605}
606
154a1ee5 607long
116c20d2 608bfd_mach_o_get_symtab_upper_bound (bfd *abfd)
3af9a47b
NC
609{
610 long nsyms = bfd_mach_o_count_symbols (abfd);
611
3af9a47b
NC
612 return ((nsyms + 1) * sizeof (asymbol *));
613}
614
154a1ee5 615long
116c20d2 616bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
3af9a47b 617{
046b007d 618 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 619 long nsyms = bfd_mach_o_count_symbols (abfd);
046b007d
TG
620 bfd_mach_o_symtab_command *sym = mdata->symtab;
621 unsigned long j;
3af9a47b
NC
622
623 if (nsyms < 0)
624 return nsyms;
625
092d27ff
TG
626 if (nsyms == 0)
627 {
628 /* Do not try to read symbols if there are none. */
629 alocation[0] = NULL;
630 return 0;
631 }
632
afbb9e17 633 if (!bfd_mach_o_read_symtab_symbols (abfd))
3af9a47b 634 {
afbb9e17
TG
635 (*_bfd_error_handler)
636 (_("bfd_mach_o_canonicalize_symtab: unable to load symbols"));
046b007d
TG
637 return 0;
638 }
3af9a47b 639
046b007d 640 BFD_ASSERT (sym->symbols != NULL);
3af9a47b 641
046b007d
TG
642 for (j = 0; j < sym->nsyms; j++)
643 alocation[j] = &sym->symbols[j].symbol;
3af9a47b 644
046b007d 645 alocation[j] = NULL;
a95a4550 646
3af9a47b
NC
647 return nsyms;
648}
649
b2b62060
TG
650long
651bfd_mach_o_get_synthetic_symtab (bfd *abfd,
652 long symcount ATTRIBUTE_UNUSED,
653 asymbol **syms ATTRIBUTE_UNUSED,
654 long dynsymcount ATTRIBUTE_UNUSED,
655 asymbol **dynsyms ATTRIBUTE_UNUSED,
656 asymbol **ret)
657{
658 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
659 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
660 bfd_mach_o_symtab_command *symtab = mdata->symtab;
661 asymbol *s;
662 unsigned long count, i, j, n;
663 size_t size;
664 char *names;
665 char *nul_name;
666
667 *ret = NULL;
668
669 if (dysymtab == NULL || symtab == NULL || symtab->symbols == NULL)
670 return 0;
671
672 if (dysymtab->nindirectsyms == 0)
673 return 0;
674
675 count = dysymtab->nindirectsyms;
676 size = count * sizeof (asymbol) + 1;
677
678 for (j = 0; j < count; j++)
679 {
680 unsigned int isym = dysymtab->indirect_syms[j];
681
682 if (isym < symtab->nsyms && symtab->symbols[isym].symbol.name)
683 size += strlen (symtab->symbols[isym].symbol.name) + sizeof ("$stub");
684 }
685
686 s = *ret = (asymbol *) bfd_malloc (size);
687 if (s == NULL)
688 return -1;
689 names = (char *) (s + count);
690 nul_name = names;
691 *names++ = 0;
692
693 n = 0;
694 for (i = 0; i < mdata->nsects; i++)
695 {
696 bfd_mach_o_section *sec = mdata->sections[i];
91d6fa6a 697 unsigned int first, last;
b2b62060
TG
698 bfd_vma addr;
699 bfd_vma entry_size;
700
701 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
702 {
703 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
704 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
705 case BFD_MACH_O_S_SYMBOL_STUBS:
706 first = sec->reserved1;
707 last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
708 addr = sec->addr;
709 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
710 for (j = first; j < last; j++)
711 {
712 unsigned int isym = dysymtab->indirect_syms[j];
713
714 s->flags = BSF_GLOBAL | BSF_SYNTHETIC;
715 s->section = sec->bfdsection;
716 s->value = addr - sec->addr;
717 s->udata.p = NULL;
718
719 if (isym < symtab->nsyms
720 && symtab->symbols[isym].symbol.name)
721 {
722 const char *sym = symtab->symbols[isym].symbol.name;
723 size_t len;
724
725 s->name = names;
726 len = strlen (sym);
727 memcpy (names, sym, len);
728 names += len;
729 memcpy (names, "$stub", sizeof ("$stub"));
730 names += sizeof ("$stub");
731 }
732 else
733 s->name = nul_name;
734
735 addr += entry_size;
736 s++;
737 n++;
738 }
739 break;
740 default:
741 break;
742 }
743 }
744
745 return n;
746}
747
154a1ee5 748void
116c20d2
NC
749bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
750 asymbol *symbol,
751 symbol_info *ret)
3af9a47b
NC
752{
753 bfd_symbol_info (symbol, ret);
754}
755
154a1ee5 756void
116c20d2 757bfd_mach_o_print_symbol (bfd *abfd,
91d6fa6a 758 void * afile,
116c20d2
NC
759 asymbol *symbol,
760 bfd_print_symbol_type how)
3af9a47b
NC
761{
762 FILE *file = (FILE *) afile;
15e1c58a 763 const char *name;
92bc0e80 764 bfd_mach_o_asymbol *asym = (bfd_mach_o_asymbol *)symbol;
3af9a47b
NC
765
766 switch (how)
767 {
768 case bfd_print_symbol_name:
769 fprintf (file, "%s", symbol->name);
770 break;
771 default:
91d6fa6a 772 bfd_print_symbol_vandf (abfd, (void *) file, symbol);
92bc0e80
TG
773 if (asym->n_type & BFD_MACH_O_N_STAB)
774 name = bfd_get_stab_name (asym->n_type);
15e1c58a 775 else
92bc0e80 776 switch (asym->n_type & BFD_MACH_O_N_TYPE)
15e1c58a
TG
777 {
778 case BFD_MACH_O_N_UNDF:
e0ce1005
TG
779 if (symbol->value == 0)
780 name = "UND";
781 else
782 name = "COM";
15e1c58a
TG
783 break;
784 case BFD_MACH_O_N_ABS:
785 name = "ABS";
786 break;
787 case BFD_MACH_O_N_INDR:
788 name = "INDR";
789 break;
790 case BFD_MACH_O_N_PBUD:
791 name = "PBUD";
792 break;
793 case BFD_MACH_O_N_SECT:
794 name = "SECT";
795 break;
796 default:
797 name = "???";
798 break;
799 }
800 if (name == NULL)
801 name = "";
92bc0e80
TG
802 fprintf (file, " %02x %-6s %02x %04x",
803 asym->n_type, name, asym->n_sect, asym->n_desc);
804 if ((asym->n_type & BFD_MACH_O_N_STAB) == 0
805 && (asym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_SECT)
e0ce1005 806 fprintf (file, " [%s]", symbol->section->name);
15e1c58a 807 fprintf (file, " %s", symbol->name);
3af9a47b
NC
808 }
809}
810
811static void
116c20d2
NC
812bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype,
813 bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED,
814 enum bfd_architecture *type,
815 unsigned long *subtype)
3af9a47b
NC
816{
817 *subtype = bfd_arch_unknown;
818
819 switch (mtype)
820 {
821 case BFD_MACH_O_CPU_TYPE_VAX: *type = bfd_arch_vax; break;
822 case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
1e8a024a
TG
823 case BFD_MACH_O_CPU_TYPE_I386:
824 *type = bfd_arch_i386;
825 *subtype = bfd_mach_i386_i386;
826 break;
827 case BFD_MACH_O_CPU_TYPE_X86_64:
828 *type = bfd_arch_i386;
829 *subtype = bfd_mach_x86_64;
830 break;
3af9a47b
NC
831 case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
832 case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;
833 case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
834 case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
835 case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;
1e8a024a
TG
836 case BFD_MACH_O_CPU_TYPE_SPARC:
837 *type = bfd_arch_sparc;
838 *subtype = bfd_mach_sparc;
839 break;
3af9a47b
NC
840 case BFD_MACH_O_CPU_TYPE_I860: *type = bfd_arch_i860; break;
841 case BFD_MACH_O_CPU_TYPE_ALPHA: *type = bfd_arch_alpha; break;
1e8a024a
TG
842 case BFD_MACH_O_CPU_TYPE_POWERPC:
843 *type = bfd_arch_powerpc;
c2f09c75 844 *subtype = bfd_mach_ppc;
1e8a024a
TG
845 break;
846 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
847 *type = bfd_arch_powerpc;
c2f09c75 848 *subtype = bfd_mach_ppc64;
1e8a024a 849 break;
3af9a47b 850 default:
1e8a024a
TG
851 *type = bfd_arch_unknown;
852 break;
3af9a47b
NC
853 }
854}
a95a4550 855
154a1ee5 856static bfd_boolean
116c20d2
NC
857bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
858{
46d1c23b 859 struct mach_o_header_external raw;
1e8a024a
TG
860 unsigned int size;
861
c2f09c75 862 size = mach_o_wide_p (header) ?
154a1ee5 863 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
116c20d2 864
46d1c23b
TG
865 bfd_h_put_32 (abfd, header->magic, raw.magic);
866 bfd_h_put_32 (abfd, header->cputype, raw.cputype);
867 bfd_h_put_32 (abfd, header->cpusubtype, raw.cpusubtype);
868 bfd_h_put_32 (abfd, header->filetype, raw.filetype);
869 bfd_h_put_32 (abfd, header->ncmds, raw.ncmds);
870 bfd_h_put_32 (abfd, header->sizeofcmds, raw.sizeofcmds);
871 bfd_h_put_32 (abfd, header->flags, raw.flags);
116c20d2 872
c2f09c75 873 if (mach_o_wide_p (header))
46d1c23b 874 bfd_h_put_32 (abfd, header->reserved, raw.reserved);
1e8a024a 875
c2f09c75 876 if (bfd_seek (abfd, 0, SEEK_SET) != 0
46d1c23b 877 || bfd_bwrite (&raw, size, abfd) != size)
154a1ee5 878 return FALSE;
116c20d2 879
154a1ee5 880 return TRUE;
116c20d2
NC
881}
882
883static int
ab273af8 884bfd_mach_o_write_thread (bfd *abfd, bfd_mach_o_load_command *command)
116c20d2
NC
885{
886 bfd_mach_o_thread_command *cmd = &command->command.thread;
887 unsigned int i;
46d1c23b 888 struct mach_o_thread_command_external raw;
92bc0e80 889 unsigned int offset;
116c20d2
NC
890
891 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
892 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
893
894 offset = 8;
116c20d2
NC
895 for (i = 0; i < cmd->nflavours; i++)
896 {
897 BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
46d1c23b
TG
898 BFD_ASSERT (cmd->flavours[i].offset ==
899 (command->offset + offset + BFD_MACH_O_LC_SIZE));
116c20d2 900
46d1c23b
TG
901 bfd_h_put_32 (abfd, cmd->flavours[i].flavour, raw.flavour);
902 bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), raw.count);
116c20d2 903
c2f09c75 904 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
46d1c23b 905 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
116c20d2
NC
906 return -1;
907
46d1c23b 908 offset += cmd->flavours[i].size + sizeof (raw);
116c20d2
NC
909 }
910
911 return 0;
912}
913
92bc0e80
TG
914long
915bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
916 asection *asect)
917{
918 return (asect->reloc_count + 1) * sizeof (arelent *);
919}
920
b32e07d7 921static int
46d1c23b
TG
922bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
923 struct mach_o_reloc_info_external *raw,
b32e07d7 924 arelent *res, asymbol **syms)
92bc0e80 925{
046b007d 926 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
92bc0e80 927 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
b32e07d7
TG
928 bfd_mach_o_reloc_info reloc;
929 bfd_vma addr;
930 bfd_vma symnum;
931 asymbol **sym;
932
46d1c23b
TG
933 addr = bfd_get_32 (abfd, raw->r_address);
934 symnum = bfd_get_32 (abfd, raw->r_symbolnum);
b32e07d7
TG
935
936 if (addr & BFD_MACH_O_SR_SCATTERED)
937 {
938 unsigned int j;
939
940 /* Scattered relocation.
941 Extract section and offset from r_value. */
942 res->sym_ptr_ptr = NULL;
943 res->addend = 0;
944 for (j = 0; j < mdata->nsects; j++)
945 {
946 bfd_mach_o_section *sect = mdata->sections[j];
947 if (symnum >= sect->addr && symnum < sect->addr + sect->size)
948 {
949 res->sym_ptr_ptr = sect->bfdsection->symbol_ptr_ptr;
950 res->addend = symnum - sect->addr;
951 break;
952 }
953 }
954 res->address = BFD_MACH_O_GET_SR_ADDRESS (addr);
955 reloc.r_type = BFD_MACH_O_GET_SR_TYPE (addr);
956 reloc.r_length = BFD_MACH_O_GET_SR_LENGTH (addr);
957 reloc.r_pcrel = addr & BFD_MACH_O_SR_PCREL;
958 reloc.r_scattered = 1;
959 }
960 else
961 {
962 unsigned int num = BFD_MACH_O_GET_R_SYMBOLNUM (symnum);
963 res->addend = 0;
964 res->address = addr;
965 if (symnum & BFD_MACH_O_R_EXTERN)
06988dfc
TG
966 {
967 sym = syms + num;
968 reloc.r_extern = 1;
969 }
b32e07d7
TG
970 else
971 {
972 BFD_ASSERT (num != 0);
973 BFD_ASSERT (num <= mdata->nsects);
974 sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
1523fa24
TG
975 /* For a symbol defined in section S, the addend (stored in the
976 binary) contains the address of the section. To comply with
977 bfd conventio, substract the section address.
978 Use the address from the header, so that the user can modify
979 the vma of the section. */
980 res->addend = -mdata->sections[num - 1]->addr;
06988dfc 981 reloc.r_extern = 0;
b32e07d7
TG
982 }
983 res->sym_ptr_ptr = sym;
984 reloc.r_type = BFD_MACH_O_GET_R_TYPE (symnum);
985 reloc.r_length = BFD_MACH_O_GET_R_LENGTH (symnum);
986 reloc.r_pcrel = (symnum & BFD_MACH_O_R_PCREL) ? 1 : 0;
987 reloc.r_scattered = 0;
988 }
989
990 if (!(*bed->_bfd_mach_o_swap_reloc_in)(res, &reloc))
991 return -1;
992 return 0;
993}
994
995static int
996bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
997 unsigned long count,
998 arelent *res, asymbol **syms)
999{
92bc0e80 1000 unsigned long i;
46d1c23b 1001 struct mach_o_reloc_info_external *native_relocs;
92bc0e80
TG
1002 bfd_size_type native_size;
1003
92bc0e80 1004 /* Allocate and read relocs. */
b32e07d7 1005 native_size = count * BFD_MACH_O_RELENT_SIZE;
46d1c23b
TG
1006 native_relocs =
1007 (struct mach_o_reloc_info_external *) bfd_malloc (native_size);
92bc0e80
TG
1008 if (native_relocs == NULL)
1009 return -1;
1010
b32e07d7 1011 if (bfd_seek (abfd, filepos, SEEK_SET) != 0
92bc0e80 1012 || bfd_bread (native_relocs, native_size, abfd) != native_size)
b32e07d7
TG
1013 goto err;
1014
1015 for (i = 0; i < count; i++)
92bc0e80 1016 {
46d1c23b
TG
1017 if (bfd_mach_o_canonicalize_one_reloc (abfd, &native_relocs[i],
1018 &res[i], syms) < 0)
b32e07d7 1019 goto err;
92bc0e80 1020 }
b32e07d7
TG
1021 free (native_relocs);
1022 return i;
1023 err:
1024 free (native_relocs);
1025 return -1;
1026}
1027
1028long
1029bfd_mach_o_canonicalize_reloc (bfd *abfd, asection *asect,
1030 arelent **rels, asymbol **syms)
1031{
1032 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
1033 unsigned long i;
1034 arelent *res;
1035
1036 if (asect->reloc_count == 0)
1037 return 0;
1038
1039 /* No need to go further if we don't know how to read relocs. */
1040 if (bed->_bfd_mach_o_swap_reloc_in == NULL)
1041 return 0;
92bc0e80
TG
1042
1043 res = bfd_malloc (asect->reloc_count * sizeof (arelent));
1044 if (res == NULL)
b32e07d7
TG
1045 return -1;
1046
1047 if (bfd_mach_o_canonicalize_relocs (abfd, asect->rel_filepos,
1048 asect->reloc_count, res, syms) < 0)
92bc0e80 1049 {
b32e07d7 1050 free (res);
92bc0e80
TG
1051 return -1;
1052 }
1053
1054 for (i = 0; i < asect->reloc_count; i++)
b32e07d7
TG
1055 rels[i] = &res[i];
1056 rels[i] = NULL;
1057 asect->relocation = res;
92bc0e80 1058
b32e07d7
TG
1059 return i;
1060}
92bc0e80 1061
b32e07d7
TG
1062long
1063bfd_mach_o_get_dynamic_reloc_upper_bound (bfd *abfd)
1064{
1065 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
92bc0e80 1066
b32e07d7
TG
1067 if (mdata->dysymtab == NULL)
1068 return 1;
1069 return (mdata->dysymtab->nextrel + mdata->dysymtab->nlocrel)
1070 * sizeof (arelent *);
1071}
92bc0e80 1072
b32e07d7
TG
1073long
1074bfd_mach_o_canonicalize_dynamic_reloc (bfd *abfd, arelent **rels,
1075 struct bfd_symbol **syms)
1076{
1077 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1078 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
1079 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
1080 unsigned long i;
1081 arelent *res;
1082
1083 if (dysymtab == NULL)
1084 return 0;
1085 if (dysymtab->nextrel == 0 && dysymtab->nlocrel == 0)
1086 return 0;
1087
1088 /* No need to go further if we don't know how to read relocs. */
1089 if (bed->_bfd_mach_o_swap_reloc_in == NULL)
1090 return 0;
1091
1092 res = bfd_malloc ((dysymtab->nextrel + dysymtab->nlocrel) * sizeof (arelent));
1093 if (res == NULL)
1094 return -1;
1095
1096 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->extreloff,
1097 dysymtab->nextrel, res, syms) < 0)
1098 {
1099 free (res);
1100 return -1;
92bc0e80 1101 }
b32e07d7
TG
1102
1103 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->locreloff,
1104 dysymtab->nlocrel,
1105 res + dysymtab->nextrel, syms) < 0)
1106 {
1107 free (res);
1108 return -1;
1109 }
1110
1111 for (i = 0; i < dysymtab->nextrel + dysymtab->nlocrel; i++)
1112 rels[i] = &res[i];
1113 rels[i] = NULL;
92bc0e80
TG
1114 return i;
1115}
1116
1117static bfd_boolean
ab273af8 1118bfd_mach_o_write_relocs (bfd *abfd, bfd_mach_o_section *section)
92bc0e80 1119{
046b007d 1120 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
92bc0e80
TG
1121 unsigned int i;
1122 arelent **entries;
1123 asection *sec;
1124 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
1125
1126 sec = section->bfdsection;
1127 if (sec->reloc_count == 0)
1128 return TRUE;
1129
1130 if (bed->_bfd_mach_o_swap_reloc_out == NULL)
1131 return TRUE;
1132
1133 /* Allocate relocation room. */
1134 mdata->filelen = FILE_ALIGN(mdata->filelen, 2);
1135 section->nreloc = sec->reloc_count;
1136 sec->rel_filepos = mdata->filelen;
1137 section->reloff = sec->rel_filepos;
1138 mdata->filelen += sec->reloc_count * BFD_MACH_O_RELENT_SIZE;
1139
1140 if (bfd_seek (abfd, section->reloff, SEEK_SET) != 0)
1141 return FALSE;
1142
1143 /* Convert and write. */
1144 entries = section->bfdsection->orelocation;
1145 for (i = 0; i < section->nreloc; i++)
1146 {
1147 arelent *rel = entries[i];
46d1c23b 1148 struct mach_o_reloc_info_external raw;
92bc0e80
TG
1149 bfd_mach_o_reloc_info info, *pinfo = &info;
1150
1151 /* Convert relocation to an intermediate representation. */
1152 if (!(*bed->_bfd_mach_o_swap_reloc_out) (rel, pinfo))
1153 return FALSE;
1154
1155 /* Lower the relocation info. */
1156 if (pinfo->r_scattered)
1157 {
1158 unsigned long v;
1159
1160 v = BFD_MACH_O_SR_SCATTERED
1161 | (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0)
1162 | BFD_MACH_O_SET_SR_LENGTH(pinfo->r_length)
1163 | BFD_MACH_O_SET_SR_TYPE(pinfo->r_type)
1164 | BFD_MACH_O_SET_SR_ADDRESS(pinfo->r_address);
46d1c23b
TG
1165 /* Note: scattered relocs have field in reverse order... */
1166 bfd_put_32 (abfd, v, raw.r_address);
1167 bfd_put_32 (abfd, pinfo->r_value, raw.r_symbolnum);
92bc0e80
TG
1168 }
1169 else
1170 {
1171 unsigned long v;
1172
46d1c23b 1173 bfd_put_32 (abfd, pinfo->r_address, raw.r_address);
92bc0e80
TG
1174 v = BFD_MACH_O_SET_R_SYMBOLNUM (pinfo->r_value)
1175 | (pinfo->r_pcrel ? BFD_MACH_O_R_PCREL : 0)
1176 | BFD_MACH_O_SET_R_LENGTH (pinfo->r_length)
1177 | (pinfo->r_extern ? BFD_MACH_O_R_EXTERN : 0)
1178 | BFD_MACH_O_SET_R_TYPE (pinfo->r_type);
46d1c23b 1179 bfd_put_32 (abfd, v, raw.r_symbolnum);
92bc0e80
TG
1180 }
1181
46d1c23b 1182 if (bfd_bwrite (&raw, BFD_MACH_O_RELENT_SIZE, abfd)
92bc0e80
TG
1183 != BFD_MACH_O_RELENT_SIZE)
1184 return FALSE;
1185 }
1186 return TRUE;
1187}
1188
116c20d2 1189static int
ab273af8 1190bfd_mach_o_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
116c20d2 1191{
46d1c23b
TG
1192 struct mach_o_section_32_external raw;
1193
1194 memcpy (raw.sectname, section->sectname, 16);
72b5104c 1195 memcpy (raw.segname, section->segname, 16);
46d1c23b
TG
1196 bfd_h_put_32 (abfd, section->addr, raw.addr);
1197 bfd_h_put_32 (abfd, section->size, raw.size);
1198 bfd_h_put_32 (abfd, section->offset, raw.offset);
1199 bfd_h_put_32 (abfd, section->align, raw.align);
1200 bfd_h_put_32 (abfd, section->reloff, raw.reloff);
1201 bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
1202 bfd_h_put_32 (abfd, section->flags, raw.flags);
1203 bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
1204 bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
1205
1206 if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
92bc0e80 1207 != BFD_MACH_O_SECTION_SIZE)
116c20d2
NC
1208 return -1;
1209
1210 return 0;
1211}
1212
1213static int
ab273af8 1214bfd_mach_o_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
116c20d2 1215{
46d1c23b
TG
1216 struct mach_o_section_64_external raw;
1217
1218 memcpy (raw.sectname, section->sectname, 16);
1219 memcpy (raw.segname, section->segname, 16);
1220 bfd_h_put_64 (abfd, section->addr, raw.addr);
1221 bfd_h_put_64 (abfd, section->size, raw.size);
1222 bfd_h_put_32 (abfd, section->offset, raw.offset);
1223 bfd_h_put_32 (abfd, section->align, raw.align);
1224 bfd_h_put_32 (abfd, section->reloff, raw.reloff);
1225 bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
1226 bfd_h_put_32 (abfd, section->flags, raw.flags);
1227 bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
1228 bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
1229 bfd_h_put_32 (abfd, section->reserved3, raw.reserved3);
1230
1231 if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
92bc0e80 1232 != BFD_MACH_O_SECTION_64_SIZE)
116c20d2
NC
1233 return -1;
1234
1e8a024a
TG
1235 return 0;
1236}
1237
1238static int
ab273af8 1239bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 1240{
46d1c23b 1241 struct mach_o_segment_command_32_external raw;
1e8a024a 1242 bfd_mach_o_segment_command *seg = &command->command.segment;
f1bde64c 1243 bfd_mach_o_section *sec;
1e8a024a 1244
c2f09c75
TG
1245 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1246
f1bde64c
TG
1247 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1248 if (!bfd_mach_o_write_relocs (abfd, sec))
92bc0e80 1249 return -1;
c2f09c75 1250
46d1c23b
TG
1251 memcpy (raw.segname, seg->segname, 16);
1252 bfd_h_put_32 (abfd, seg->vmaddr, raw.vmaddr);
1253 bfd_h_put_32 (abfd, seg->vmsize, raw.vmsize);
1254 bfd_h_put_32 (abfd, seg->fileoff, raw.fileoff);
1255 bfd_h_put_32 (abfd, seg->filesize, raw.filesize);
1256 bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
1257 bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
1258 bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
1259 bfd_h_put_32 (abfd, seg->flags, raw.flags);
c2f09c75 1260
46d1c23b
TG
1261 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1262 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
c2f09c75 1263 return -1;
1e8a024a 1264
f1bde64c
TG
1265 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1266 if (bfd_mach_o_write_section_32 (abfd, sec))
92bc0e80 1267 return -1;
1e8a024a 1268
116c20d2
NC
1269 return 0;
1270}
1271
1e8a024a 1272static int
ab273af8 1273bfd_mach_o_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 1274{
46d1c23b 1275 struct mach_o_segment_command_64_external raw;
c2f09c75 1276 bfd_mach_o_segment_command *seg = &command->command.segment;
f1bde64c 1277 bfd_mach_o_section *sec;
c2f09c75
TG
1278
1279 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
1280
f1bde64c
TG
1281 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1282 if (!bfd_mach_o_write_relocs (abfd, sec))
92bc0e80 1283 return -1;
c2f09c75 1284
46d1c23b
TG
1285 memcpy (raw.segname, seg->segname, 16);
1286 bfd_h_put_64 (abfd, seg->vmaddr, raw.vmaddr);
1287 bfd_h_put_64 (abfd, seg->vmsize, raw.vmsize);
1288 bfd_h_put_64 (abfd, seg->fileoff, raw.fileoff);
1289 bfd_h_put_64 (abfd, seg->filesize, raw.filesize);
1290 bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
1291 bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
1292 bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
1293 bfd_h_put_32 (abfd, seg->flags, raw.flags);
1294
1295 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1296 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
c2f09c75
TG
1297 return -1;
1298
f1bde64c
TG
1299 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1300 if (bfd_mach_o_write_section_64 (abfd, sec))
92bc0e80 1301 return -1;
c2f09c75 1302
c2f09c75 1303 return 0;
1e8a024a
TG
1304}
1305
c2f09c75 1306static bfd_boolean
ab273af8 1307bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
116c20d2 1308{
046b007d 1309 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
116c20d2 1310 bfd_mach_o_symtab_command *sym = &command->command.symtab;
116c20d2 1311 unsigned long i;
c2f09c75 1312 unsigned int wide = bfd_mach_o_wide_p (abfd);
046b007d 1313 unsigned int symlen = wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
c2f09c75
TG
1314 struct bfd_strtab_hash *strtab;
1315 asymbol **symbols = bfd_get_outsymbols (abfd);
1316
1317 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1318
1319 /* Write the symbols first. */
92bc0e80
TG
1320 mdata->filelen = FILE_ALIGN(mdata->filelen, wide ? 3 : 2);
1321 sym->symoff = mdata->filelen;
c2f09c75
TG
1322 if (bfd_seek (abfd, sym->symoff, SEEK_SET) != 0)
1323 return FALSE;
1324
1325 sym->nsyms = bfd_get_symcount (abfd);
92bc0e80 1326 mdata->filelen += sym->nsyms * symlen;
c2f09c75
TG
1327
1328 strtab = _bfd_stringtab_init ();
1329 if (strtab == NULL)
1330 return FALSE;
116c20d2 1331
a4551119
TG
1332 if (sym->nsyms > 0)
1333 /* Although we don't strictly need to do this, for compatibility with
1334 Darwin system tools, actually output an empty string for the index
1335 0 entry. */
1336 _bfd_stringtab_add (strtab, "", TRUE, FALSE);
1337
116c20d2
NC
1338 for (i = 0; i < sym->nsyms; i++)
1339 {
91d6fa6a 1340 bfd_size_type str_index;
92bc0e80 1341 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
c2f09c75 1342
92bc0e80 1343 /* Compute name index. */
c2f09c75 1344 /* An index of 0 always means the empty string. */
92bc0e80 1345 if (s->symbol.name == 0 || s->symbol.name[0] == '\0')
91d6fa6a 1346 str_index = 0;
c2f09c75
TG
1347 else
1348 {
91d6fa6a
NC
1349 str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
1350 if (str_index == (bfd_size_type) -1)
c2f09c75
TG
1351 goto err;
1352 }
46d1c23b 1353
c2f09c75 1354 if (wide)
46d1c23b
TG
1355 {
1356 struct mach_o_nlist_64_external raw;
1357
1358 bfd_h_put_32 (abfd, str_index, raw.n_strx);
1359 bfd_h_put_8 (abfd, s->n_type, raw.n_type);
1360 bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
1361 bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
1362 bfd_h_put_64 (abfd, s->symbol.section->vma + s->symbol.value,
1363 raw.n_value);
1364
1365 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1366 goto err;
1367 }
c2f09c75 1368 else
46d1c23b
TG
1369 {
1370 struct mach_o_nlist_external raw;
116c20d2 1371
46d1c23b
TG
1372 bfd_h_put_32 (abfd, str_index, raw.n_strx);
1373 bfd_h_put_8 (abfd, s->n_type, raw.n_type);
1374 bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
1375 bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
1376 bfd_h_put_32 (abfd, s->symbol.section->vma + s->symbol.value,
1377 raw.n_value);
1378
1379 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1380 goto err;
1381 }
116c20d2 1382 }
c2f09c75 1383 sym->strsize = _bfd_stringtab_size (strtab);
92bc0e80
TG
1384 sym->stroff = mdata->filelen;
1385 mdata->filelen += sym->strsize;
116c20d2 1386
c2f09c75
TG
1387 if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
1388 goto err;
1389 _bfd_stringtab_free (strtab);
116c20d2 1390
c2f09c75 1391 /* The command. */
46d1c23b
TG
1392 {
1393 struct mach_o_symtab_command_external raw;
116c20d2 1394
46d1c23b
TG
1395 bfd_h_put_32 (abfd, sym->symoff, raw.symoff);
1396 bfd_h_put_32 (abfd, sym->nsyms, raw.nsyms);
1397 bfd_h_put_32 (abfd, sym->stroff, raw.stroff);
1398 bfd_h_put_32 (abfd, sym->strsize, raw.strsize);
1399
1400 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1401 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1402 return FALSE;
1403 }
116c20d2 1404
c2f09c75 1405 return TRUE;
116c20d2 1406
c2f09c75
TG
1407 err:
1408 _bfd_stringtab_free (strtab);
1409 return FALSE;
116c20d2
NC
1410}
1411
92bc0e80
TG
1412/* Process the symbols and generate Mach-O specific fields.
1413 Number them. */
1414
1415static bfd_boolean
1416bfd_mach_o_mangle_symbols (bfd *abfd)
1417{
1418 unsigned long i;
1419 asymbol **symbols = bfd_get_outsymbols (abfd);
1420
1421 for (i = 0; i < bfd_get_symcount (abfd); i++)
1422 {
1423 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1424
1425 if (s->n_type == BFD_MACH_O_N_UNDF && !(s->symbol.flags & BSF_DEBUGGING))
1426 {
1427 /* As genuine Mach-O symbols type shouldn't be N_UNDF (undefined
1428 symbols should be N_UNDEF | N_EXT), we suppose the back-end
1429 values haven't been set. */
1430 if (s->symbol.section == bfd_abs_section_ptr)
1431 s->n_type = BFD_MACH_O_N_ABS;
1432 else if (s->symbol.section == bfd_und_section_ptr)
1433 {
1434 s->n_type = BFD_MACH_O_N_UNDF;
1435 if (s->symbol.flags & BSF_WEAK)
1436 s->n_desc |= BFD_MACH_O_N_WEAK_REF;
1437 }
1438 else if (s->symbol.section == bfd_com_section_ptr)
1439 s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
1440 else
1441 s->n_type = BFD_MACH_O_N_SECT;
1442
1443 if (s->symbol.flags & BSF_GLOBAL)
1444 s->n_type |= BFD_MACH_O_N_EXT;
1445 }
1446
1447 /* Compute section index. */
1448 if (s->symbol.section != bfd_abs_section_ptr
1449 && s->symbol.section != bfd_und_section_ptr
1450 && s->symbol.section != bfd_com_section_ptr)
1451 s->n_sect = s->symbol.section->target_index;
1452
1453 /* Number symbols. */
1454 s->symbol.udata.i = i;
1455 }
1456 return TRUE;
1457}
1458
154a1ee5 1459bfd_boolean
116c20d2 1460bfd_mach_o_write_contents (bfd *abfd)
3af9a47b
NC
1461{
1462 unsigned int i;
046b007d 1463 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 1464
92bc0e80
TG
1465 if (mdata->header.ncmds == 0)
1466 if (!bfd_mach_o_build_commands (abfd))
1467 return FALSE;
1468
3af9a47b 1469 /* Now write header information. */
c2f09c75
TG
1470 if (mdata->header.filetype == 0)
1471 {
1472 if (abfd->flags & EXEC_P)
1473 mdata->header.filetype = BFD_MACH_O_MH_EXECUTE;
1474 else if (abfd->flags & DYNAMIC)
1475 mdata->header.filetype = BFD_MACH_O_MH_DYLIB;
1476 else
1477 mdata->header.filetype = BFD_MACH_O_MH_OBJECT;
1478 }
154a1ee5 1479 if (!bfd_mach_o_write_header (abfd, &mdata->header))
b34976b6 1480 return FALSE;
3af9a47b 1481
92bc0e80
TG
1482 /* Assign a number to each symbols. */
1483 if (!bfd_mach_o_mangle_symbols (abfd))
1484 return FALSE;
1485
3af9a47b
NC
1486 for (i = 0; i < mdata->header.ncmds; i++)
1487 {
46d1c23b 1488 struct mach_o_load_command_external raw;
3af9a47b
NC
1489 bfd_mach_o_load_command *cur = &mdata->commands[i];
1490 unsigned long typeflag;
1491
154a1ee5 1492 typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
3af9a47b 1493
46d1c23b
TG
1494 bfd_h_put_32 (abfd, typeflag, raw.cmd);
1495 bfd_h_put_32 (abfd, cur->len, raw.cmdsize);
3af9a47b 1496
c2f09c75 1497 if (bfd_seek (abfd, cur->offset, SEEK_SET) != 0
46d1c23b 1498 || bfd_bwrite (&raw, BFD_MACH_O_LC_SIZE, abfd) != 8)
b34976b6 1499 return FALSE;
3af9a47b
NC
1500
1501 switch (cur->type)
1502 {
1503 case BFD_MACH_O_LC_SEGMENT:
ab273af8 1504 if (bfd_mach_o_write_segment_32 (abfd, cur) != 0)
1e8a024a
TG
1505 return FALSE;
1506 break;
1507 case BFD_MACH_O_LC_SEGMENT_64:
ab273af8 1508 if (bfd_mach_o_write_segment_64 (abfd, cur) != 0)
b34976b6 1509 return FALSE;
3af9a47b
NC
1510 break;
1511 case BFD_MACH_O_LC_SYMTAB:
ab273af8 1512 if (!bfd_mach_o_write_symtab (abfd, cur))
b34976b6 1513 return FALSE;
3af9a47b
NC
1514 break;
1515 case BFD_MACH_O_LC_SYMSEG:
1516 break;
1517 case BFD_MACH_O_LC_THREAD:
1518 case BFD_MACH_O_LC_UNIXTHREAD:
ab273af8 1519 if (bfd_mach_o_write_thread (abfd, cur) != 0)
b34976b6 1520 return FALSE;
3af9a47b
NC
1521 break;
1522 case BFD_MACH_O_LC_LOADFVMLIB:
1523 case BFD_MACH_O_LC_IDFVMLIB:
1524 case BFD_MACH_O_LC_IDENT:
1525 case BFD_MACH_O_LC_FVMFILE:
1526 case BFD_MACH_O_LC_PREPAGE:
1527 case BFD_MACH_O_LC_DYSYMTAB:
1528 case BFD_MACH_O_LC_LOAD_DYLIB:
1529 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1530 case BFD_MACH_O_LC_ID_DYLIB:
046b007d 1531 case BFD_MACH_O_LC_REEXPORT_DYLIB:
73017762 1532 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
3af9a47b
NC
1533 case BFD_MACH_O_LC_LOAD_DYLINKER:
1534 case BFD_MACH_O_LC_ID_DYLINKER:
1535 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1536 case BFD_MACH_O_LC_ROUTINES:
1537 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1538 break;
1539 default:
4a97a0e5
AM
1540 (*_bfd_error_handler) (_("unable to write unknown load command 0x%lx"),
1541 (unsigned long) cur->type);
b34976b6 1542 return FALSE;
3af9a47b
NC
1543 }
1544 }
1545
b34976b6 1546 return TRUE;
3af9a47b
NC
1547}
1548
f1bde64c
TG
1549static void
1550bfd_mach_o_append_section_to_segment (bfd_mach_o_segment_command *seg,
1551 asection *sec)
1552{
1553 bfd_mach_o_section *s = (bfd_mach_o_section *)sec->used_by_bfd;
1554 if (seg->sect_head == NULL)
1555 seg->sect_head = s;
1556 else
1557 seg->sect_tail->next = s;
1558 seg->sect_tail = s;
1559}
1560
1561/* Create section Mach-O flags from BFD flags. */
1562
1563static void
1564bfd_mach_o_set_section_flags_from_bfd (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
1565{
1566 flagword bfd_flags;
1567 bfd_mach_o_section *s = bfd_mach_o_get_mach_o_section (sec);
1568
1569 /* Create default flags. */
1570 bfd_flags = bfd_get_section_flags (abfd, sec);
1571 if ((bfd_flags & SEC_CODE) == SEC_CODE)
1572 s->flags = BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS
1573 | BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS
1574 | BFD_MACH_O_S_REGULAR;
1575 else if ((bfd_flags & (SEC_ALLOC | SEC_LOAD)) == SEC_ALLOC)
1576 s->flags = BFD_MACH_O_S_ZEROFILL;
1577 else if (bfd_flags & SEC_DEBUGGING)
1578 s->flags = BFD_MACH_O_S_REGULAR | BFD_MACH_O_S_ATTR_DEBUG;
1579 else
1580 s->flags = BFD_MACH_O_S_REGULAR;
1581}
1582
154a1ee5
TG
1583/* Build Mach-O load commands from the sections. */
1584
1585bfd_boolean
1586bfd_mach_o_build_commands (bfd *abfd)
1587{
046b007d 1588 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
c2f09c75 1589 unsigned int wide = mach_o_wide_p (&mdata->header);
154a1ee5 1590 bfd_mach_o_segment_command *seg;
154a1ee5 1591 asection *sec;
c2f09c75
TG
1592 bfd_mach_o_load_command *cmd;
1593 bfd_mach_o_load_command *symtab_cmd;
1594 int target_index;
154a1ee5
TG
1595
1596 /* Return now if commands are already built. */
1597 if (mdata->header.ncmds)
1598 return FALSE;
1599
f1bde64c
TG
1600 /* Very simple version: a command (segment) to contain all the sections and
1601 a command for the symbol table. */
c2f09c75
TG
1602 mdata->header.ncmds = 2;
1603 mdata->commands = bfd_alloc (abfd, mdata->header.ncmds
154a1ee5
TG
1604 * sizeof (bfd_mach_o_load_command));
1605 if (mdata->commands == NULL)
1606 return FALSE;
c2f09c75
TG
1607 cmd = &mdata->commands[0];
1608 seg = &cmd->command.segment;
1609
154a1ee5 1610 seg->nsects = bfd_count_sections (abfd);
154a1ee5
TG
1611
1612 /* Set segment command. */
1613 if (wide)
1614 {
c2f09c75
TG
1615 cmd->type = BFD_MACH_O_LC_SEGMENT_64;
1616 cmd->offset = BFD_MACH_O_HEADER_64_SIZE;
1617 cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
154a1ee5
TG
1618 + BFD_MACH_O_SECTION_64_SIZE * seg->nsects;
1619 }
1620 else
1621 {
c2f09c75
TG
1622 cmd->type = BFD_MACH_O_LC_SEGMENT;
1623 cmd->offset = BFD_MACH_O_HEADER_SIZE;
1624 cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
154a1ee5
TG
1625 + BFD_MACH_O_SECTION_SIZE * seg->nsects;
1626 }
c2f09c75
TG
1627 cmd->type_required = FALSE;
1628 mdata->header.sizeofcmds = cmd->len;
92bc0e80 1629 mdata->filelen = cmd->offset + cmd->len;
154a1ee5 1630
c2f09c75
TG
1631 /* Set symtab command. */
1632 symtab_cmd = &mdata->commands[1];
1633
1634 symtab_cmd->type = BFD_MACH_O_LC_SYMTAB;
1635 symtab_cmd->offset = cmd->offset + cmd->len;
1636 symtab_cmd->len = 6 * 4;
1637 symtab_cmd->type_required = FALSE;
1638
1639 mdata->header.sizeofcmds += symtab_cmd->len;
92bc0e80 1640 mdata->filelen += symtab_cmd->len;
c2f09c75
TG
1641
1642 /* Fill segment command. */
154a1ee5
TG
1643 memset (seg->segname, 0, sizeof (seg->segname));
1644 seg->vmaddr = 0;
92bc0e80 1645 seg->fileoff = mdata->filelen;
154a1ee5
TG
1646 seg->filesize = 0;
1647 seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
1648 | BFD_MACH_O_PROT_EXECUTE;
1649 seg->initprot = seg->maxprot;
1650 seg->flags = 0;
7ba695a9
TG
1651 seg->sect_head = NULL;
1652 seg->sect_tail = NULL;
154a1ee5 1653
a4551119
TG
1654 /* Create Mach-O sections.
1655 Section type, attribute and align should have been set when the
1656 section was created - either read in or specified. */
c2f09c75 1657 target_index = 0;
154a1ee5
TG
1658 for (sec = abfd->sections; sec; sec = sec->next)
1659 {
a4551119 1660 unsigned bfd_align = bfd_get_section_alignment (abfd, sec);
f1bde64c 1661 bfd_mach_o_section *msect = bfd_mach_o_get_mach_o_section (sec);
c2f09c75 1662
f1bde64c
TG
1663 bfd_mach_o_append_section_to_segment (seg, sec);
1664
f1bde64c
TG
1665 msect->addr = bfd_get_section_vma (abfd, sec);
1666 msect->size = bfd_get_section_size (sec);
a4551119
TG
1667 /* Use the largest alignment set, in case it was bumped after the
1668 section was created. */
1669 msect->align = msect->align > bfd_align ? msect->align : bfd_align;
f1bde64c
TG
1670
1671 if (msect->size != 0)
1672 {
1673 mdata->filelen = FILE_ALIGN (mdata->filelen, msect->align);
1674 msect->offset = mdata->filelen;
92bc0e80
TG
1675 }
1676 else
f1bde64c
TG
1677 msect->offset = 0;
1678
1679 sec->filepos = msect->offset;
c2f09c75 1680 sec->target_index = ++target_index;
154a1ee5 1681
f1bde64c 1682 mdata->filelen += msect->size;
154a1ee5 1683 }
92bc0e80 1684 seg->filesize = mdata->filelen - seg->fileoff;
154a1ee5
TG
1685 seg->vmsize = seg->filesize;
1686
1687 return TRUE;
1688}
1689
1690/* Set the contents of a section. */
1691
1692bfd_boolean
1693bfd_mach_o_set_section_contents (bfd *abfd,
1694 asection *section,
1695 const void * location,
1696 file_ptr offset,
1697 bfd_size_type count)
1698{
1699 file_ptr pos;
1700
1701 /* This must be done first, because bfd_set_section_contents is
1702 going to set output_has_begun to TRUE. */
1703 if (! abfd->output_has_begun && ! bfd_mach_o_build_commands (abfd))
1704 return FALSE;
1705
1706 if (count == 0)
1707 return TRUE;
1708
1709 pos = section->filepos + offset;
1710 if (bfd_seek (abfd, pos, SEEK_SET) != 0
1711 || bfd_bwrite (location, count, abfd) != count)
1712 return FALSE;
1713
1714 return TRUE;
1715}
1716
1717int
116c20d2 1718bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
a6b96beb 1719 struct bfd_link_info *info ATTRIBUTE_UNUSED)
3af9a47b
NC
1720{
1721 return 0;
1722}
1723
1724/* Make an empty symbol. This is required only because
1725 bfd_make_section_anyway wants to create a symbol for the section. */
1726
154a1ee5 1727asymbol *
116c20d2 1728bfd_mach_o_make_empty_symbol (bfd *abfd)
3af9a47b 1729{
d3ce72d0
NC
1730 asymbol *new_symbol;
1731
1732 new_symbol = bfd_zalloc (abfd, sizeof (bfd_mach_o_asymbol));
1733 if (new_symbol == NULL)
1734 return new_symbol;
1735 new_symbol->the_bfd = abfd;
1736 new_symbol->udata.i = 0;
1737 return new_symbol;
3af9a47b
NC
1738}
1739
154a1ee5 1740static bfd_boolean
116c20d2 1741bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
3af9a47b 1742{
46d1c23b 1743 struct mach_o_header_external raw;
1e8a024a 1744 unsigned int size;
edeb6e24 1745 bfd_vma (*get32) (const void *) = NULL;
3af9a47b 1746
1e8a024a 1747 /* Just read the magic number. */
c2f09c75 1748 if (bfd_seek (abfd, 0, SEEK_SET) != 0
46d1c23b 1749 || bfd_bread (raw.magic, sizeof (raw.magic), abfd) != 4)
154a1ee5 1750 return FALSE;
3af9a47b 1751
46d1c23b 1752 if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
3af9a47b
NC
1753 {
1754 header->byteorder = BFD_ENDIAN_BIG;
154a1ee5 1755 header->magic = BFD_MACH_O_MH_MAGIC;
1e8a024a 1756 header->version = 1;
3af9a47b
NC
1757 get32 = bfd_getb32;
1758 }
46d1c23b 1759 else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
3af9a47b 1760 {
a95a4550 1761 header->byteorder = BFD_ENDIAN_LITTLE;
154a1ee5 1762 header->magic = BFD_MACH_O_MH_MAGIC;
1e8a024a
TG
1763 header->version = 1;
1764 get32 = bfd_getl32;
1765 }
46d1c23b 1766 else if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
1e8a024a
TG
1767 {
1768 header->byteorder = BFD_ENDIAN_BIG;
154a1ee5 1769 header->magic = BFD_MACH_O_MH_MAGIC_64;
1e8a024a
TG
1770 header->version = 2;
1771 get32 = bfd_getb32;
1772 }
46d1c23b 1773 else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
1e8a024a
TG
1774 {
1775 header->byteorder = BFD_ENDIAN_LITTLE;
154a1ee5 1776 header->magic = BFD_MACH_O_MH_MAGIC_64;
1e8a024a 1777 header->version = 2;
3af9a47b
NC
1778 get32 = bfd_getl32;
1779 }
1780 else
1781 {
1782 header->byteorder = BFD_ENDIAN_UNKNOWN;
154a1ee5 1783 return FALSE;
3af9a47b 1784 }
a95a4550 1785
1e8a024a 1786 /* Once the size of the header is known, read the full header. */
c2f09c75 1787 size = mach_o_wide_p (header) ?
154a1ee5 1788 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
1e8a024a 1789
c2f09c75 1790 if (bfd_seek (abfd, 0, SEEK_SET) != 0
46d1c23b 1791 || bfd_bread (&raw, size, abfd) != size)
154a1ee5 1792 return FALSE;
1e8a024a 1793
46d1c23b
TG
1794 header->cputype = (*get32) (raw.cputype);
1795 header->cpusubtype = (*get32) (raw.cpusubtype);
1796 header->filetype = (*get32) (raw.filetype);
1797 header->ncmds = (*get32) (raw.ncmds);
1798 header->sizeofcmds = (*get32) (raw.sizeofcmds);
1799 header->flags = (*get32) (raw.flags);
3af9a47b 1800
c2f09c75 1801 if (mach_o_wide_p (header))
46d1c23b 1802 header->reserved = (*get32) (raw.reserved);
1e8a024a 1803
154a1ee5 1804 return TRUE;
3af9a47b
NC
1805}
1806
f1bde64c
TG
1807bfd_boolean
1808bfd_mach_o_new_section_hook (bfd *abfd, asection *sec)
1809{
1810 bfd_mach_o_section *s;
a4551119 1811 unsigned bfdalign = bfd_get_section_alignment (abfd, sec);
f1bde64c
TG
1812
1813 s = bfd_mach_o_get_mach_o_section (sec);
1814 if (s == NULL)
1815 {
1816 flagword bfd_flags;
a4551119 1817 static const mach_o_section_name_xlat * xlat;
f1bde64c
TG
1818
1819 s = (bfd_mach_o_section *) bfd_zalloc (abfd, sizeof (*s));
1820 if (s == NULL)
1821 return FALSE;
1822 sec->used_by_bfd = s;
1823 s->bfdsection = sec;
1824
a4551119
TG
1825 /* Create the Darwin seg/sect name pair from the bfd name.
1826 If this is a canonical name for which a specific paiting exists
1827 there will also be defined flags, type, attribute and alignment
1828 values. */
1829 xlat = bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, s);
1830 if (xlat != NULL)
1831 {
1832 s->flags = xlat->macho_sectype | xlat->macho_secattr;
1833 s->align = xlat->sectalign > bfdalign ? xlat->sectalign
1834 : bfdalign;
1835 bfd_set_section_alignment (abfd, sec, s->align);
1836 bfd_flags = bfd_get_section_flags (abfd, sec);
1837 if (bfd_flags == SEC_NO_FLAGS)
1838 bfd_set_section_flags (abfd, sec, xlat->bfd_flags);
1839 }
f1bde64c 1840 else
a4551119
TG
1841 /* Create default flags. */
1842 bfd_mach_o_set_section_flags_from_bfd (abfd, sec);
f1bde64c
TG
1843 }
1844
1845 return _bfd_generic_new_section_hook (abfd, sec);
1846}
1847
1848static void
1849bfd_mach_o_init_section_from_mach_o (bfd *abfd, asection *sec,
1850 unsigned long prot)
3af9a47b 1851{
117ed4f8 1852 flagword flags;
f1bde64c 1853 bfd_mach_o_section *section;
3af9a47b 1854
f1bde64c
TG
1855 flags = bfd_get_section_flags (abfd, sec);
1856 section = bfd_mach_o_get_mach_o_section (sec);
3af9a47b 1857
a4551119
TG
1858 /* TODO: see if we should use the xlat system for doing this by
1859 preference and fall back to this for unknown sections. */
1860
8462aec7 1861 if (flags == SEC_NO_FLAGS)
ef17cb22 1862 {
8462aec7
TG
1863 /* Try to guess flags. */
1864 if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
1865 flags = SEC_DEBUGGING;
1866 else
1867 {
1868 flags = SEC_ALLOC;
1869 if ((section->flags & BFD_MACH_O_SECTION_TYPE_MASK)
1870 != BFD_MACH_O_S_ZEROFILL)
1871 {
1872 flags |= SEC_LOAD;
1873 if (prot & BFD_MACH_O_PROT_EXECUTE)
1874 flags |= SEC_CODE;
1875 if (prot & BFD_MACH_O_PROT_WRITE)
1876 flags |= SEC_DATA;
1877 else if (prot & BFD_MACH_O_PROT_READ)
1878 flags |= SEC_READONLY;
1879 }
1880 }
ef17cb22 1881 }
15e1c58a
TG
1882 else
1883 {
8462aec7
TG
1884 if ((flags & SEC_DEBUGGING) == 0)
1885 flags |= SEC_ALLOC;
15e1c58a 1886 }
8462aec7
TG
1887
1888 if (section->offset != 0)
1889 flags |= SEC_HAS_CONTENTS;
92bc0e80
TG
1890 if (section->nreloc != 0)
1891 flags |= SEC_RELOC;
1892
f1bde64c
TG
1893 bfd_set_section_flags (abfd, sec, flags);
1894
1895 sec->vma = section->addr;
1896 sec->lma = section->addr;
1897 sec->size = section->size;
1898 sec->filepos = section->offset;
1899 sec->alignment_power = section->align;
1900 sec->segment_mark = 0;
1901 sec->reloc_count = section->nreloc;
1902 sec->rel_filepos = section->reloff;
1903}
1904
1905static asection *
1906bfd_mach_o_make_bfd_section (bfd *abfd,
1907 const unsigned char *segname,
1908 const unsigned char *sectname)
1909{
1910 const char *sname;
1911 flagword flags;
a95a4550 1912
f1bde64c
TG
1913 bfd_mach_o_convert_section_name_to_bfd
1914 (abfd, (const char *)segname, (const char *)sectname, &sname, &flags);
1915 if (sname == NULL)
1916 return NULL;
3af9a47b 1917
f1bde64c 1918 return bfd_make_section_anyway_with_flags (abfd, sname, flags);
3af9a47b
NC
1919}
1920
f1bde64c 1921static asection *
ab273af8 1922bfd_mach_o_read_section_32 (bfd *abfd,
ab273af8
TG
1923 unsigned int offset,
1924 unsigned long prot)
3af9a47b 1925{
46d1c23b 1926 struct mach_o_section_32_external raw;
f1bde64c
TG
1927 asection *sec;
1928 bfd_mach_o_section *section;
3af9a47b 1929
c2f09c75 1930 if (bfd_seek (abfd, offset, SEEK_SET) != 0
46d1c23b 1931 || (bfd_bread (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
c2f09c75 1932 != BFD_MACH_O_SECTION_SIZE))
f1bde64c 1933 return NULL;
a95a4550 1934
5a5cbf72 1935 sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
f1bde64c
TG
1936 if (sec == NULL)
1937 return NULL;
1938
1939 section = bfd_mach_o_get_mach_o_section (sec);
1940 memcpy (section->segname, raw.segname, sizeof (raw.segname));
1941 section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
1942 memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
69499dca 1943 section->sectname[BFD_MACH_O_SECTNAME_SIZE] = 0;
46d1c23b
TG
1944 section->addr = bfd_h_get_32 (abfd, raw.addr);
1945 section->size = bfd_h_get_32 (abfd, raw.size);
1946 section->offset = bfd_h_get_32 (abfd, raw.offset);
1947 section->align = bfd_h_get_32 (abfd, raw.align);
1948 section->reloff = bfd_h_get_32 (abfd, raw.reloff);
1949 section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
1950 section->flags = bfd_h_get_32 (abfd, raw.flags);
1951 section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
1952 section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
1e8a024a 1953 section->reserved3 = 0;
1e8a024a 1954
f1bde64c 1955 bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
1e8a024a 1956
f1bde64c 1957 return sec;
1e8a024a
TG
1958}
1959
f1bde64c 1960static asection *
ab273af8 1961bfd_mach_o_read_section_64 (bfd *abfd,
ab273af8
TG
1962 unsigned int offset,
1963 unsigned long prot)
1e8a024a 1964{
46d1c23b 1965 struct mach_o_section_64_external raw;
f1bde64c
TG
1966 asection *sec;
1967 bfd_mach_o_section *section;
1e8a024a 1968
c2f09c75 1969 if (bfd_seek (abfd, offset, SEEK_SET) != 0
46d1c23b 1970 || (bfd_bread (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
c2f09c75 1971 != BFD_MACH_O_SECTION_64_SIZE))
f1bde64c
TG
1972 return NULL;
1973
5a5cbf72 1974 sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
f1bde64c
TG
1975 if (sec == NULL)
1976 return NULL;
1e8a024a 1977
f1bde64c
TG
1978 section = bfd_mach_o_get_mach_o_section (sec);
1979 memcpy (section->segname, raw.segname, sizeof (raw.segname));
1980 section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
1981 memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
69499dca 1982 section->sectname[BFD_MACH_O_SECTNAME_SIZE] = 0;
46d1c23b
TG
1983 section->addr = bfd_h_get_64 (abfd, raw.addr);
1984 section->size = bfd_h_get_64 (abfd, raw.size);
1985 section->offset = bfd_h_get_32 (abfd, raw.offset);
1986 section->align = bfd_h_get_32 (abfd, raw.align);
1987 section->reloff = bfd_h_get_32 (abfd, raw.reloff);
1988 section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
1989 section->flags = bfd_h_get_32 (abfd, raw.flags);
1990 section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
1991 section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
1992 section->reserved3 = bfd_h_get_32 (abfd, raw.reserved3);
3af9a47b 1993
f1bde64c 1994 bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
3af9a47b 1995
f1bde64c 1996 return sec;
3af9a47b
NC
1997}
1998
f1bde64c 1999static asection *
ab273af8 2000bfd_mach_o_read_section (bfd *abfd,
ab273af8
TG
2001 unsigned int offset,
2002 unsigned long prot,
2003 unsigned int wide)
1e8a024a
TG
2004{
2005 if (wide)
f1bde64c 2006 return bfd_mach_o_read_section_64 (abfd, offset, prot);
1e8a024a 2007 else
f1bde64c 2008 return bfd_mach_o_read_section_32 (abfd, offset, prot);
1e8a024a
TG
2009}
2010
afbb9e17 2011static bfd_boolean
ab273af8
TG
2012bfd_mach_o_read_symtab_symbol (bfd *abfd,
2013 bfd_mach_o_symtab_command *sym,
2014 bfd_mach_o_asymbol *s,
2015 unsigned long i)
3af9a47b 2016{
046b007d 2017 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
c2f09c75 2018 unsigned int wide = mach_o_wide_p (&mdata->header);
046b007d
TG
2019 unsigned int symwidth =
2020 wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
92bc0e80 2021 unsigned int symoff = sym->symoff + (i * symwidth);
46d1c23b 2022 struct mach_o_nlist_64_external raw;
3af9a47b
NC
2023 unsigned char type = -1;
2024 unsigned char section = -1;
2025 short desc = -1;
1e8a024a 2026 symvalue value = -1;
3af9a47b
NC
2027 unsigned long stroff = -1;
2028 unsigned int symtype = -1;
2029
2030 BFD_ASSERT (sym->strtab != NULL);
2031
c2f09c75 2032 if (bfd_seek (abfd, symoff, SEEK_SET) != 0
46d1c23b 2033 || bfd_bread (&raw, symwidth, abfd) != symwidth)
3af9a47b 2034 {
46d1c23b
TG
2035 (*_bfd_error_handler)
2036 (_("bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"),
2037 symwidth, (unsigned long) symoff);
afbb9e17 2038 return FALSE;
3af9a47b
NC
2039 }
2040
46d1c23b
TG
2041 stroff = bfd_h_get_32 (abfd, raw.n_strx);
2042 type = bfd_h_get_8 (abfd, raw.n_type);
c2f09c75 2043 symtype = type & BFD_MACH_O_N_TYPE;
46d1c23b
TG
2044 section = bfd_h_get_8 (abfd, raw.n_sect);
2045 desc = bfd_h_get_16 (abfd, raw.n_desc);
1e8a024a 2046 if (wide)
46d1c23b 2047 value = bfd_h_get_64 (abfd, raw.n_value);
1e8a024a 2048 else
46d1c23b 2049 value = bfd_h_get_32 (abfd, raw.n_value);
3af9a47b
NC
2050
2051 if (stroff >= sym->strsize)
2052 {
46d1c23b
TG
2053 (*_bfd_error_handler)
2054 (_("bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"),
2055 (unsigned long) stroff,
2056 (unsigned long) sym->strsize);
afbb9e17 2057 return FALSE;
3af9a47b
NC
2058 }
2059
92bc0e80
TG
2060 s->symbol.the_bfd = abfd;
2061 s->symbol.name = sym->strtab + stroff;
2062 s->symbol.value = value;
2063 s->symbol.flags = 0x0;
2064 s->symbol.udata.i = 0;
2065 s->n_type = type;
2066 s->n_sect = section;
2067 s->n_desc = desc;
3af9a47b
NC
2068
2069 if (type & BFD_MACH_O_N_STAB)
2070 {
92bc0e80
TG
2071 s->symbol.flags |= BSF_DEBUGGING;
2072 s->symbol.section = bfd_und_section_ptr;
15e1c58a
TG
2073 switch (type)
2074 {
2075 case N_FUN:
2076 case N_STSYM:
2077 case N_LCSYM:
2078 case N_BNSYM:
2079 case N_SLINE:
2080 case N_ENSYM:
2081 case N_ECOMM:
2082 case N_ECOML:
2083 case N_GSYM:
2084 if ((section > 0) && (section <= mdata->nsects))
2085 {
92bc0e80
TG
2086 s->symbol.section = mdata->sections[section - 1]->bfdsection;
2087 s->symbol.value =
2088 s->symbol.value - mdata->sections[section - 1]->addr;
15e1c58a
TG
2089 }
2090 break;
2091 }
3af9a47b
NC
2092 }
2093 else
2094 {
2095 if (type & BFD_MACH_O_N_PEXT)
92bc0e80 2096 s->symbol.flags |= BSF_GLOBAL;
c2f09c75 2097
3af9a47b 2098 if (type & BFD_MACH_O_N_EXT)
92bc0e80 2099 s->symbol.flags |= BSF_GLOBAL;
15e1c58a
TG
2100
2101 if (!(type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT)))
92bc0e80 2102 s->symbol.flags |= BSF_LOCAL;
3af9a47b
NC
2103
2104 switch (symtype)
2105 {
2106 case BFD_MACH_O_N_UNDF:
c2f09c75 2107 if (type == (BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT)
92bc0e80 2108 && s->symbol.value != 0)
c2f09c75
TG
2109 {
2110 /* A common symbol. */
92bc0e80
TG
2111 s->symbol.section = bfd_com_section_ptr;
2112 s->symbol.flags = BSF_NO_FLAGS;
c2f09c75
TG
2113 }
2114 else
92bc0e80
TG
2115 {
2116 s->symbol.section = bfd_und_section_ptr;
2117 if (s->n_desc & BFD_MACH_O_N_WEAK_REF)
2118 s->symbol.flags |= BSF_WEAK;
2119 }
3af9a47b
NC
2120 break;
2121 case BFD_MACH_O_N_PBUD:
92bc0e80 2122 s->symbol.section = bfd_und_section_ptr;
3af9a47b
NC
2123 break;
2124 case BFD_MACH_O_N_ABS:
92bc0e80 2125 s->symbol.section = bfd_abs_section_ptr;
3af9a47b
NC
2126 break;
2127 case BFD_MACH_O_N_SECT:
2128 if ((section > 0) && (section <= mdata->nsects))
2129 {
92bc0e80
TG
2130 s->symbol.section = mdata->sections[section - 1]->bfdsection;
2131 s->symbol.value =
2132 s->symbol.value - mdata->sections[section - 1]->addr;
3af9a47b
NC
2133 }
2134 else
2135 {
2136 /* Mach-O uses 0 to mean "no section"; not an error. */
2137 if (section != 0)
2138 {
4a97a0e5
AM
2139 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
2140 "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"),
2141 s->symbol.name, section, mdata->nsects);
3af9a47b 2142 }
92bc0e80 2143 s->symbol.section = bfd_und_section_ptr;
3af9a47b
NC
2144 }
2145 break;
2146 case BFD_MACH_O_N_INDR:
0596a831
TG
2147 /* FIXME: we don't follow the BFD convention as this indirect symbol
2148 won't be followed by the referenced one. This looks harmless
2149 unless we start using the linker. */
2150 s->symbol.flags |= BSF_INDIRECT;
2151 s->symbol.section = bfd_ind_section_ptr;
2152 s->symbol.value = 0;
3af9a47b
NC
2153 break;
2154 default:
4a97a0e5
AM
2155 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
2156 "symbol \"%s\" specified invalid type field 0x%x: setting to undefined"),
2157 s->symbol.name, symtype);
92bc0e80 2158 s->symbol.section = bfd_und_section_ptr;
3af9a47b
NC
2159 break;
2160 }
2161 }
2162
afbb9e17 2163 return TRUE;
3af9a47b
NC
2164}
2165
c5012cd8 2166bfd_boolean
ab273af8 2167bfd_mach_o_read_symtab_strtab (bfd *abfd)
3af9a47b 2168{
046b007d
TG
2169 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2170 bfd_mach_o_symtab_command *sym = mdata->symtab;
2171
2172 /* Fail if there is no symtab. */
2173 if (sym == NULL)
afbb9e17 2174 return FALSE;
046b007d
TG
2175
2176 /* Success if already loaded. */
2177 if (sym->strtab)
afbb9e17 2178 return TRUE;
3af9a47b
NC
2179
2180 if (abfd->flags & BFD_IN_MEMORY)
2181 {
2182 struct bfd_in_memory *b;
2183
2184 b = (struct bfd_in_memory *) abfd->iostream;
2185
2186 if ((sym->stroff + sym->strsize) > b->size)
2187 {
2188 bfd_set_error (bfd_error_file_truncated);
afbb9e17 2189 return FALSE;
3af9a47b 2190 }
f075ee0c 2191 sym->strtab = (char *) b->buffer + sym->stroff;
3af9a47b 2192 }
046b007d 2193 else
3af9a47b 2194 {
046b007d
TG
2195 sym->strtab = bfd_alloc (abfd, sym->strsize);
2196 if (sym->strtab == NULL)
afbb9e17 2197 return FALSE;
046b007d
TG
2198
2199 if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0
afbb9e17 2200 || bfd_bread (sym->strtab, sym->strsize, abfd) != sym->strsize)
046b007d
TG
2201 {
2202 bfd_set_error (bfd_error_file_truncated);
afbb9e17 2203 return FALSE;
046b007d 2204 }
3af9a47b
NC
2205 }
2206
afbb9e17 2207 return TRUE;
3af9a47b
NC
2208}
2209
c5012cd8 2210bfd_boolean
ab273af8 2211bfd_mach_o_read_symtab_symbols (bfd *abfd)
3af9a47b 2212{
046b007d
TG
2213 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2214 bfd_mach_o_symtab_command *sym = mdata->symtab;
3af9a47b 2215 unsigned long i;
3af9a47b 2216
092d27ff
TG
2217 if (sym == NULL || sym->symbols)
2218 {
2219 /* Return now if there are no symbols or if already loaded. */
afbb9e17 2220 return TRUE;
092d27ff 2221 }
046b007d 2222
92bc0e80 2223 sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
3af9a47b
NC
2224
2225 if (sym->symbols == NULL)
2226 {
4a97a0e5 2227 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"));
afbb9e17 2228 return FALSE;
3af9a47b 2229 }
a95a4550 2230
afbb9e17
TG
2231 if (!bfd_mach_o_read_symtab_strtab (abfd))
2232 return FALSE;
3af9a47b
NC
2233
2234 for (i = 0; i < sym->nsyms; i++)
2235 {
afbb9e17
TG
2236 if (!bfd_mach_o_read_symtab_symbol (abfd, sym, &sym->symbols[i], i))
2237 return FALSE;
3af9a47b 2238 }
a95a4550 2239
afbb9e17 2240 return TRUE;
3af9a47b
NC
2241}
2242
2243static const char *
116c20d2 2244bfd_mach_o_i386_flavour_string (unsigned int flavour)
3af9a47b
NC
2245{
2246 switch ((int) flavour)
2247 {
15e1c58a
TG
2248 case BFD_MACH_O_x86_THREAD_STATE32: return "x86_THREAD_STATE32";
2249 case BFD_MACH_O_x86_FLOAT_STATE32: return "x86_FLOAT_STATE32";
2250 case BFD_MACH_O_x86_EXCEPTION_STATE32: return "x86_EXCEPTION_STATE32";
2251 case BFD_MACH_O_x86_THREAD_STATE64: return "x86_THREAD_STATE64";
2252 case BFD_MACH_O_x86_FLOAT_STATE64: return "x86_FLOAT_STATE64";
2253 case BFD_MACH_O_x86_EXCEPTION_STATE64: return "x86_EXCEPTION_STATE64";
2254 case BFD_MACH_O_x86_THREAD_STATE: return "x86_THREAD_STATE";
2255 case BFD_MACH_O_x86_FLOAT_STATE: return "x86_FLOAT_STATE";
2256 case BFD_MACH_O_x86_EXCEPTION_STATE: return "x86_EXCEPTION_STATE";
2257 case BFD_MACH_O_x86_DEBUG_STATE32: return "x86_DEBUG_STATE32";
2258 case BFD_MACH_O_x86_DEBUG_STATE64: return "x86_DEBUG_STATE64";
2259 case BFD_MACH_O_x86_DEBUG_STATE: return "x86_DEBUG_STATE";
b32e07d7 2260 case BFD_MACH_O_x86_THREAD_STATE_NONE: return "x86_THREAD_STATE_NONE";
3af9a47b
NC
2261 default: return "UNKNOWN";
2262 }
2263}
2264
2265static const char *
116c20d2 2266bfd_mach_o_ppc_flavour_string (unsigned int flavour)
3af9a47b
NC
2267{
2268 switch ((int) flavour)
2269 {
b32e07d7
TG
2270 case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
2271 case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
2272 case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
2273 case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
2274 case BFD_MACH_O_PPC_THREAD_STATE64: return "PPC_THREAD_STATE64";
2275 case BFD_MACH_O_PPC_EXCEPTION_STATE64: return "PPC_EXCEPTION_STATE64";
3af9a47b
NC
2276 default: return "UNKNOWN";
2277 }
2278}
2279
2280static int
ab273af8 2281bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b
NC
2282{
2283 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
46d1c23b 2284 struct mach_o_str_command_external raw;
3af9a47b 2285 unsigned int nameoff;
3af9a47b
NC
2286
2287 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
2288 || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
2289
46d1c23b
TG
2290 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2291 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
2292 return -1;
2293
46d1c23b 2294 nameoff = bfd_h_get_32 (abfd, raw.str);
3af9a47b
NC
2295
2296 cmd->name_offset = command->offset + nameoff;
2297 cmd->name_len = command->len - nameoff;
b32e07d7
TG
2298 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
2299 if (cmd->name_str == NULL)
3af9a47b 2300 return -1;
b32e07d7
TG
2301 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
2302 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
3af9a47b 2303 return -1;
3af9a47b
NC
2304 return 0;
2305}
2306
2307static int
ab273af8 2308bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b
NC
2309{
2310 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
46d1c23b 2311 struct mach_o_dylib_command_external raw;
3af9a47b 2312 unsigned int nameoff;
3af9a47b 2313
046b007d
TG
2314 switch (command->type)
2315 {
2316 case BFD_MACH_O_LC_LOAD_DYLIB:
046b007d 2317 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
046b007d 2318 case BFD_MACH_O_LC_ID_DYLIB:
046b007d 2319 case BFD_MACH_O_LC_REEXPORT_DYLIB:
73017762 2320 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
046b007d
TG
2321 break;
2322 default:
b32e07d7
TG
2323 BFD_FAIL ();
2324 return -1;
046b007d 2325 }
3af9a47b 2326
46d1c23b
TG
2327 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2328 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
2329 return -1;
2330
46d1c23b
TG
2331 nameoff = bfd_h_get_32 (abfd, raw.name);
2332 cmd->timestamp = bfd_h_get_32 (abfd, raw.timestamp);
2333 cmd->current_version = bfd_h_get_32 (abfd, raw.current_version);
2334 cmd->compatibility_version = bfd_h_get_32 (abfd, raw.compatibility_version);
3af9a47b
NC
2335
2336 cmd->name_offset = command->offset + nameoff;
2337 cmd->name_len = command->len - nameoff;
b32e07d7
TG
2338 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
2339 if (cmd->name_str == NULL)
3af9a47b 2340 return -1;
b32e07d7
TG
2341 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
2342 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
3af9a47b 2343 return -1;
3af9a47b
NC
2344 return 0;
2345}
2346
2347static int
ab273af8
TG
2348bfd_mach_o_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
2349 bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
3af9a47b
NC
2350{
2351 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
2352
2353 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
2354 return 0;
2355}
2356
2357static int
ab273af8 2358bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 2359{
b32e07d7 2360 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 2361 bfd_mach_o_thread_command *cmd = &command->command.thread;
92bc0e80 2362 unsigned int offset;
3af9a47b
NC
2363 unsigned int nflavours;
2364 unsigned int i;
2365
2366 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
2367 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
2368
b32e07d7 2369 /* Count the number of threads. */
3af9a47b
NC
2370 offset = 8;
2371 nflavours = 0;
2372 while (offset != command->len)
2373 {
46d1c23b
TG
2374 struct mach_o_thread_command_external raw;
2375
3af9a47b
NC
2376 if (offset >= command->len)
2377 return -1;
2378
c2f09c75 2379 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
46d1c23b 2380 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
2381 return -1;
2382
46d1c23b 2383 offset += sizeof (raw) + bfd_h_get_32 (abfd, raw.count) * 4;
3af9a47b
NC
2384 nflavours++;
2385 }
2386
b32e07d7
TG
2387 /* Allocate threads. */
2388 cmd->flavours = bfd_alloc
2389 (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
3af9a47b
NC
2390 if (cmd->flavours == NULL)
2391 return -1;
2392 cmd->nflavours = nflavours;
2393
2394 offset = 8;
2395 nflavours = 0;
2396 while (offset != command->len)
2397 {
46d1c23b
TG
2398 struct mach_o_thread_command_external raw;
2399
3af9a47b
NC
2400 if (offset >= command->len)
2401 return -1;
2402
2403 if (nflavours >= cmd->nflavours)
2404 return -1;
2405
c2f09c75 2406 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
46d1c23b 2407 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b
NC
2408 return -1;
2409
46d1c23b
TG
2410 cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, raw.flavour);
2411 cmd->flavours[nflavours].offset = command->offset + offset + sizeof (raw);
2412 cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, raw.count) * 4;
2413 offset += cmd->flavours[nflavours].size + sizeof (raw);
3af9a47b
NC
2414 nflavours++;
2415 }
2416
2417 for (i = 0; i < nflavours; i++)
2418 {
2419 asection *bfdsec;
2420 unsigned int snamelen;
2421 char *sname;
2422 const char *flavourstr;
2423 const char *prefix = "LC_THREAD";
a95a4550
AM
2424 unsigned int j = 0;
2425
3af9a47b
NC
2426 switch (mdata->header.cputype)
2427 {
2428 case BFD_MACH_O_CPU_TYPE_POWERPC:
1e8a024a 2429 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
3af9a47b
NC
2430 flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
2431 break;
2432 case BFD_MACH_O_CPU_TYPE_I386:
1e8a024a 2433 case BFD_MACH_O_CPU_TYPE_X86_64:
3af9a47b
NC
2434 flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
2435 break;
2436 default:
2437 flavourstr = "UNKNOWN_ARCHITECTURE";
2438 break;
2439 }
a95a4550 2440
3af9a47b 2441 snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
116c20d2 2442 sname = bfd_alloc (abfd, snamelen);
3af9a47b
NC
2443 if (sname == NULL)
2444 return -1;
2445
2446 for (;;)
2447 {
a95a4550
AM
2448 sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
2449 if (bfd_get_section_by_name (abfd, sname) == NULL)
3af9a47b 2450 break;
a95a4550 2451 j++;
3af9a47b
NC
2452 }
2453
117ed4f8 2454 bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
a95a4550 2455
3af9a47b
NC
2456 bfdsec->vma = 0;
2457 bfdsec->lma = 0;
eea6121a 2458 bfdsec->size = cmd->flavours[i].size;
3af9a47b
NC
2459 bfdsec->filepos = cmd->flavours[i].offset;
2460 bfdsec->alignment_power = 0x0;
3af9a47b
NC
2461
2462 cmd->section = bfdsec;
2463 }
2464
2465 return 0;
2466}
2467
a95a4550 2468static int
ab273af8 2469bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 2470{
046b007d 2471 bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
b32e07d7 2472 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b
NC
2473
2474 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
2475
46d1c23b
TG
2476 {
2477 struct mach_o_dysymtab_command_external raw;
2478
2479 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2480 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2481 return -1;
3af9a47b 2482
46d1c23b
TG
2483 cmd->ilocalsym = bfd_h_get_32 (abfd, raw.ilocalsym);
2484 cmd->nlocalsym = bfd_h_get_32 (abfd, raw.nlocalsym);
2485 cmd->iextdefsym = bfd_h_get_32 (abfd, raw.iextdefsym);
2486 cmd->nextdefsym = bfd_h_get_32 (abfd, raw.nextdefsym);
2487 cmd->iundefsym = bfd_h_get_32 (abfd, raw.iundefsym);
2488 cmd->nundefsym = bfd_h_get_32 (abfd, raw.nundefsym);
2489 cmd->tocoff = bfd_h_get_32 (abfd, raw.tocoff);
2490 cmd->ntoc = bfd_h_get_32 (abfd, raw.ntoc);
2491 cmd->modtaboff = bfd_h_get_32 (abfd, raw.modtaboff);
2492 cmd->nmodtab = bfd_h_get_32 (abfd, raw.nmodtab);
2493 cmd->extrefsymoff = bfd_h_get_32 (abfd, raw.extrefsymoff);
2494 cmd->nextrefsyms = bfd_h_get_32 (abfd, raw.nextrefsyms);
2495 cmd->indirectsymoff = bfd_h_get_32 (abfd, raw.indirectsymoff);
2496 cmd->nindirectsyms = bfd_h_get_32 (abfd, raw.nindirectsyms);
2497 cmd->extreloff = bfd_h_get_32 (abfd, raw.extreloff);
2498 cmd->nextrel = bfd_h_get_32 (abfd, raw.nextrel);
2499 cmd->locreloff = bfd_h_get_32 (abfd, raw.locreloff);
2500 cmd->nlocrel = bfd_h_get_32 (abfd, raw.nlocrel);
2501 }
046b007d
TG
2502
2503 if (cmd->nmodtab != 0)
2504 {
046b007d
TG
2505 unsigned int i;
2506 int wide = bfd_mach_o_wide_p (abfd);
2507 unsigned int module_len = wide ? 56 : 52;
2508
2509 cmd->dylib_module =
2510 bfd_alloc (abfd, cmd->nmodtab * sizeof (bfd_mach_o_dylib_module));
2511 if (cmd->dylib_module == NULL)
2512 return -1;
2513
2514 if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0)
2515 return -1;
2516
2517 for (i = 0; i < cmd->nmodtab; i++)
2518 {
2519 bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
2520 unsigned long v;
46d1c23b 2521 unsigned char buf[56];
046b007d 2522
91d6fa6a 2523 if (bfd_bread ((void *) buf, module_len, abfd) != module_len)
046b007d
TG
2524 return -1;
2525
2526 module->module_name_idx = bfd_h_get_32 (abfd, buf + 0);
2527 module->iextdefsym = bfd_h_get_32 (abfd, buf + 4);
2528 module->nextdefsym = bfd_h_get_32 (abfd, buf + 8);
2529 module->irefsym = bfd_h_get_32 (abfd, buf + 12);
2530 module->nrefsym = bfd_h_get_32 (abfd, buf + 16);
2531 module->ilocalsym = bfd_h_get_32 (abfd, buf + 20);
2532 module->nlocalsym = bfd_h_get_32 (abfd, buf + 24);
2533 module->iextrel = bfd_h_get_32 (abfd, buf + 28);
2534 module->nextrel = bfd_h_get_32 (abfd, buf + 32);
2535 v = bfd_h_get_32 (abfd, buf +36);
2536 module->iinit = v & 0xffff;
2537 module->iterm = (v >> 16) & 0xffff;
2538 v = bfd_h_get_32 (abfd, buf + 40);
2539 module->ninit = v & 0xffff;
2540 module->nterm = (v >> 16) & 0xffff;
2541 if (wide)
2542 {
2543 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 44);
2544 module->objc_module_info_addr = bfd_h_get_64 (abfd, buf + 48);
2545 }
2546 else
2547 {
2548 module->objc_module_info_addr = bfd_h_get_32 (abfd, buf + 44);
2549 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 48);
2550 }
2551 }
2552 }
afbb9e17 2553
046b007d
TG
2554 if (cmd->ntoc != 0)
2555 {
046b007d
TG
2556 unsigned int i;
2557
2558 cmd->dylib_toc = bfd_alloc
2559 (abfd, cmd->ntoc * sizeof (bfd_mach_o_dylib_table_of_content));
2560 if (cmd->dylib_toc == NULL)
2561 return -1;
2562
2563 if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
2564 return -1;
2565
2566 for (i = 0; i < cmd->ntoc; i++)
2567 {
46d1c23b 2568 struct mach_o_dylib_table_of_contents_external raw;
046b007d
TG
2569 bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
2570
46d1c23b 2571 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
2572 return -1;
2573
46d1c23b
TG
2574 toc->symbol_index = bfd_h_get_32 (abfd, raw.symbol_index);
2575 toc->module_index = bfd_h_get_32 (abfd, raw.module_index);
046b007d
TG
2576 }
2577 }
2578
2579 if (cmd->nindirectsyms != 0)
2580 {
046b007d
TG
2581 unsigned int i;
2582
2583 cmd->indirect_syms = bfd_alloc
2584 (abfd, cmd->nindirectsyms * sizeof (unsigned int));
2585 if (cmd->indirect_syms == NULL)
2586 return -1;
2587
2588 if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
2589 return -1;
2590
2591 for (i = 0; i < cmd->nindirectsyms; i++)
2592 {
46d1c23b 2593 unsigned char raw[4];
046b007d
TG
2594 unsigned int *is = &cmd->indirect_syms[i];
2595
46d1c23b 2596 if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
2597 return -1;
2598
46d1c23b 2599 *is = bfd_h_get_32 (abfd, raw);
046b007d
TG
2600 }
2601 }
2602
2603 if (cmd->nextrefsyms != 0)
2604 {
046b007d
TG
2605 unsigned long v;
2606 unsigned int i;
2607
2608 cmd->ext_refs = bfd_alloc
2609 (abfd, cmd->nextrefsyms * sizeof (bfd_mach_o_dylib_reference));
2610 if (cmd->ext_refs == NULL)
2611 return -1;
2612
2613 if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
2614 return -1;
2615
2616 for (i = 0; i < cmd->nextrefsyms; i++)
2617 {
46d1c23b 2618 unsigned char raw[4];
046b007d
TG
2619 bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
2620
46d1c23b 2621 if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
2622 return -1;
2623
b32e07d7
TG
2624 /* Fields isym and flags are written as bit-fields, thus we need
2625 a specific processing for endianness. */
46d1c23b 2626 v = bfd_h_get_32 (abfd, raw);
b32e07d7
TG
2627 if (bfd_big_endian (abfd))
2628 {
2629 ref->isym = (v >> 8) & 0xffffff;
2630 ref->flags = v & 0xff;
2631 }
2632 else
2633 {
2634 ref->isym = v & 0xffffff;
2635 ref->flags = (v >> 24) & 0xff;
2636 }
046b007d
TG
2637 }
2638 }
3af9a47b 2639
b32e07d7
TG
2640 if (mdata->dysymtab)
2641 return -1;
2642 mdata->dysymtab = cmd;
2643
3af9a47b
NC
2644 return 0;
2645}
2646
a95a4550 2647static int
ab273af8 2648bfd_mach_o_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 2649{
046b007d
TG
2650 bfd_mach_o_symtab_command *symtab = &command->command.symtab;
2651 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
46d1c23b 2652 struct mach_o_symtab_command_external raw;
3af9a47b
NC
2653
2654 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
2655
46d1c23b
TG
2656 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2657 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
3af9a47b 2658 return -1;
a95a4550 2659
46d1c23b
TG
2660 symtab->symoff = bfd_h_get_32 (abfd, raw.symoff);
2661 symtab->nsyms = bfd_h_get_32 (abfd, raw.nsyms);
2662 symtab->stroff = bfd_h_get_32 (abfd, raw.stroff);
2663 symtab->strsize = bfd_h_get_32 (abfd, raw.strsize);
046b007d
TG
2664 symtab->symbols = NULL;
2665 symtab->strtab = NULL;
3af9a47b 2666
046b007d 2667 if (symtab->nsyms != 0)
15e1c58a
TG
2668 abfd->flags |= HAS_SYMS;
2669
046b007d
TG
2670 if (mdata->symtab)
2671 return -1;
2672 mdata->symtab = symtab;
3af9a47b
NC
2673 return 0;
2674}
2675
15e1c58a 2676static int
ab273af8 2677bfd_mach_o_read_uuid (bfd *abfd, bfd_mach_o_load_command *command)
15e1c58a
TG
2678{
2679 bfd_mach_o_uuid_command *cmd = &command->command.uuid;
15e1c58a
TG
2680
2681 BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
2682
46d1c23b
TG
2683 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2684 || bfd_bread (cmd->uuid, 16, abfd) != 16)
15e1c58a
TG
2685 return -1;
2686
15e1c58a
TG
2687 return 0;
2688}
2689
046b007d 2690static int
ab273af8 2691bfd_mach_o_read_linkedit (bfd *abfd, bfd_mach_o_load_command *command)
046b007d
TG
2692{
2693 bfd_mach_o_linkedit_command *cmd = &command->command.linkedit;
46d1c23b 2694 struct mach_o_linkedit_data_command_external raw;
046b007d 2695
46d1c23b
TG
2696 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2697 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
2698 return -1;
2699
46d1c23b
TG
2700 cmd->dataoff = bfd_get_32 (abfd, raw.dataoff);
2701 cmd->datasize = bfd_get_32 (abfd, raw.datasize);
046b007d
TG
2702 return 0;
2703}
2704
2705static int
ab273af8 2706bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command)
046b007d
TG
2707{
2708 bfd_mach_o_str_command *cmd = &command->command.str;
46d1c23b 2709 struct mach_o_str_command_external raw;
046b007d
TG
2710 unsigned long off;
2711
46d1c23b
TG
2712 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2713 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
046b007d
TG
2714 return -1;
2715
46d1c23b 2716 off = bfd_get_32 (abfd, raw.str);
046b007d
TG
2717 cmd->stroff = command->offset + off;
2718 cmd->str_len = command->len - off;
2719 cmd->str = bfd_alloc (abfd, cmd->str_len);
2720 if (cmd->str == NULL)
2721 return -1;
2722 if (bfd_seek (abfd, cmd->stroff, SEEK_SET) != 0
91d6fa6a 2723 || bfd_bread ((void *) cmd->str, cmd->str_len, abfd) != cmd->str_len)
046b007d
TG
2724 return -1;
2725 return 0;
2726}
2727
ad86f1fb 2728static int
ab273af8 2729bfd_mach_o_read_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
ad86f1fb
TG
2730{
2731 bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
46d1c23b 2732 struct mach_o_dyld_info_command_external raw;
ad86f1fb 2733
46d1c23b
TG
2734 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2735 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
ad86f1fb
TG
2736 return -1;
2737
46d1c23b
TG
2738 cmd->rebase_off = bfd_get_32 (abfd, raw.rebase_off);
2739 cmd->rebase_size = bfd_get_32 (abfd, raw.rebase_size);
2740 cmd->bind_off = bfd_get_32 (abfd, raw.bind_off);
2741 cmd->bind_size = bfd_get_32 (abfd, raw.bind_size);
2742 cmd->weak_bind_off = bfd_get_32 (abfd, raw.weak_bind_off);
2743 cmd->weak_bind_size = bfd_get_32 (abfd, raw.weak_bind_size);
2744 cmd->lazy_bind_off = bfd_get_32 (abfd, raw.lazy_bind_off);
2745 cmd->lazy_bind_size = bfd_get_32 (abfd, raw.lazy_bind_size);
2746 cmd->export_off = bfd_get_32 (abfd, raw.export_off);
2747 cmd->export_size = bfd_get_32 (abfd, raw.export_size);
ad86f1fb
TG
2748 return 0;
2749}
2750
edbdea0e
TG
2751static bfd_boolean
2752bfd_mach_o_read_version_min (bfd *abfd, bfd_mach_o_load_command *command)
2753{
2754 bfd_mach_o_version_min_command *cmd = &command->command.version_min;
2755 struct mach_o_version_min_command_external raw;
2756 unsigned int ver;
2757
2758 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2759 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2760 return FALSE;
2761
2762 ver = bfd_get_32 (abfd, raw.version);
2763 cmd->rel = ver >> 16;
2764 cmd->maj = ver >> 8;
2765 cmd->min = ver;
2766 cmd->reserved = bfd_get_32 (abfd, raw.reserved);
2767 return TRUE;
2768}
2769
3af9a47b 2770static int
ab273af8
TG
2771bfd_mach_o_read_segment (bfd *abfd,
2772 bfd_mach_o_load_command *command,
2773 unsigned int wide)
3af9a47b 2774{
3af9a47b
NC
2775 bfd_mach_o_segment_command *seg = &command->command.segment;
2776 unsigned long i;
a95a4550 2777
1e8a024a
TG
2778 if (wide)
2779 {
46d1c23b
TG
2780 struct mach_o_segment_command_64_external raw;
2781
1e8a024a 2782 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
3af9a47b 2783
46d1c23b
TG
2784 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2785 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2786 return -1;
3af9a47b 2787
46d1c23b 2788 memcpy (seg->segname, raw.segname, 16);
15e1c58a 2789 seg->segname[16] = '\0';
1e8a024a 2790
46d1c23b
TG
2791 seg->vmaddr = bfd_h_get_64 (abfd, raw.vmaddr);
2792 seg->vmsize = bfd_h_get_64 (abfd, raw.vmsize);
2793 seg->fileoff = bfd_h_get_64 (abfd, raw.fileoff);
2794 seg->filesize = bfd_h_get_64 (abfd, raw.filesize);
2795 seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
2796 seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
2797 seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
2798 seg->flags = bfd_h_get_32 (abfd, raw.flags);
1e8a024a
TG
2799 }
2800 else
2801 {
46d1c23b
TG
2802 struct mach_o_segment_command_32_external raw;
2803
1e8a024a
TG
2804 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
2805
46d1c23b
TG
2806 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2807 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2808 return -1;
1e8a024a 2809
46d1c23b 2810 memcpy (seg->segname, raw.segname, 16);
15e1c58a 2811 seg->segname[16] = '\0';
1e8a024a 2812
46d1c23b
TG
2813 seg->vmaddr = bfd_h_get_32 (abfd, raw.vmaddr);
2814 seg->vmsize = bfd_h_get_32 (abfd, raw.vmsize);
2815 seg->fileoff = bfd_h_get_32 (abfd, raw.fileoff);
2816 seg->filesize = bfd_h_get_32 (abfd, raw.filesize);
2817 seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
2818 seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
2819 seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
2820 seg->flags = bfd_h_get_32 (abfd, raw.flags);
1e8a024a 2821 }
9d4b6009
TG
2822 seg->sect_head = NULL;
2823 seg->sect_tail = NULL;
3af9a47b 2824
f1bde64c 2825 for (i = 0; i < seg->nsects; i++)
3af9a47b 2826 {
f1bde64c
TG
2827 bfd_vma segoff;
2828 asection *sec;
a95a4550 2829
f1bde64c
TG
2830 if (wide)
2831 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
2832 + (i * BFD_MACH_O_SECTION_64_SIZE);
2833 else
2834 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
2835 + (i * BFD_MACH_O_SECTION_SIZE);
3af9a47b 2836
f1bde64c
TG
2837 sec = bfd_mach_o_read_section (abfd, segoff, seg->initprot, wide);
2838 if (sec == NULL)
2839 return -1;
2840
2841 bfd_mach_o_append_section_to_segment (seg, sec);
3af9a47b
NC
2842 }
2843
2844 return 0;
2845}
2846
1e8a024a 2847static int
ab273af8 2848bfd_mach_o_read_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 2849{
ab273af8 2850 return bfd_mach_o_read_segment (abfd, command, 0);
1e8a024a
TG
2851}
2852
2853static int
ab273af8 2854bfd_mach_o_read_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 2855{
ab273af8 2856 return bfd_mach_o_read_segment (abfd, command, 1);
1e8a024a
TG
2857}
2858
3af9a47b 2859static int
ab273af8 2860bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b 2861{
46d1c23b
TG
2862 struct mach_o_load_command_external raw;
2863 unsigned int cmd;
3af9a47b 2864
046b007d 2865 /* Read command type and length. */
c2f09c75 2866 if (bfd_seek (abfd, command->offset, SEEK_SET) != 0
46d1c23b 2867 || bfd_bread (&raw, BFD_MACH_O_LC_SIZE, abfd) != BFD_MACH_O_LC_SIZE)
3af9a47b
NC
2868 return -1;
2869
46d1c23b
TG
2870 cmd = bfd_h_get_32 (abfd, raw.cmd);
2871 command->type = cmd & ~BFD_MACH_O_LC_REQ_DYLD;
2872 command->type_required = cmd & BFD_MACH_O_LC_REQ_DYLD ? TRUE : FALSE;
2873 command->len = bfd_h_get_32 (abfd, raw.cmdsize);
3af9a47b
NC
2874
2875 switch (command->type)
2876 {
2877 case BFD_MACH_O_LC_SEGMENT:
ab273af8 2878 if (bfd_mach_o_read_segment_32 (abfd, command) != 0)
1e8a024a
TG
2879 return -1;
2880 break;
2881 case BFD_MACH_O_LC_SEGMENT_64:
ab273af8 2882 if (bfd_mach_o_read_segment_64 (abfd, command) != 0)
3af9a47b
NC
2883 return -1;
2884 break;
2885 case BFD_MACH_O_LC_SYMTAB:
ab273af8 2886 if (bfd_mach_o_read_symtab (abfd, command) != 0)
3af9a47b
NC
2887 return -1;
2888 break;
2889 case BFD_MACH_O_LC_SYMSEG:
2890 break;
2891 case BFD_MACH_O_LC_THREAD:
2892 case BFD_MACH_O_LC_UNIXTHREAD:
ab273af8 2893 if (bfd_mach_o_read_thread (abfd, command) != 0)
3af9a47b
NC
2894 return -1;
2895 break;
2896 case BFD_MACH_O_LC_LOAD_DYLINKER:
2897 case BFD_MACH_O_LC_ID_DYLINKER:
ab273af8 2898 if (bfd_mach_o_read_dylinker (abfd, command) != 0)
3af9a47b
NC
2899 return -1;
2900 break;
2901 case BFD_MACH_O_LC_LOAD_DYLIB:
2902 case BFD_MACH_O_LC_ID_DYLIB:
2903 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
046b007d 2904 case BFD_MACH_O_LC_REEXPORT_DYLIB:
73017762 2905 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
ab273af8 2906 if (bfd_mach_o_read_dylib (abfd, command) != 0)
3af9a47b
NC
2907 return -1;
2908 break;
2909 case BFD_MACH_O_LC_PREBOUND_DYLIB:
ab273af8 2910 if (bfd_mach_o_read_prebound_dylib (abfd, command) != 0)
3af9a47b
NC
2911 return -1;
2912 break;
2913 case BFD_MACH_O_LC_LOADFVMLIB:
2914 case BFD_MACH_O_LC_IDFVMLIB:
2915 case BFD_MACH_O_LC_IDENT:
2916 case BFD_MACH_O_LC_FVMFILE:
2917 case BFD_MACH_O_LC_PREPAGE:
2918 case BFD_MACH_O_LC_ROUTINES:
9b02d212 2919 case BFD_MACH_O_LC_ROUTINES_64:
046b007d 2920 break;
3af9a47b 2921 case BFD_MACH_O_LC_SUB_FRAMEWORK:
046b007d
TG
2922 case BFD_MACH_O_LC_SUB_UMBRELLA:
2923 case BFD_MACH_O_LC_SUB_LIBRARY:
2924 case BFD_MACH_O_LC_SUB_CLIENT:
0c9b2b4c 2925 case BFD_MACH_O_LC_RPATH:
ab273af8 2926 if (bfd_mach_o_read_str (abfd, command) != 0)
046b007d 2927 return -1;
3af9a47b
NC
2928 break;
2929 case BFD_MACH_O_LC_DYSYMTAB:
ab273af8 2930 if (bfd_mach_o_read_dysymtab (abfd, command) != 0)
3af9a47b
NC
2931 return -1;
2932 break;
3af9a47b
NC
2933 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
2934 case BFD_MACH_O_LC_PREBIND_CKSUM:
2935 break;
15e1c58a 2936 case BFD_MACH_O_LC_UUID:
ab273af8 2937 if (bfd_mach_o_read_uuid (abfd, command) != 0)
15e1c58a
TG
2938 return -1;
2939 break;
2940 case BFD_MACH_O_LC_CODE_SIGNATURE:
846b9259 2941 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
edbdea0e 2942 case BFD_MACH_O_LC_FUNCTION_STARTS:
ab273af8 2943 if (bfd_mach_o_read_linkedit (abfd, command) != 0)
046b007d 2944 return -1;
15e1c58a 2945 break;
ad86f1fb 2946 case BFD_MACH_O_LC_DYLD_INFO:
ab273af8 2947 if (bfd_mach_o_read_dyld_info (abfd, command) != 0)
ad86f1fb
TG
2948 return -1;
2949 break;
edbdea0e
TG
2950 case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
2951 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
2952 if (!bfd_mach_o_read_version_min (abfd, command))
2953 return -1;
2954 break;
3af9a47b 2955 default:
c0d9d051
TG
2956 (*_bfd_error_handler)(_("%B: unable to read unknown load command 0x%lx"),
2957 abfd, (unsigned long) command->type);
3af9a47b
NC
2958 break;
2959 }
2960
2961 return 0;
2962}
2963
2964static void
116c20d2 2965bfd_mach_o_flatten_sections (bfd *abfd)
3af9a47b 2966{
046b007d 2967 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b 2968 long csect = 0;
f1bde64c 2969 unsigned long i;
a95a4550 2970
15e1c58a 2971 /* Count total number of sections. */
3af9a47b
NC
2972 mdata->nsects = 0;
2973
2974 for (i = 0; i < mdata->header.ncmds; i++)
2975 {
1e8a024a
TG
2976 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
2977 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
3af9a47b 2978 {
e84d6fca
AM
2979 bfd_mach_o_segment_command *seg;
2980
2981 seg = &mdata->commands[i].command.segment;
3af9a47b
NC
2982 mdata->nsects += seg->nsects;
2983 }
2984 }
2985
15e1c58a 2986 /* Allocate sections array. */
e84d6fca
AM
2987 mdata->sections = bfd_alloc (abfd,
2988 mdata->nsects * sizeof (bfd_mach_o_section *));
15e1c58a
TG
2989
2990 /* Fill the array. */
3af9a47b
NC
2991 csect = 0;
2992
2993 for (i = 0; i < mdata->header.ncmds; i++)
2994 {
1e8a024a
TG
2995 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
2996 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
3af9a47b 2997 {
e84d6fca 2998 bfd_mach_o_segment_command *seg;
f1bde64c 2999 bfd_mach_o_section *sec;
3af9a47b 3000
e84d6fca 3001 seg = &mdata->commands[i].command.segment;
3af9a47b
NC
3002 BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
3003
f1bde64c
TG
3004 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
3005 mdata->sections[csect++] = sec;
3af9a47b
NC
3006 }
3007 }
3008}
3009
afbb9e17 3010static bfd_boolean
116c20d2 3011bfd_mach_o_scan_start_address (bfd *abfd)
3af9a47b 3012{
046b007d 3013 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b
NC
3014 bfd_mach_o_thread_command *cmd = NULL;
3015 unsigned long i;
3016
3017 for (i = 0; i < mdata->header.ncmds; i++)
afbb9e17
TG
3018 if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
3019 (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
3020 {
3021 cmd = &mdata->commands[i].command.thread;
3022 break;
3023 }
3af9a47b
NC
3024
3025 if (cmd == NULL)
afbb9e17 3026 return FALSE;
3af9a47b 3027
afbb9e17 3028 /* FIXME: create a subtarget hook ? */
3af9a47b
NC
3029 for (i = 0; i < cmd->nflavours; i++)
3030 {
a95a4550 3031 if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
e84d6fca 3032 && (cmd->flavours[i].flavour
15e1c58a 3033 == (unsigned long) BFD_MACH_O_x86_THREAD_STATE32))
3af9a47b
NC
3034 {
3035 unsigned char buf[4];
3036
c2f09c75
TG
3037 if (bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET) != 0
3038 || bfd_bread (buf, 4, abfd) != 4)
afbb9e17 3039 return FALSE;
3af9a47b
NC
3040
3041 abfd->start_address = bfd_h_get_32 (abfd, buf);
3042 }
a95a4550 3043 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
3af9a47b
NC
3044 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
3045 {
3046 unsigned char buf[4];
3047
c2f09c75
TG
3048 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
3049 || bfd_bread (buf, 4, abfd) != 4)
afbb9e17 3050 return FALSE;
3af9a47b
NC
3051
3052 abfd->start_address = bfd_h_get_32 (abfd, buf);
3053 }
1e8a024a 3054 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
b32e07d7 3055 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE64))
1e8a024a
TG
3056 {
3057 unsigned char buf[8];
3058
c2f09c75
TG
3059 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
3060 || bfd_bread (buf, 8, abfd) != 8)
afbb9e17 3061 return FALSE;
1e8a024a
TG
3062
3063 abfd->start_address = bfd_h_get_64 (abfd, buf);
3064 }
3065 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
3066 && (cmd->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE64))
3067 {
3068 unsigned char buf[8];
3069
c2f09c75
TG
3070 if (bfd_seek (abfd, cmd->flavours[i].offset + (16 * 8), SEEK_SET) != 0
3071 || bfd_bread (buf, 8, abfd) != 8)
afbb9e17 3072 return FALSE;
1e8a024a
TG
3073
3074 abfd->start_address = bfd_h_get_64 (abfd, buf);
3075 }
3af9a47b
NC
3076 }
3077
afbb9e17 3078 return TRUE;
3af9a47b
NC
3079}
3080
42fa0891
TG
3081bfd_boolean
3082bfd_mach_o_set_arch_mach (bfd *abfd,
3083 enum bfd_architecture arch,
3084 unsigned long machine)
3085{
3086 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
3087
3088 /* If this isn't the right architecture for this backend, and this
3089 isn't the generic backend, fail. */
3090 if (arch != bed->arch
3091 && arch != bfd_arch_unknown
3092 && bed->arch != bfd_arch_unknown)
3093 return FALSE;
3094
3095 return bfd_default_set_arch_mach (abfd, arch, machine);
3096}
3097
afbb9e17 3098static bfd_boolean
116c20d2
NC
3099bfd_mach_o_scan (bfd *abfd,
3100 bfd_mach_o_header *header,
3101 bfd_mach_o_data_struct *mdata)
3af9a47b
NC
3102{
3103 unsigned int i;
3af9a47b
NC
3104 enum bfd_architecture cputype;
3105 unsigned long cpusubtype;
1e8a024a
TG
3106 unsigned int hdrsize;
3107
c2f09c75 3108 hdrsize = mach_o_wide_p (header) ?
154a1ee5 3109 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
3af9a47b 3110
3af9a47b 3111 mdata->header = *header;
3af9a47b 3112
154a1ee5 3113 abfd->flags = abfd->flags & BFD_IN_MEMORY;
15e1c58a
TG
3114 switch (header->filetype)
3115 {
3116 case BFD_MACH_O_MH_OBJECT:
3117 abfd->flags |= HAS_RELOC;
3118 break;
3119 case BFD_MACH_O_MH_EXECUTE:
3120 abfd->flags |= EXEC_P;
3121 break;
3122 case BFD_MACH_O_MH_DYLIB:
3123 case BFD_MACH_O_MH_BUNDLE:
3124 abfd->flags |= DYNAMIC;
3125 break;
3126 }
3127
3af9a47b
NC
3128 abfd->tdata.mach_o_data = mdata;
3129
e84d6fca
AM
3130 bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
3131 &cputype, &cpusubtype);
3af9a47b
NC
3132 if (cputype == bfd_arch_unknown)
3133 {
afbb9e17
TG
3134 (*_bfd_error_handler)
3135 (_("bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"),
3136 header->cputype, header->cpusubtype);
3137 return FALSE;
3af9a47b
NC
3138 }
3139
3140 bfd_set_arch_mach (abfd, cputype, cpusubtype);
a95a4550 3141
3af9a47b
NC
3142 if (header->ncmds != 0)
3143 {
046b007d
TG
3144 mdata->commands = bfd_alloc
3145 (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
3af9a47b 3146 if (mdata->commands == NULL)
afbb9e17 3147 return FALSE;
a95a4550 3148
3af9a47b
NC
3149 for (i = 0; i < header->ncmds; i++)
3150 {
3151 bfd_mach_o_load_command *cur = &mdata->commands[i];
3152
3153 if (i == 0)
1e8a024a 3154 cur->offset = hdrsize;
3af9a47b
NC
3155 else
3156 {
3157 bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
3158 cur->offset = prev->offset + prev->len;
3159 }
3160
ab273af8 3161 if (bfd_mach_o_read_command (abfd, cur) < 0)
afbb9e17 3162 return FALSE;
a95a4550 3163 }
3af9a47b
NC
3164 }
3165
3166 if (bfd_mach_o_scan_start_address (abfd) < 0)
afbb9e17 3167 return FALSE;
3af9a47b
NC
3168
3169 bfd_mach_o_flatten_sections (abfd);
afbb9e17 3170 return TRUE;
3af9a47b
NC
3171}
3172
b34976b6 3173bfd_boolean
154a1ee5 3174bfd_mach_o_mkobject_init (bfd *abfd)
3af9a47b
NC
3175{
3176 bfd_mach_o_data_struct *mdata = NULL;
3177
116c20d2 3178 mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
3af9a47b 3179 if (mdata == NULL)
b34976b6 3180 return FALSE;
3af9a47b
NC
3181 abfd->tdata.mach_o_data = mdata;
3182
3183 mdata->header.magic = 0;
3184 mdata->header.cputype = 0;
3185 mdata->header.cpusubtype = 0;
3186 mdata->header.filetype = 0;
3187 mdata->header.ncmds = 0;
3188 mdata->header.sizeofcmds = 0;
3189 mdata->header.flags = 0;
3190 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
3191 mdata->commands = NULL;
3af9a47b
NC
3192 mdata->nsects = 0;
3193 mdata->sections = NULL;
3af9a47b 3194
b34976b6 3195 return TRUE;
3af9a47b
NC
3196}
3197
42fa0891
TG
3198static bfd_boolean
3199bfd_mach_o_gen_mkobject (bfd *abfd)
3200{
3201 bfd_mach_o_data_struct *mdata;
3202
3203 if (!bfd_mach_o_mkobject_init (abfd))
3204 return FALSE;
3205
3206 mdata = bfd_mach_o_get_data (abfd);
3207 mdata->header.magic = BFD_MACH_O_MH_MAGIC;
3208 mdata->header.cputype = 0;
3209 mdata->header.cpusubtype = 0;
3210 mdata->header.byteorder = abfd->xvec->byteorder;
3211 mdata->header.version = 1;
3212
3213 return TRUE;
3214}
3215
3af9a47b 3216const bfd_target *
154a1ee5
TG
3217bfd_mach_o_header_p (bfd *abfd,
3218 bfd_mach_o_filetype filetype,
3219 bfd_mach_o_cpu_type cputype)
3af9a47b 3220{
e84d6fca 3221 struct bfd_preserve preserve;
3af9a47b
NC
3222 bfd_mach_o_header header;
3223
e84d6fca 3224 preserve.marker = NULL;
154a1ee5 3225 if (!bfd_mach_o_read_header (abfd, &header))
e84d6fca 3226 goto wrong;
3af9a47b 3227
e84d6fca
AM
3228 if (! (header.byteorder == BFD_ENDIAN_BIG
3229 || header.byteorder == BFD_ENDIAN_LITTLE))
3af9a47b 3230 {
4a97a0e5
AM
3231 (*_bfd_error_handler) (_("unknown header byte-order value 0x%lx"),
3232 (unsigned long) header.byteorder);
e84d6fca 3233 goto wrong;
3af9a47b
NC
3234 }
3235
e84d6fca
AM
3236 if (! ((header.byteorder == BFD_ENDIAN_BIG
3237 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
3238 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
3239 || (header.byteorder == BFD_ENDIAN_LITTLE
3240 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
3241 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
3242 goto wrong;
3af9a47b 3243
154a1ee5
TG
3244 /* Check cputype and filetype.
3245 In case of wildcard, do not accept magics that are handled by existing
3246 targets. */
3247 if (cputype)
3248 {
3249 if (header.cputype != cputype)
3250 goto wrong;
3251 }
3252 else
3253 {
3254 switch (header.cputype)
3255 {
3256 case BFD_MACH_O_CPU_TYPE_I386:
3257 /* Handled by mach-o-i386 */
3258 goto wrong;
3259 default:
3260 break;
3261 }
3262 }
3263 if (filetype)
3264 {
3265 if (header.filetype != filetype)
3266 goto wrong;
3267 }
3268 else
3269 {
3270 switch (header.filetype)
3271 {
3272 case BFD_MACH_O_MH_CORE:
3273 /* Handled by core_p */
3274 goto wrong;
3275 default:
3276 break;
3277 }
3278 }
3279
e84d6fca
AM
3280 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
3281 if (preserve.marker == NULL
3282 || !bfd_preserve_save (abfd, &preserve))
3283 goto fail;
3af9a47b 3284
afbb9e17
TG
3285 if (!bfd_mach_o_scan (abfd, &header,
3286 (bfd_mach_o_data_struct *) preserve.marker))
e84d6fca 3287 goto wrong;
a95a4550 3288
e84d6fca 3289 bfd_preserve_finish (abfd, &preserve);
3af9a47b 3290 return abfd->xvec;
e84d6fca
AM
3291
3292 wrong:
3293 bfd_set_error (bfd_error_wrong_format);
3294
3295 fail:
3296 if (preserve.marker != NULL)
3297 bfd_preserve_restore (abfd, &preserve);
3298 return NULL;
3af9a47b
NC
3299}
3300
154a1ee5
TG
3301static const bfd_target *
3302bfd_mach_o_gen_object_p (bfd *abfd)
3af9a47b 3303{
154a1ee5
TG
3304 return bfd_mach_o_header_p (abfd, 0, 0);
3305}
e84d6fca 3306
154a1ee5
TG
3307static const bfd_target *
3308bfd_mach_o_gen_core_p (bfd *abfd)
3309{
3310 return bfd_mach_o_header_p (abfd, BFD_MACH_O_MH_CORE, 0);
3af9a47b
NC
3311}
3312
3313typedef struct mach_o_fat_archentry
3314{
3315 unsigned long cputype;
3316 unsigned long cpusubtype;
3317 unsigned long offset;
3318 unsigned long size;
3319 unsigned long align;
3af9a47b
NC
3320} mach_o_fat_archentry;
3321
3322typedef struct mach_o_fat_data_struct
3323{
3324 unsigned long magic;
3325 unsigned long nfat_arch;
3326 mach_o_fat_archentry *archentries;
3327} mach_o_fat_data_struct;
3328
3329const bfd_target *
116c20d2 3330bfd_mach_o_archive_p (bfd *abfd)
3af9a47b 3331{
e84d6fca 3332 mach_o_fat_data_struct *adata = NULL;
46d1c23b 3333 struct mach_o_fat_header_external hdr;
3af9a47b
NC
3334 unsigned long i;
3335
c2f09c75 3336 if (bfd_seek (abfd, 0, SEEK_SET) != 0
46d1c23b 3337 || bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
e84d6fca 3338 goto error;
3af9a47b 3339
116c20d2 3340 adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
3af9a47b 3341 if (adata == NULL)
e84d6fca 3342 goto error;
a95a4550 3343
46d1c23b
TG
3344 adata->magic = bfd_getb32 (hdr.magic);
3345 adata->nfat_arch = bfd_getb32 (hdr.nfat_arch);
3af9a47b 3346 if (adata->magic != 0xcafebabe)
e84d6fca 3347 goto error;
27cc28f9
AS
3348 /* Avoid matching Java bytecode files, which have the same magic number.
3349 In the Java bytecode file format this field contains the JVM version,
3350 which starts at 43.0. */
3351 if (adata->nfat_arch > 30)
3352 goto error;
3af9a47b 3353
c2f09c75 3354 adata->archentries =
3af9a47b
NC
3355 bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
3356 if (adata->archentries == NULL)
e84d6fca 3357 goto error;
3af9a47b
NC
3358
3359 for (i = 0; i < adata->nfat_arch; i++)
3360 {
46d1c23b
TG
3361 struct mach_o_fat_arch_external arch;
3362 if (bfd_bread (&arch, sizeof (arch), abfd) != sizeof (arch))
e84d6fca 3363 goto error;
46d1c23b
TG
3364 adata->archentries[i].cputype = bfd_getb32 (arch.cputype);
3365 adata->archentries[i].cpusubtype = bfd_getb32 (arch.cpusubtype);
3366 adata->archentries[i].offset = bfd_getb32 (arch.offset);
3367 adata->archentries[i].size = bfd_getb32 (arch.size);
3368 adata->archentries[i].align = bfd_getb32 (arch.align);
3af9a47b
NC
3369 }
3370
3371 abfd->tdata.mach_o_fat_data = adata;
3372 return abfd->xvec;
e84d6fca
AM
3373
3374 error:
3375 if (adata != NULL)
3376 bfd_release (abfd, adata);
3377 bfd_set_error (bfd_error_wrong_format);
3378 return NULL;
3af9a47b
NC
3379}
3380
3381bfd *
116c20d2 3382bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
3af9a47b 3383{
e84d6fca 3384 mach_o_fat_data_struct *adata;
3af9a47b
NC
3385 mach_o_fat_archentry *entry = NULL;
3386 unsigned long i;
15e1c58a 3387 bfd *nbfd;
15e1c58a
TG
3388 enum bfd_architecture arch_type;
3389 unsigned long arch_subtype;
3af9a47b 3390
e84d6fca 3391 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
3af9a47b
NC
3392 BFD_ASSERT (adata != NULL);
3393
3394 /* Find index of previous entry. */
3395 if (prev == NULL)
3396 i = 0; /* Start at first one. */
3397 else
3398 {
3399 for (i = 0; i < adata->nfat_arch; i++)
3400 {
15e1c58a 3401 if (adata->archentries[i].offset == prev->origin)
3af9a47b
NC
3402 break;
3403 }
3404
3405 if (i == adata->nfat_arch)
3406 {
3407 /* Not found. */
3408 bfd_set_error (bfd_error_bad_value);
a95a4550 3409 return NULL;
3af9a47b
NC
3410 }
3411 i++; /* Get next entry. */
3412 }
a95a4550 3413
3af9a47b
NC
3414 if (i >= adata->nfat_arch)
3415 {
3416 bfd_set_error (bfd_error_no_more_archived_files);
3417 return NULL;
3418 }
3419
3420 entry = &adata->archentries[i];
15e1c58a
TG
3421 nbfd = _bfd_new_bfd_contained_in (archive);
3422 if (nbfd == NULL)
3423 return NULL;
3424
3425 nbfd->origin = entry->offset;
3426
3427 bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype,
3428 &arch_type, &arch_subtype);
846b9259 3429
c0d9d051
TG
3430 /* Create the member filename. Use ARCH_NAME. */
3431 nbfd->filename = bfd_printable_arch_mach (arch_type, arch_subtype);
15e1c58a 3432 nbfd->iostream = NULL;
846b9259 3433 bfd_set_arch_mach (nbfd, arch_type, arch_subtype);
3af9a47b 3434
15e1c58a 3435 return nbfd;
3af9a47b
NC
3436}
3437
846b9259
TG
3438/* If ABFD format is FORMAT and architecture is ARCH, return it.
3439 If ABFD is a fat image containing a member that corresponds to FORMAT
3440 and ARCH, returns it.
3441 In other case, returns NULL.
3442 This function allows transparent uses of fat images. */
3443bfd *
3444bfd_mach_o_fat_extract (bfd *abfd,
3445 bfd_format format,
3446 const bfd_arch_info_type *arch)
3447{
3448 bfd *res;
3449 mach_o_fat_data_struct *adata;
3450 unsigned int i;
3451
3452 if (bfd_check_format (abfd, format))
3453 {
3454 if (bfd_get_arch_info (abfd) == arch)
3455 return abfd;
3456 return NULL;
3457 }
3458 if (!bfd_check_format (abfd, bfd_archive)
3459 || abfd->xvec != &mach_o_fat_vec)
3460 return NULL;
c2f09c75 3461
846b9259
TG
3462 /* This is a Mach-O fat image. */
3463 adata = (mach_o_fat_data_struct *) abfd->tdata.mach_o_fat_data;
3464 BFD_ASSERT (adata != NULL);
3465
3466 for (i = 0; i < adata->nfat_arch; i++)
3467 {
3468 struct mach_o_fat_archentry *e = &adata->archentries[i];
3469 enum bfd_architecture cpu_type;
3470 unsigned long cpu_subtype;
3471
3472 bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype,
3473 &cpu_type, &cpu_subtype);
3474 if (cpu_type != arch->arch || cpu_subtype != arch->mach)
3475 continue;
3476
3477 /* The architecture is found. */
3478 res = _bfd_new_bfd_contained_in (abfd);
3479 if (res == NULL)
3480 return NULL;
3481
3482 res->origin = e->offset;
3483
c0d9d051 3484 res->filename = bfd_printable_arch_mach (cpu_type, cpu_subtype);
846b9259
TG
3485 res->iostream = NULL;
3486
3487 if (bfd_check_format (res, format))
3488 {
3489 BFD_ASSERT (bfd_get_arch_info (res) == arch);
3490 return res;
3491 }
3492 bfd_close (res);
3493 return NULL;
3494 }
3495
3496 return NULL;
3497}
3498
3af9a47b 3499int
116c20d2
NC
3500bfd_mach_o_lookup_command (bfd *abfd,
3501 bfd_mach_o_load_command_type type,
3502 bfd_mach_o_load_command **mcommand)
3af9a47b 3503{
046b007d 3504 struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
3af9a47b
NC
3505 bfd_mach_o_load_command *ncmd = NULL;
3506 unsigned int i, num;
3507
3af9a47b
NC
3508 BFD_ASSERT (md != NULL);
3509 BFD_ASSERT (mcommand != NULL);
3510
3511 num = 0;
3512 for (i = 0; i < md->header.ncmds; i++)
3513 {
3514 struct bfd_mach_o_load_command *cmd = &md->commands[i];
3515
3516 if (cmd->type != type)
3517 continue;
3518
3519 if (num == 0)
3520 ncmd = cmd;
3521 num++;
3522 }
3523
3524 *mcommand = ncmd;
3525 return num;
3526}
3527
3528unsigned long
116c20d2 3529bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
3af9a47b
NC
3530{
3531 switch (type)
3532 {
3533 case BFD_MACH_O_CPU_TYPE_MC680x0:
3534 return 0x04000000;
3535 case BFD_MACH_O_CPU_TYPE_MC88000:
3536 return 0xffffe000;
3537 case BFD_MACH_O_CPU_TYPE_POWERPC:
3538 return 0xc0000000;
3539 case BFD_MACH_O_CPU_TYPE_I386:
3540 return 0xc0000000;
3541 case BFD_MACH_O_CPU_TYPE_SPARC:
3542 return 0xf0000000;
3543 case BFD_MACH_O_CPU_TYPE_I860:
3544 return 0;
3545 case BFD_MACH_O_CPU_TYPE_HPPA:
e84d6fca 3546 return 0xc0000000 - 0x04000000;
3af9a47b
NC
3547 default:
3548 return 0;
3549 }
3550}
3551
c5012cd8 3552const bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] =
046b007d
TG
3553{
3554 { "regular", BFD_MACH_O_S_REGULAR},
3555 { "zerofill", BFD_MACH_O_S_ZEROFILL},
3556 { "cstring_literals", BFD_MACH_O_S_CSTRING_LITERALS},
3557 { "4byte_literals", BFD_MACH_O_S_4BYTE_LITERALS},
3558 { "8byte_literals", BFD_MACH_O_S_8BYTE_LITERALS},
3559 { "literal_pointers", BFD_MACH_O_S_LITERAL_POINTERS},
3560 { "non_lazy_symbol_pointers", BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS},
3561 { "lazy_symbol_pointers", BFD_MACH_O_S_LAZY_SYMBOL_POINTERS},
3562 { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS},
3563 { "mod_init_func_pointers", BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS},
3564 { "mod_fini_func_pointers", BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS},
3565 { "coalesced", BFD_MACH_O_S_COALESCED},
3566 { "gb_zerofill", BFD_MACH_O_S_GB_ZEROFILL},
3567 { "interposing", BFD_MACH_O_S_INTERPOSING},
3568 { "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS},
3569 { "dtrace_dof", BFD_MACH_O_S_DTRACE_DOF},
a4551119 3570 { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS},
046b007d
TG
3571 { "lazy_dylib_symbol_pointers", BFD_MACH_O_S_LAZY_DYLIB_SYMBOL_POINTERS},
3572 { NULL, 0}
3573};
3574
c5012cd8 3575const bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[] =
046b007d
TG
3576{
3577 { "loc_reloc", BFD_MACH_O_S_ATTR_LOC_RELOC },
3578 { "ext_reloc", BFD_MACH_O_S_ATTR_EXT_RELOC },
3579 { "some_instructions", BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS },
3580 { "debug", BFD_MACH_O_S_ATTR_DEBUG },
3581 { "modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
3582 { "live_support", BFD_MACH_O_S_ATTR_LIVE_SUPPORT },
3583 { "no_dead_strip", BFD_MACH_O_S_ATTR_NO_DEAD_STRIP },
3584 { "strip_static_syms", BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS },
3585 { "no_toc", BFD_MACH_O_S_ATTR_NO_TOC },
3586 { "pure_instructions", BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS },
a4551119 3587 { "self_modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
046b007d
TG
3588 { NULL, 0}
3589};
3590
a4551119 3591/* Get the section type from NAME. Return 256 if NAME is unknown. */
53d58d96
TG
3592
3593unsigned int
3594bfd_mach_o_get_section_type_from_name (const char *name)
3595{
afbb9e17 3596 const bfd_mach_o_xlat_name *x;
53d58d96
TG
3597
3598 for (x = bfd_mach_o_section_type_name; x->name; x++)
3599 if (strcmp (x->name, name) == 0)
3600 return x->val;
a4551119
TG
3601 /* Maximum section ID = 0xff. */
3602 return 256;
53d58d96
TG
3603}
3604
3605/* Get the section attribute from NAME. Return -1 if NAME is unknown. */
3606
3607unsigned int
3608bfd_mach_o_get_section_attribute_from_name (const char *name)
3609{
afbb9e17 3610 const bfd_mach_o_xlat_name *x;
53d58d96
TG
3611
3612 for (x = bfd_mach_o_section_attribute_name; x->name; x++)
3613 if (strcmp (x->name, name) == 0)
3614 return x->val;
3615 return (unsigned int)-1;
3616}
3617
3af9a47b 3618int
116c20d2
NC
3619bfd_mach_o_core_fetch_environment (bfd *abfd,
3620 unsigned char **rbuf,
3621 unsigned int *rlen)
3af9a47b 3622{
046b007d 3623 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3af9a47b
NC
3624 unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
3625 unsigned int i = 0;
3626
3627 for (i = 0; i < mdata->header.ncmds; i++)
3628 {
3629 bfd_mach_o_load_command *cur = &mdata->commands[i];
3630 bfd_mach_o_segment_command *seg = NULL;
3631
3632 if (cur->type != BFD_MACH_O_LC_SEGMENT)
3633 continue;
3634
3635 seg = &cur->command.segment;
3636
3637 if ((seg->vmaddr + seg->vmsize) == stackaddr)
3638 {
3639 unsigned long start = seg->fileoff;
3640 unsigned long end = seg->fileoff + seg->filesize;
3641 unsigned char *buf = bfd_malloc (1024);
3642 unsigned long size = 1024;
3643
3644 for (;;)
3645 {
3646 bfd_size_type nread = 0;
3647 unsigned long offset;
3648 int found_nonnull = 0;
3649
3650 if (size > (end - start))
3651 size = (end - start);
3652
515ef31d
NC
3653 buf = bfd_realloc_or_free (buf, size);
3654 if (buf == NULL)
3655 return -1;
c2f09c75
TG
3656
3657 if (bfd_seek (abfd, end - size, SEEK_SET) != 0)
3658 {
3659 free (buf);
3660 return -1;
3661 }
3662
3af9a47b 3663 nread = bfd_bread (buf, size, abfd);
a95a4550 3664
3af9a47b 3665 if (nread != size)
515ef31d
NC
3666 {
3667 free (buf);
3668 return -1;
3669 }
a95a4550 3670
3af9a47b
NC
3671 for (offset = 4; offset <= size; offset += 4)
3672 {
e84d6fca 3673 unsigned long val;
3af9a47b 3674
e84d6fca 3675 val = *((unsigned long *) (buf + size - offset));
3af9a47b
NC
3676 if (! found_nonnull)
3677 {
3678 if (val != 0)
3679 found_nonnull = 1;
3680 }
3681 else if (val == 0x0)
3682 {
e84d6fca
AM
3683 unsigned long bottom;
3684 unsigned long top;
3af9a47b 3685
e84d6fca
AM
3686 bottom = seg->fileoff + seg->filesize - offset;
3687 top = seg->fileoff + seg->filesize - 4;
3af9a47b
NC
3688 *rbuf = bfd_malloc (top - bottom);
3689 *rlen = top - bottom;
3690
3691 memcpy (*rbuf, buf + size - *rlen, *rlen);
515ef31d 3692 free (buf);
3af9a47b
NC
3693 return 0;
3694 }
3695 }
3696
3697 if (size == (end - start))
3698 break;
3699
3700 size *= 2;
3701 }
515ef31d
NC
3702
3703 free (buf);
3af9a47b
NC
3704 }
3705 }
3706
3707 return -1;
3708}
3709
3710char *
116c20d2 3711bfd_mach_o_core_file_failing_command (bfd *abfd)
3af9a47b
NC
3712{
3713 unsigned char *buf = NULL;
3714 unsigned int len = 0;
3715 int ret = -1;
3716
3717 ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
3718 if (ret < 0)
3719 return NULL;
3720
f075ee0c 3721 return (char *) buf;
3af9a47b
NC
3722}
3723
3724int
116c20d2 3725bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
3af9a47b
NC
3726{
3727 return 0;
3728}
3729
d9071b0c
TG
3730bfd_boolean
3731bfd_mach_o_find_nearest_line (bfd *abfd,
3732 asection *section,
3733 asymbol **symbols,
3734 bfd_vma offset,
3735 const char **filename_ptr,
3736 const char **functionname_ptr,
3737 unsigned int *line_ptr)
3738{
3739 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3740 /* TODO: Handle executables and dylibs by using dSYMs. */
3741 if (mdata->header.filetype != BFD_MACH_O_MH_OBJECT)
3742 return FALSE;
3743 if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections,
3744 section, symbols, offset,
3745 filename_ptr, functionname_ptr,
3746 line_ptr, 0,
3747 &mdata->dwarf2_find_line_info))
3748 return TRUE;
3749 return FALSE;
3750}
3751
3752bfd_boolean
3753bfd_mach_o_close_and_cleanup (bfd *abfd)
3754{
3755 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3756 if (bfd_get_format (abfd) == bfd_object && mdata != NULL)
3757 _bfd_dwarf2_cleanup_debug_info (abfd, &mdata->dwarf2_find_line_info);
3758
3759 return _bfd_generic_close_and_cleanup (abfd);
3760}
3761
92bc0e80
TG
3762#define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
3763#define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
3764
3765#define bfd_mach_o_swap_reloc_in NULL
3766#define bfd_mach_o_swap_reloc_out NULL
b32e07d7 3767#define bfd_mach_o_print_thread NULL
a4551119 3768#define bfd_mach_o_tgt_seg_table NULL
92bc0e80 3769
116c20d2
NC
3770#define TARGET_NAME mach_o_be_vec
3771#define TARGET_STRING "mach-o-be"
42fa0891 3772#define TARGET_ARCHITECTURE bfd_arch_unknown
116c20d2
NC
3773#define TARGET_BIG_ENDIAN 1
3774#define TARGET_ARCHIVE 0
3af9a47b
NC
3775#include "mach-o-target.c"
3776
3777#undef TARGET_NAME
3778#undef TARGET_STRING
42fa0891 3779#undef TARGET_ARCHITECTURE
3af9a47b
NC
3780#undef TARGET_BIG_ENDIAN
3781#undef TARGET_ARCHIVE
3782
116c20d2
NC
3783#define TARGET_NAME mach_o_le_vec
3784#define TARGET_STRING "mach-o-le"
42fa0891 3785#define TARGET_ARCHITECTURE bfd_arch_unknown
116c20d2
NC
3786#define TARGET_BIG_ENDIAN 0
3787#define TARGET_ARCHIVE 0
3af9a47b
NC
3788
3789#include "mach-o-target.c"
3790
3791#undef TARGET_NAME
3792#undef TARGET_STRING
42fa0891 3793#undef TARGET_ARCHITECTURE
3af9a47b
NC
3794#undef TARGET_BIG_ENDIAN
3795#undef TARGET_ARCHIVE
3796
8f95b6e4
TG
3797/* Not yet handled: creating an archive. */
3798#define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive
3799
3800/* Not used. */
3801#define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr
3802#define bfd_mach_o_write_ar_hdr _bfd_noarchive_write_ar_hdr
3803#define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap
3804#define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
3805#define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
3806#define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname
3807#define bfd_mach_o_write_armap _bfd_noarchive_write_armap
3808#define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index
3809#define bfd_mach_o_generic_stat_arch_elt _bfd_noarchive_generic_stat_arch_elt
3810#define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
3811
116c20d2
NC
3812#define TARGET_NAME mach_o_fat_vec
3813#define TARGET_STRING "mach-o-fat"
42fa0891 3814#define TARGET_ARCHITECTURE bfd_arch_unknown
116c20d2
NC
3815#define TARGET_BIG_ENDIAN 1
3816#define TARGET_ARCHIVE 1
3af9a47b
NC
3817
3818#include "mach-o-target.c"
3819
3820#undef TARGET_NAME
3821#undef TARGET_STRING
42fa0891 3822#undef TARGET_ARCHITECTURE
3af9a47b
NC
3823#undef TARGET_BIG_ENDIAN
3824#undef TARGET_ARCHIVE
This page took 0.684466 seconds and 4 git commands to generate.